commit 7774ca3b245957b6cef7b774ce117b29a98dab6e Author: Nathan Freitas nathan@freitas.net Date: Fri Apr 3 12:22:54 2015 -0400
remove old embedded badvpn_dns --- external/badvpn_dns/Android.mk | 75 - external/badvpn_dns/CMakeLists.txt | 408 -- external/badvpn_dns/COPYING | 24 - external/badvpn_dns/ChangeLog | 216 - external/badvpn_dns/INSTALL | 76 - external/badvpn_dns/INSTALL-WINDOWS | 72 - external/badvpn_dns/arpprobe/BArpProbe.c | 359 -- external/badvpn_dns/arpprobe/BArpProbe.h | 80 - external/badvpn_dns/arpprobe/CMakeLists.txt | 1 - external/badvpn_dns/badvpn.7 | 324 -- external/badvpn_dns/base/BLog.c | 96 - external/badvpn_dns/base/BLog.h | 402 -- external/badvpn_dns/base/BLog_syslog.c | 150 - external/badvpn_dns/base/BLog_syslog.h | 42 - external/badvpn_dns/base/BMutex.h | 101 - external/badvpn_dns/base/BPending.c | 205 - external/badvpn_dns/base/BPending.h | 250 - external/badvpn_dns/base/BPending_list.h | 4 - external/badvpn_dns/base/CMakeLists.txt | 13 - external/badvpn_dns/base/DebugObject.c | 39 - external/badvpn_dns/base/DebugObject.h | 147 - external/badvpn_dns/blog_channels.txt | 145 - external/badvpn_dns/blog_generator/blog.php | 121 - .../badvpn_dns/blog_generator/blog_functions.php | 35 - external/badvpn_dns/bproto/BProto.h | 85 - .../badvpn_dns/bproto_generator/ProtoParser.lime | 99 - .../badvpn_dns/bproto_generator/ProtoParser.php | 560 --- external/badvpn_dns/bproto_generator/bproto.php | 115 - .../bproto_generator/bproto_functions.php | 777 ---- external/badvpn_dns/client/CMakeLists.txt | 30 - external/badvpn_dns/client/DPReceive.c | 324 -- external/badvpn_dns/client/DPReceive.h | 98 - external/badvpn_dns/client/DPRelay.c | 307 -- external/badvpn_dns/client/DPRelay.h | 89 - external/badvpn_dns/client/DataProto.c | 566 --- external/badvpn_dns/client/DataProto.h | 237 - .../badvpn_dns/client/DataProtoKeepaliveSource.c | 72 - .../badvpn_dns/client/DataProtoKeepaliveSource.h | 73 - external/badvpn_dns/client/DatagramPeerIO.c | 425 -- external/badvpn_dns/client/DatagramPeerIO.h | 271 -- .../badvpn_dns/client/FragmentProtoAssembler.c | 469 -- .../badvpn_dns/client/FragmentProtoAssembler.h | 134 - .../client/FragmentProtoAssembler_tree.h | 9 - .../badvpn_dns/client/FragmentProtoDisassembler.c | 229 - .../badvpn_dns/client/FragmentProtoDisassembler.h | 109 - external/badvpn_dns/client/FrameDecider.c | 795 ---- external/badvpn_dns/client/FrameDecider.h | 196 - .../badvpn_dns/client/FrameDecider_groups_tree.h | 9 - .../badvpn_dns/client/FrameDecider_macs_tree.h | 9 - .../client/FrameDecider_multicast_tree.h | 9 - external/badvpn_dns/client/PasswordListener.c | 374 -- external/badvpn_dns/client/PasswordListener.h | 156 - external/badvpn_dns/client/PeerChat.c | 433 -- external/badvpn_dns/client/PeerChat.h | 123 - external/badvpn_dns/client/SCOutmsgEncoder.c | 104 - external/badvpn_dns/client/SCOutmsgEncoder.h | 76 - external/badvpn_dns/client/SPProtoDecoder.c | 398 -- external/badvpn_dns/client/SPProtoDecoder.h | 171 - external/badvpn_dns/client/SPProtoEncoder.c | 436 -- external/badvpn_dns/client/SPProtoEncoder.h | 172 - external/badvpn_dns/client/SimpleStreamBuffer.c | 144 - external/badvpn_dns/client/SimpleStreamBuffer.h | 52 - external/badvpn_dns/client/SinglePacketSource.c | 85 - external/badvpn_dns/client/SinglePacketSource.h | 73 - external/badvpn_dns/client/StreamPeerIO.c | 712 --- external/badvpn_dns/client/StreamPeerIO.h | 222 - external/badvpn_dns/client/badvpn-client.8 | 316 -- external/badvpn_dns/client/client.c | 2997 ------------ external/badvpn_dns/client/client.h | 193 - .../badvpn_dns/cmake/modules/COPYING-CMAKE-SCRIPTS | 22 - external/badvpn_dns/cmake/modules/FindGLIB2.cmake | 52 - .../cmake/modules/FindLibraryWithDebug.cmake | 113 - external/badvpn_dns/cmake/modules/FindNSPR.cmake | 57 - external/badvpn_dns/cmake/modules/FindNSS.cmake | 57 - .../badvpn_dns/cmake/modules/FindOpenSSL.cmake | 72 - external/badvpn_dns/compile-tun2sock.sh | 112 - external/badvpn_dns/compile-udpgw.sh | 84 - external/badvpn_dns/dhcpclient/BDHCPClient.c | 340 -- external/badvpn_dns/dhcpclient/BDHCPClient.h | 87 - external/badvpn_dns/dhcpclient/BDHCPClientCore.c | 860 ---- external/badvpn_dns/dhcpclient/BDHCPClientCore.h | 114 - external/badvpn_dns/dhcpclient/CMakeLists.txt | 10 - external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.c | 137 - external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.h | 49 - external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.c | 119 - external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.h | 49 - external/badvpn_dns/dostest/CMakeLists.txt | 10 - external/badvpn_dns/dostest/StreamBuffer.c | 147 - external/badvpn_dns/dostest/StreamBuffer.h | 70 - external/badvpn_dns/dostest/dostest-attacker.c | 512 -- external/badvpn_dns/dostest/dostest-server.c | 567 --- external/badvpn_dns/examples/CMakeLists.txt | 97 - external/badvpn_dns/examples/FastPacketSource.h | 79 - external/badvpn_dns/examples/RandomPacketSink.h | 116 - external/badvpn_dns/examples/TimerPacketSink.h | 97 - external/badvpn_dns/examples/arpprobe_test.c | 131 - external/badvpn_dns/examples/bavl_test.c | 129 - external/badvpn_dns/examples/bencryption_bench.c | 146 - external/badvpn_dns/examples/bprocess_example.c | 140 - external/badvpn_dns/examples/brandom2_test.c | 65 - external/badvpn_dns/examples/btimer_example.c | 84 - external/badvpn_dns/examples/cavl_test.c | 285 -- external/badvpn_dns/examples/cavl_test_tree.h | 23 - external/badvpn_dns/examples/dhcpclient_test.c | 159 - external/badvpn_dns/examples/emscripten_test.c | 71 - external/badvpn_dns/examples/fairqueue_test.c | 145 - external/badvpn_dns/examples/fairqueue_test2.c | 93 - external/badvpn_dns/examples/indexedlist_test.c | 95 - external/badvpn_dns/examples/ipaddr6_test.c | 169 - external/badvpn_dns/examples/ncd_parser_test.c | 294 -- external/badvpn_dns/examples/ncd_tokenizer_test.c | 149 - .../badvpn_dns/examples/ncd_value_parser_test.c | 78 - .../badvpn_dns/examples/ncdinterfacemonitor_test.c | 150 - external/badvpn_dns/examples/ncdudevmanager_test.c | 161 - external/badvpn_dns/examples/ncdudevmonitor_test.c | 152 - external/badvpn_dns/examples/ncdval_test.c | 380 -- external/badvpn_dns/examples/ncdvalcons_test.c | 111 - external/badvpn_dns/examples/parse_number_test.c | 130 - external/badvpn_dns/examples/predicate_test.c | 116 - external/badvpn_dns/examples/savl_test.c | 135 - external/badvpn_dns/examples/savl_test_tree.h | 9 - external/badvpn_dns/examples/stdin_input.c | 138 - external/badvpn_dns/examples/substring_test.c | 204 - external/badvpn_dns/fix_flex.php | 10 - external/badvpn_dns/flooder/CMakeLists.txt | 7 - external/badvpn_dns/flooder/flooder.c | 671 --- external/badvpn_dns/flooder/flooder.h | 37 - external/badvpn_dns/flow/BufferWriter.c | 112 - external/badvpn_dns/flow/BufferWriter.h | 107 - external/badvpn_dns/flow/CMakeLists.txt | 31 - external/badvpn_dns/flow/LineBuffer.c | 140 - external/badvpn_dns/flow/LineBuffer.h | 54 - external/badvpn_dns/flow/PacketBuffer.c | 131 - external/badvpn_dns/flow/PacketBuffer.h | 77 - external/badvpn_dns/flow/PacketCopier.c | 136 - external/badvpn_dns/flow/PacketCopier.h | 90 - external/badvpn_dns/flow/PacketPassConnector.c | 125 - external/badvpn_dns/flow/PacketPassConnector.h | 102 - external/badvpn_dns/flow/PacketPassFairQueue.c | 405 -- external/badvpn_dns/flow/PacketPassFairQueue.h | 204 - .../badvpn_dns/flow/PacketPassFairQueue_tree.h | 7 - external/badvpn_dns/flow/PacketPassFifoQueue.c | 241 - external/badvpn_dns/flow/PacketPassFifoQueue.h | 76 - external/badvpn_dns/flow/PacketPassInterface.c | 68 - external/badvpn_dns/flow/PacketPassInterface.h | 236 - external/badvpn_dns/flow/PacketPassNotifier.c | 103 - external/badvpn_dns/flow/PacketPassNotifier.h | 99 - external/badvpn_dns/flow/PacketPassPriorityQueue.c | 283 -- external/badvpn_dns/flow/PacketPassPriorityQueue.h | 192 - .../badvpn_dns/flow/PacketPassPriorityQueue_tree.h | 7 - external/badvpn_dns/flow/PacketProtoDecoder.c | 182 - external/badvpn_dns/flow/PacketProtoDecoder.h | 96 - external/badvpn_dns/flow/PacketProtoEncoder.c | 101 - external/badvpn_dns/flow/PacketProtoEncoder.h | 80 - external/badvpn_dns/flow/PacketProtoFlow.c | 82 - external/badvpn_dns/flow/PacketProtoFlow.h | 83 - external/badvpn_dns/flow/PacketRecvBlocker.c | 99 - external/badvpn_dns/flow/PacketRecvBlocker.h | 90 - external/badvpn_dns/flow/PacketRecvConnector.c | 123 - external/badvpn_dns/flow/PacketRecvConnector.h | 102 - external/badvpn_dns/flow/PacketRecvInterface.c | 56 - external/badvpn_dns/flow/PacketRecvInterface.h | 170 - external/badvpn_dns/flow/PacketRouter.c | 129 - external/badvpn_dns/flow/PacketRouter.h | 126 - external/badvpn_dns/flow/PacketStreamSender.c | 111 - external/badvpn_dns/flow/PacketStreamSender.h | 83 - external/badvpn_dns/flow/RouteBuffer.c | 256 - external/badvpn_dns/flow/RouteBuffer.h | 139 - external/badvpn_dns/flow/SinglePacketBuffer.c | 87 - external/badvpn_dns/flow/SinglePacketBuffer.h | 75 - external/badvpn_dns/flow/SinglePacketSender.c | 72 - external/badvpn_dns/flow/SinglePacketSender.h | 82 - external/badvpn_dns/flow/SingleStreamReceiver.c | 82 - external/badvpn_dns/flow/SingleStreamReceiver.h | 53 - external/badvpn_dns/flow/SingleStreamSender.c | 82 - external/badvpn_dns/flow/SingleStreamSender.h | 53 - external/badvpn_dns/flow/StreamPacketSender.c | 90 - external/badvpn_dns/flow/StreamPacketSender.h | 77 - external/badvpn_dns/flow/StreamPassConnector.c | 120 - external/badvpn_dns/flow/StreamPassConnector.h | 98 - external/badvpn_dns/flow/StreamPassInterface.c | 56 - external/badvpn_dns/flow/StreamPassInterface.h | 165 - external/badvpn_dns/flow/StreamRecvConnector.c | 120 - external/badvpn_dns/flow/StreamRecvConnector.h | 98 - external/badvpn_dns/flow/StreamRecvInterface.c | 56 - external/badvpn_dns/flow/StreamRecvInterface.h | 165 - external/badvpn_dns/flowextra/CMakeLists.txt | 5 - external/badvpn_dns/flowextra/KeepaliveIO.c | 112 - external/badvpn_dns/flowextra/KeepaliveIO.h | 88 - .../flowextra/PacketPassInactivityMonitor.c | 131 - .../flowextra/PacketPassInactivityMonitor.h | 124 - external/badvpn_dns/generate_files | 51 - .../badvpn_dns/generated/NCDConfigParser_parse.c | 1890 -------- .../badvpn_dns/generated/NCDConfigParser_parse.h | 22 - .../badvpn_dns/generated/NCDConfigParser_parse.out | 950 ---- .../badvpn_dns/generated/NCDConfigParser_parse.y | 718 --- external/badvpn_dns/generated/NCDValParser_parse.c | 1119 ----- external/badvpn_dns/generated/NCDValParser_parse.h | 7 - .../badvpn_dns/generated/NCDValParser_parse.out | 217 - external/badvpn_dns/generated/NCDValParser_parse.y | 202 - external/badvpn_dns/generated/bison_BPredicate.c | 2168 --------- external/badvpn_dns/generated/bison_BPredicate.h | 114 - .../badvpn_dns/generated/blog_channel_BArpProbe.h | 4 - .../generated/blog_channel_BConnection.h | 4 - .../generated/blog_channel_BDHCPClient.h | 4 - .../generated/blog_channel_BDHCPClientCore.h | 4 - .../badvpn_dns/generated/blog_channel_BDatagram.h | 4 - .../generated/blog_channel_BEncryption.h | 4 - .../generated/blog_channel_BInputProcess.h | 4 - .../generated/blog_channel_BLockReactor.h | 4 - .../badvpn_dns/generated/blog_channel_BNetwork.h | 4 - .../badvpn_dns/generated/blog_channel_BPredicate.h | 4 - .../badvpn_dns/generated/blog_channel_BProcess.h | 4 - .../badvpn_dns/generated/blog_channel_BReactor.h | 4 - .../generated/blog_channel_BSSLConnection.h | 4 - .../badvpn_dns/generated/blog_channel_BSignal.h | 4 - .../generated/blog_channel_BSocksClient.h | 4 - external/badvpn_dns/generated/blog_channel_BTap.h | 4 - .../generated/blog_channel_BThreadSignal.h | 4 - .../generated/blog_channel_BThreadWork.h | 4 - external/badvpn_dns/generated/blog_channel_BTime.h | 4 - .../generated/blog_channel_BUnixSignal.h | 4 - .../badvpn_dns/generated/blog_channel_DPReceive.h | 4 - .../badvpn_dns/generated/blog_channel_DPRelay.h | 4 - .../badvpn_dns/generated/blog_channel_DataProto.h | 4 - .../generated/blog_channel_DatagramPeerIO.h | 4 - .../blog_channel_FragmentProtoAssembler.h | 4 - .../generated/blog_channel_FrameDecider.h | 4 - .../badvpn_dns/generated/blog_channel_LineBuffer.h | 4 - .../badvpn_dns/generated/blog_channel_Listener.h | 4 - .../generated/blog_channel_NCDBuildProgram.h | 4 - .../generated/blog_channel_NCDConfigParser.h | 4 - .../generated/blog_channel_NCDConfigTokenizer.h | 4 - .../generated/blog_channel_NCDIfConfig.h | 4 - .../generated/blog_channel_NCDInterfaceMonitor.h | 4 - .../generated/blog_channel_NCDModuleIndex.h | 4 - .../generated/blog_channel_NCDModuleProcess.h | 4 - .../generated/blog_channel_NCDPlaceholderDb.h | 4 - .../badvpn_dns/generated/blog_channel_NCDRequest.h | 4 - .../generated/blog_channel_NCDRequestClient.h | 4 - .../generated/blog_channel_NCDRfkillMonitor.h | 4 - .../generated/blog_channel_NCDUdevCache.h | 4 - .../generated/blog_channel_NCDUdevManager.h | 4 - .../generated/blog_channel_NCDUdevMonitor.h | 4 - .../generated/blog_channel_NCDUdevMonitorParser.h | 4 - .../badvpn_dns/generated/blog_channel_NCDVal.h | 4 - .../generated/blog_channel_NCDValGenerator.h | 4 - .../generated/blog_channel_NCDValParser.h | 4 - .../generated/blog_channel_PRStreamSink.h | 4 - .../generated/blog_channel_PRStreamSource.h | 4 - .../generated/blog_channel_PacketProtoDecoder.h | 4 - .../generated/blog_channel_PasswordListener.h | 4 - .../badvpn_dns/generated/blog_channel_PeerChat.h | 4 - .../generated/blog_channel_SPProtoDecoder.h | 4 - .../generated/blog_channel_ServerConnection.h | 4 - .../generated/blog_channel_SocksUdpGwClient.h | 4 - .../generated/blog_channel_StreamPeerIO.h | 4 - .../generated/blog_channel_UdpGwClient.h | 4 - external/badvpn_dns/generated/blog_channel_addr.h | 4 - .../badvpn_dns/generated/blog_channel_client.h | 4 - .../generated/blog_channel_dostest_attacker.h | 4 - .../generated/blog_channel_dostest_server.h | 4 - .../badvpn_dns/generated/blog_channel_flooder.h | 4 - external/badvpn_dns/generated/blog_channel_lwip.h | 4 - external/badvpn_dns/generated/blog_channel_ncd.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_alias.h | 4 - .../generated/blog_channel_ncd_arithmetic.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_assert.h | 4 - .../generated/blog_channel_ncd_backtrack.h | 4 - .../generated/blog_channel_ncd_blocker.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_buffer.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_call2.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_choose.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_concat.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_daemon.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_depend.h | 4 - .../generated/blog_channel_ncd_depend_scope.h | 4 - .../generated/blog_channel_ncd_dynamic_depend.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_exit.h | 4 - .../generated/blog_channel_ncd_explode.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_file.h | 4 - .../generated/blog_channel_ncd_file_open.h | 4 - .../generated/blog_channel_ncd_foreach.h | 4 - .../generated/blog_channel_ncd_from_string.h | 4 - .../generated/blog_channel_ncd_getargs.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_getenv.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_if.h | 4 - .../generated/blog_channel_ncd_imperative.h | 4 - .../generated/blog_channel_ncd_implode.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_index.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_list.h | 4 - .../generated/blog_channel_ncd_load_module.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_log.h | 4 - .../generated/blog_channel_ncd_log_msg.h | 4 - .../generated/blog_channel_ncd_logical.h | 4 - .../generated/blog_channel_ncd_multidepend.h | 4 - .../blog_channel_ncd_net_backend_badvpn.h | 4 - .../blog_channel_ncd_net_backend_rfkill.h | 4 - .../blog_channel_ncd_net_backend_waitdevice.h | 4 - .../blog_channel_ncd_net_backend_waitlink.h | 4 - .../blog_channel_ncd_net_backend_wpa_supplicant.h | 4 - .../generated/blog_channel_ncd_net_dns.h | 4 - .../generated/blog_channel_ncd_net_iptables.h | 4 - .../generated/blog_channel_ncd_net_ipv4_addr.h | 4 - .../blog_channel_ncd_net_ipv4_addr_in_network.h | 4 - .../blog_channel_ncd_net_ipv4_arp_probe.h | 4 - .../generated/blog_channel_ncd_net_ipv4_dhcp.h | 4 - .../generated/blog_channel_ncd_net_ipv4_route.h | 4 - .../generated/blog_channel_ncd_net_ipv6_addr.h | 4 - .../blog_channel_ncd_net_ipv6_addr_in_network.h | 4 - .../generated/blog_channel_ncd_net_ipv6_route.h | 4 - .../blog_channel_ncd_net_ipv6_wait_dynamic_addr.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_net_up.h | 4 - .../blog_channel_ncd_net_watch_interfaces.h | 4 - .../generated/blog_channel_ncd_netmask.h | 4 - .../generated/blog_channel_ncd_ondemand.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_parse.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_print.h | 4 - .../generated/blog_channel_ncd_process_manager.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_reboot.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_ref.h | 4 - .../generated/blog_channel_ncd_regex_match.h | 4 - .../generated/blog_channel_ncd_request.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_run.h | 4 - .../generated/blog_channel_ncd_runonce.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_sleep.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_socket.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_spawn.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_strcmp.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_substr.h | 4 - .../generated/blog_channel_ncd_sys_evdev.h | 4 - .../blog_channel_ncd_sys_request_client.h | 4 - .../blog_channel_ncd_sys_request_server.h | 4 - .../generated/blog_channel_ncd_sys_start_process.h | 4 - .../blog_channel_ncd_sys_watch_directory.h | 4 - .../generated/blog_channel_ncd_sys_watch_input.h | 4 - .../generated/blog_channel_ncd_sys_watch_usb.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_timer.h | 4 - .../generated/blog_channel_ncd_to_string.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_try.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_value.h | 4 - .../generated/blog_channel_ncd_valuemetic.h | 4 - .../badvpn_dns/generated/blog_channel_ncd_var.h | 4 - .../badvpn_dns/generated/blog_channel_nsskey.h | 4 - .../badvpn_dns/generated/blog_channel_server.h | 4 - .../badvpn_dns/generated/blog_channel_tun2socks.h | 4 - external/badvpn_dns/generated/blog_channel_udpgw.h | 4 - .../badvpn_dns/generated/blog_channels_defines.h | 146 - external/badvpn_dns/generated/blog_channels_list.h | 145 - external/badvpn_dns/generated/bproto_addr.h | 675 --- external/badvpn_dns/generated/bproto_bproto_test.h | 1029 ---- external/badvpn_dns/generated/bproto_msgproto.h | 2122 --------- external/badvpn_dns/generated/flex_BPredicate.c | 2143 --------- external/badvpn_dns/generated/flex_BPredicate.h | 350 -- external/badvpn_dns/lemon/lemon.c | 4889 -------------------- external/badvpn_dns/lemon/lempar.c | 842 ---- external/badvpn_dns/lime/HOWTO | 70 - external/badvpn_dns/lime/flex_token_stream.php | 34 - external/badvpn_dns/lime/lemon.c | 4588 ------------------ external/badvpn_dns/lime/lime.bootstrap | 31 - external/badvpn_dns/lime/lime.php | 910 ---- external/badvpn_dns/lime/lime_scan_tokens.l | 121 - external/badvpn_dns/lime/metagrammar | 58 - external/badvpn_dns/lime/parse_engine.php | 252 - external/badvpn_dns/lime/set.so.php | 29 - external/badvpn_dns/lwip/CHANGELOG | 3396 -------------- external/badvpn_dns/lwip/CMakeLists.txt | 27 - external/badvpn_dns/lwip/COPYING | 33 - external/badvpn_dns/lwip/FILES | 4 - external/badvpn_dns/lwip/README | 89 - external/badvpn_dns/lwip/UPGRADING | 144 - external/badvpn_dns/lwip/custom/arch/cc.h | 96 - external/badvpn_dns/lwip/custom/arch/perf.h | 36 - external/badvpn_dns/lwip/custom/lwipopts.h | 70 - external/badvpn_dns/lwip/custom/sys.c | 37 - external/badvpn_dns/lwip/doc/FILES | 6 - external/badvpn_dns/lwip/doc/contrib.txt | 63 - external/badvpn_dns/lwip/doc/rawapi.txt | 511 -- external/badvpn_dns/lwip/doc/savannah.txt | 135 - external/badvpn_dns/lwip/doc/snmp_agent.txt | 181 - external/badvpn_dns/lwip/doc/sys_arch.txt | 267 -- external/badvpn_dns/lwip/lwip-base-version | 1 - external/badvpn_dns/lwip/src/FILES | 13 - external/badvpn_dns/lwip/src/api/api_lib.c | 788 ---- external/badvpn_dns/lwip/src/api/api_msg.c | 1610 ------- external/badvpn_dns/lwip/src/api/err.c | 75 - external/badvpn_dns/lwip/src/api/netbuf.c | 245 - external/badvpn_dns/lwip/src/api/netdb.c | 353 -- external/badvpn_dns/lwip/src/api/netifapi.c | 160 - external/badvpn_dns/lwip/src/api/sockets.c | 2555 ---------- external/badvpn_dns/lwip/src/api/tcpip.c | 492 -- external/badvpn_dns/lwip/src/core/def.c | 108 - external/badvpn_dns/lwip/src/core/dhcp.c | 1771 ------- external/badvpn_dns/lwip/src/core/dns.c | 988 ---- external/badvpn_dns/lwip/src/core/inet_chksum.c | 545 --- external/badvpn_dns/lwip/src/core/init.c | 345 -- external/badvpn_dns/lwip/src/core/ipv4/autoip.c | 528 --- external/badvpn_dns/lwip/src/core/ipv4/icmp.c | 338 -- external/badvpn_dns/lwip/src/core/ipv4/igmp.c | 805 ---- external/badvpn_dns/lwip/src/core/ipv4/ip4.c | 924 ---- external/badvpn_dns/lwip/src/core/ipv4/ip4_addr.c | 312 -- external/badvpn_dns/lwip/src/core/ipv4/ip_frag.c | 863 ---- external/badvpn_dns/lwip/src/core/ipv6/README | 1 - external/badvpn_dns/lwip/src/core/ipv6/dhcp6.c | 50 - external/badvpn_dns/lwip/src/core/ipv6/ethip6.c | 193 - external/badvpn_dns/lwip/src/core/ipv6/icmp6.c | 337 -- external/badvpn_dns/lwip/src/core/ipv6/inet6.c | 51 - external/badvpn_dns/lwip/src/core/ipv6/ip6.c | 1034 ----- external/badvpn_dns/lwip/src/core/ipv6/ip6_addr.c | 251 - external/badvpn_dns/lwip/src/core/ipv6/ip6_frag.c | 697 --- external/badvpn_dns/lwip/src/core/ipv6/mld6.c | 580 --- external/badvpn_dns/lwip/src/core/ipv6/nd6.c | 1787 ------- external/badvpn_dns/lwip/src/core/mem.c | 659 --- external/badvpn_dns/lwip/src/core/memp.c | 485 -- external/badvpn_dns/lwip/src/core/netif.c | 918 ---- external/badvpn_dns/lwip/src/core/pbuf.c | 1179 ----- external/badvpn_dns/lwip/src/core/raw.c | 422 -- external/badvpn_dns/lwip/src/core/snmp/asn1_dec.c | 657 --- external/badvpn_dns/lwip/src/core/snmp/asn1_enc.c | 611 --- external/badvpn_dns/lwip/src/core/snmp/mib2.c | 4146 ----------------- .../badvpn_dns/lwip/src/core/snmp/mib_structs.c | 1174 ----- external/badvpn_dns/lwip/src/core/snmp/msg_in.c | 1453 ------ external/badvpn_dns/lwip/src/core/snmp/msg_out.c | 678 --- external/badvpn_dns/lwip/src/core/stats.c | 181 - external/badvpn_dns/lwip/src/core/sys.c | 68 - external/badvpn_dns/lwip/src/core/tcp.c | 1852 -------- external/badvpn_dns/lwip/src/core/tcp_in.c | 1666 ------- external/badvpn_dns/lwip/src/core/tcp_out.c | 1499 ------ external/badvpn_dns/lwip/src/core/timers.c | 546 --- external/badvpn_dns/lwip/src/core/udp.c | 1151 ----- .../badvpn_dns/lwip/src/include/ipv4/lwip/autoip.h | 118 - .../badvpn_dns/lwip/src/include/ipv4/lwip/icmp.h | 125 - .../badvpn_dns/lwip/src/include/ipv4/lwip/igmp.h | 106 - .../badvpn_dns/lwip/src/include/ipv4/lwip/inet.h | 107 - .../badvpn_dns/lwip/src/include/ipv4/lwip/ip4.h | 146 - .../lwip/src/include/ipv4/lwip/ip4_addr.h | 244 - .../lwip/src/include/ipv4/lwip/ip_frag.h | 91 - .../badvpn_dns/lwip/src/include/ipv6/lwip/dhcp6.h | 58 - .../badvpn_dns/lwip/src/include/ipv6/lwip/ethip6.h | 68 - .../badvpn_dns/lwip/src/include/ipv6/lwip/icmp6.h | 152 - .../badvpn_dns/lwip/src/include/ipv6/lwip/inet6.h | 92 - .../badvpn_dns/lwip/src/include/ipv6/lwip/ip6.h | 197 - .../lwip/src/include/ipv6/lwip/ip6_addr.h | 286 -- .../lwip/src/include/ipv6/lwip/ip6_frag.h | 102 - .../badvpn_dns/lwip/src/include/ipv6/lwip/mld6.h | 118 - .../badvpn_dns/lwip/src/include/ipv6/lwip/nd6.h | 369 -- external/badvpn_dns/lwip/src/include/lwip/api.h | 338 -- .../badvpn_dns/lwip/src/include/lwip/api_msg.h | 177 - external/badvpn_dns/lwip/src/include/lwip/arch.h | 217 - external/badvpn_dns/lwip/src/include/lwip/debug.h | 99 - external/badvpn_dns/lwip/src/include/lwip/def.h | 123 - external/badvpn_dns/lwip/src/include/lwip/dhcp.h | 242 - external/badvpn_dns/lwip/src/include/lwip/dns.h | 124 - external/badvpn_dns/lwip/src/include/lwip/err.h | 85 - .../badvpn_dns/lwip/src/include/lwip/inet_chksum.h | 112 - external/badvpn_dns/lwip/src/include/lwip/init.h | 72 - external/badvpn_dns/lwip/src/include/lwip/ip.h | 254 - .../badvpn_dns/lwip/src/include/lwip/ip_addr.h | 130 - external/badvpn_dns/lwip/src/include/lwip/mem.h | 123 - external/badvpn_dns/lwip/src/include/lwip/memp.h | 116 - .../badvpn_dns/lwip/src/include/lwip/memp_std.h | 135 - external/badvpn_dns/lwip/src/include/lwip/netbuf.h | 112 - external/badvpn_dns/lwip/src/include/lwip/netdb.h | 124 - external/badvpn_dns/lwip/src/include/lwip/netif.h | 393 -- .../badvpn_dns/lwip/src/include/lwip/netifapi.h | 108 - external/badvpn_dns/lwip/src/include/lwip/opt.h | 2417 ---------- external/badvpn_dns/lwip/src/include/lwip/pbuf.h | 185 - external/badvpn_dns/lwip/src/include/lwip/raw.h | 131 - external/badvpn_dns/lwip/src/include/lwip/sio.h | 141 - external/badvpn_dns/lwip/src/include/lwip/snmp.h | 367 -- .../badvpn_dns/lwip/src/include/lwip/snmp_asn1.h | 101 - .../badvpn_dns/lwip/src/include/lwip/snmp_msg.h | 315 -- .../lwip/src/include/lwip/snmp_structs.h | 268 -- .../badvpn_dns/lwip/src/include/lwip/sockets.h | 411 -- external/badvpn_dns/lwip/src/include/lwip/stats.h | 347 -- external/badvpn_dns/lwip/src/include/lwip/sys.h | 336 -- external/badvpn_dns/lwip/src/include/lwip/tcp.h | 400 -- .../badvpn_dns/lwip/src/include/lwip/tcp_impl.h | 508 -- external/badvpn_dns/lwip/src/include/lwip/tcpip.h | 179 - external/badvpn_dns/lwip/src/include/lwip/timers.h | 100 - external/badvpn_dns/lwip/src/include/lwip/udp.h | 215 - .../badvpn_dns/lwip/src/include/netif/etharp.h | 223 - .../badvpn_dns/lwip/src/include/netif/ppp_oe.h | 190 - .../badvpn_dns/lwip/src/include/netif/slipif.h | 81 - external/badvpn_dns/lwip/src/include/posix/netdb.h | 33 - .../badvpn_dns/lwip/src/include/posix/sys/socket.h | 33 - external/badvpn_dns/lwip/src/netif/FILES | 29 - external/badvpn_dns/lwip/src/netif/etharp.c | 1413 ------ external/badvpn_dns/lwip/src/netif/ethernetif.c | 322 -- external/badvpn_dns/lwip/src/netif/ppp/auth.c | 1334 ------ external/badvpn_dns/lwip/src/netif/ppp/auth.h | 111 - external/badvpn_dns/lwip/src/netif/ppp/chap.c | 908 ---- external/badvpn_dns/lwip/src/netif/ppp/chap.h | 150 - external/badvpn_dns/lwip/src/netif/ppp/chpms.c | 396 -- external/badvpn_dns/lwip/src/netif/ppp/chpms.h | 64 - external/badvpn_dns/lwip/src/netif/ppp/fsm.c | 890 ---- external/badvpn_dns/lwip/src/netif/ppp/fsm.h | 157 - external/badvpn_dns/lwip/src/netif/ppp/ipcp.c | 1411 ------ external/badvpn_dns/lwip/src/netif/ppp/ipcp.h | 106 - external/badvpn_dns/lwip/src/netif/ppp/lcp.c | 2066 --------- external/badvpn_dns/lwip/src/netif/ppp/lcp.h | 151 - external/badvpn_dns/lwip/src/netif/ppp/magic.c | 80 - external/badvpn_dns/lwip/src/netif/ppp/magic.h | 63 - external/badvpn_dns/lwip/src/netif/ppp/md5.c | 320 -- external/badvpn_dns/lwip/src/netif/ppp/md5.h | 55 - external/badvpn_dns/lwip/src/netif/ppp/pap.c | 628 --- external/badvpn_dns/lwip/src/netif/ppp/pap.h | 118 - external/badvpn_dns/lwip/src/netif/ppp/ppp.c | 2052 -------- external/badvpn_dns/lwip/src/netif/ppp/ppp.h | 201 - external/badvpn_dns/lwip/src/netif/ppp/ppp_impl.h | 363 -- external/badvpn_dns/lwip/src/netif/ppp/ppp_oe.c | 1132 ----- external/badvpn_dns/lwip/src/netif/ppp/pppdebug.h | 73 - external/badvpn_dns/lwip/src/netif/ppp/randm.c | 249 - external/badvpn_dns/lwip/src/netif/ppp/randm.h | 81 - external/badvpn_dns/lwip/src/netif/ppp/readme.txt | 21 - external/badvpn_dns/lwip/src/netif/ppp/vj.c | 652 --- external/badvpn_dns/lwip/src/netif/ppp/vj.h | 156 - external/badvpn_dns/lwip/src/netif/slipif.c | 546 --- external/badvpn_dns/lwip/test/unit/core/test_mem.c | 73 - external/badvpn_dns/lwip/test/unit/core/test_mem.h | 8 - .../badvpn_dns/lwip/test/unit/core/test_pbuf.c | 73 - .../badvpn_dns/lwip/test/unit/core/test_pbuf.h | 8 - .../badvpn_dns/lwip/test/unit/dhcp/test_dhcp.c | 916 ---- .../badvpn_dns/lwip/test/unit/dhcp/test_dhcp.h | 8 - .../badvpn_dns/lwip/test/unit/etharp/test_etharp.c | 262 -- .../badvpn_dns/lwip/test/unit/etharp/test_etharp.h | 8 - external/badvpn_dns/lwip/test/unit/lwip_check.h | 37 - .../badvpn_dns/lwip/test/unit/lwip_unittests.c | 49 - external/badvpn_dns/lwip/test/unit/lwipopts.h | 53 - .../badvpn_dns/lwip/test/unit/tcp/tcp_helper.c | 303 -- .../badvpn_dns/lwip/test/unit/tcp/tcp_helper.h | 52 - external/badvpn_dns/lwip/test/unit/tcp/test_tcp.c | 671 --- external/badvpn_dns/lwip/test/unit/tcp/test_tcp.h | 8 - .../badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.c | 958 ---- .../badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.h | 8 - external/badvpn_dns/lwip/test/unit/udp/test_udp.c | 68 - external/badvpn_dns/lwip/test/unit/udp/test_udp.h | 8 - external/badvpn_dns/misc/BRefTarget.h | 114 - external/badvpn_dns/misc/Utf16Decoder.h | 113 - external/badvpn_dns/misc/Utf16Encoder.h | 67 - external/badvpn_dns/misc/Utf8Decoder.h | 143 - external/badvpn_dns/misc/Utf8Encoder.h | 81 - external/badvpn_dns/misc/arp_proto.h | 60 - external/badvpn_dns/misc/array_length.h | 35 - external/badvpn_dns/misc/balign.h | 76 - external/badvpn_dns/misc/balloc.h | 248 - external/badvpn_dns/misc/blimits.h | 60 - external/badvpn_dns/misc/bsize.h | 117 - external/badvpn_dns/misc/bsort.h | 69 - external/badvpn_dns/misc/bstring.h | 140 - external/badvpn_dns/misc/byteorder.h | 196 - external/badvpn_dns/misc/cmdline.h | 181 - external/badvpn_dns/misc/compare.h | 37 - external/badvpn_dns/misc/concat_strings.h | 85 - external/badvpn_dns/misc/cstring.h | 347 -- external/badvpn_dns/misc/dead.h | 134 - external/badvpn_dns/misc/debug.h | 142 - external/badvpn_dns/misc/debugcounter.h | 118 - external/badvpn_dns/misc/debugerror.h | 90 - external/badvpn_dns/misc/dhcp_proto.h | 131 - external/badvpn_dns/misc/ethernet_proto.h | 52 - external/badvpn_dns/misc/exparray.h | 101 - external/badvpn_dns/misc/expstring.h | 161 - external/badvpn_dns/misc/find_char.h | 58 - external/badvpn_dns/misc/find_program.h | 103 - external/badvpn_dns/misc/get_iface_info.h | 110 - external/badvpn_dns/misc/grow_array.h | 139 - external/badvpn_dns/misc/hashfun.h | 60 - external/badvpn_dns/misc/igmp_proto.h | 97 - external/badvpn_dns/misc/ipaddr.h | 218 - external/badvpn_dns/misc/ipaddr6.h | 400 -- external/badvpn_dns/misc/ipv4_proto.h | 145 - external/badvpn_dns/misc/ipv6_proto.h | 86 - external/badvpn_dns/misc/loggers_string.h | 43 - external/badvpn_dns/misc/loglevel.h | 80 - external/badvpn_dns/misc/maxalign.h | 53 - external/badvpn_dns/misc/merge.h | 36 - external/badvpn_dns/misc/minmax.h | 56 - external/badvpn_dns/misc/modadd.h | 59 - external/badvpn_dns/misc/mswsock.h | 229 - external/badvpn_dns/misc/nonblocking.h | 51 - external/badvpn_dns/misc/nsskey.h | 118 - external/badvpn_dns/misc/offset.h | 51 - external/badvpn_dns/misc/open_standard_streams.h | 54 - external/badvpn_dns/misc/overflow.h | 66 - external/badvpn_dns/misc/packed.h | 51 - external/badvpn_dns/misc/parse_number.h | 304 -- external/badvpn_dns/misc/print_macros.h | 98 - external/badvpn_dns/misc/read_file.h | 98 - external/badvpn_dns/misc/read_write_int.h | 181 - external/badvpn_dns/misc/socks_proto.h | 118 - external/badvpn_dns/misc/sslsocket.h | 48 - external/badvpn_dns/misc/stdbuf_cmdline.h | 92 - external/badvpn_dns/misc/strdup.h | 86 - external/badvpn_dns/misc/string_begins_with.h | 96 - external/badvpn_dns/misc/substring.h | 81 - external/badvpn_dns/misc/udp_proto.h | 170 - external/badvpn_dns/misc/unicode_funcs.h | 232 - external/badvpn_dns/misc/version.h | 41 - external/badvpn_dns/misc/write_file.h | 104 - external/badvpn_dns/ncd-request/CMakeLists.txt | 9 - external/badvpn_dns/ncd-request/ncd-request.c | 224 - external/badvpn_dns/ncd/CMakeLists.txt | 211 - external/badvpn_dns/ncd/NCDAst.c | 1022 ---- external/badvpn_dns/ncd/NCDAst.h | 237 - external/badvpn_dns/ncd/NCDBuildProgram.c | 316 -- external/badvpn_dns/ncd/NCDBuildProgram.h | 49 - external/badvpn_dns/ncd/NCDConfigParser.c | 214 - external/badvpn_dns/ncd/NCDConfigParser.h | 40 - external/badvpn_dns/ncd/NCDConfigParser_parse.y | 718 --- external/badvpn_dns/ncd/NCDConfigTokenizer.c | 321 -- external/badvpn_dns/ncd/NCDConfigTokenizer.h | 64 - external/badvpn_dns/ncd/NCDInterpProcess.c | 497 -- external/badvpn_dns/ncd/NCDInterpProcess.h | 100 - external/badvpn_dns/ncd/NCDInterpProg.c | 140 - external/badvpn_dns/ncd/NCDInterpProg.h | 63 - external/badvpn_dns/ncd/NCDInterpProg_hash.h | 12 - external/badvpn_dns/ncd/NCDInterpreter.c | 1356 ------ external/badvpn_dns/ncd/NCDInterpreter.h | 156 - external/badvpn_dns/ncd/NCDMethodIndex.c | 272 -- external/badvpn_dns/ncd/NCDMethodIndex.h | 135 - external/badvpn_dns/ncd/NCDMethodIndex_hash.h | 12 - external/badvpn_dns/ncd/NCDModule.c | 625 --- external/badvpn_dns/ncd/NCDModule.h | 1011 ---- external/badvpn_dns/ncd/NCDModuleIndex.c | 372 -- external/badvpn_dns/ncd/NCDModuleIndex.h | 86 - external/badvpn_dns/ncd/NCDModuleIndex_mhash.h | 12 - external/badvpn_dns/ncd/NCDObject.c | 40 - external/badvpn_dns/ncd/NCDObject.h | 356 -- external/badvpn_dns/ncd/NCDPlaceholderDb.c | 127 - external/badvpn_dns/ncd/NCDPlaceholderDb.h | 95 - external/badvpn_dns/ncd/NCDStringIndex.c | 262 -- external/badvpn_dns/ncd/NCDStringIndex.h | 83 - external/badvpn_dns/ncd/NCDStringIndex_hash.h | 13 - external/badvpn_dns/ncd/NCDSugar.c | 253 - external/badvpn_dns/ncd/NCDSugar.h | 38 - external/badvpn_dns/ncd/NCDVal.c | 2065 --------- external/badvpn_dns/ncd/NCDVal.h | 857 ---- external/badvpn_dns/ncd/NCDValCons.c | 283 -- external/badvpn_dns/ncd/NCDValCons.h | 176 - external/badvpn_dns/ncd/NCDValGenerator.c | 193 - external/badvpn_dns/ncd/NCDValGenerator.h | 40 - external/badvpn_dns/ncd/NCDValParser.c | 225 - external/badvpn_dns/ncd/NCDValParser.h | 50 - external/badvpn_dns/ncd/NCDValParser_parse.y | 202 - external/badvpn_dns/ncd/NCDVal_maptree.h | 15 - external/badvpn_dns/ncd/README | 386 -- external/badvpn_dns/ncd/emncd.c | 137 - external/badvpn_dns/ncd/emncd.html | 320 -- external/badvpn_dns/ncd/examples/dbus_start.ncd | 82 - .../badvpn_dns/ncd/examples/dhcpd.conf.template | 11 - .../badvpn_dns/ncd/examples/directory_updater.ncd | 72 - external/badvpn_dns/ncd/examples/events.ncd | 101 - .../ncd/examples/igmpproxy.conf.template | 10 - .../badvpn_dns/ncd/examples/make_dhcp_config.ncd | 27 - .../ncd/examples/make_igmpproxy_config.ncd | 53 - external/badvpn_dns/ncd/examples/network.ncd | 123 - external/badvpn_dns/ncd/examples/onoff_server.ncdi | 82 - .../badvpn_dns/ncd/examples/onoff_server_test.ncd | 20 - external/badvpn_dns/ncd/examples/router/README | 36 - .../ncd/examples/router/add-port-forwarding | 43 - .../ncd/examples/router/dhcp_server.ncdi | 60 - .../ncd/examples/router/list-port-forwardings | 61 - external/badvpn_dns/ncd/examples/router/ncd.conf | 6 - .../badvpn_dns/ncd/examples/router/network.ncdi | 356 -- .../examples/router/network_control_server.ncdi | 96 - .../ncd/examples/router/port_forwarding.ncdi | 170 - external/badvpn_dns/ncd/examples/router/pppoe.ncdi | 296 -- .../ncd/examples/router/remove-port-forwarding | 43 - .../badvpn_dns/ncd/examples/router/unbound.ncdi | 42 - .../badvpn_dns/ncd/examples/tcp_echo_client.ncd | 35 - .../badvpn_dns/ncd/examples/tcp_echo_server.ncd | 40 - external/badvpn_dns/ncd/extra/BEventLock.c | 146 - external/badvpn_dns/ncd/extra/BEventLock.h | 127 - external/badvpn_dns/ncd/extra/NCDBProcessOpts.c | 154 - external/badvpn_dns/ncd/extra/NCDBProcessOpts.h | 54 - external/badvpn_dns/ncd/extra/NCDBuf.c | 123 - external/badvpn_dns/ncd/extra/NCDBuf.h | 61 - external/badvpn_dns/ncd/extra/NCDIfConfig.c | 483 -- external/badvpn_dns/ncd/extra/NCDIfConfig.h | 70 - .../badvpn_dns/ncd/extra/NCDInterfaceMonitor.c | 446 -- .../badvpn_dns/ncd/extra/NCDInterfaceMonitor.h | 160 - external/badvpn_dns/ncd/extra/NCDRequestClient.c | 647 --- external/badvpn_dns/ncd/extra/NCDRequestClient.h | 111 - external/badvpn_dns/ncd/extra/NCDRfkillMonitor.c | 117 - external/badvpn_dns/ncd/extra/NCDRfkillMonitor.h | 53 - external/badvpn_dns/ncd/extra/address_utils.h | 280 -- external/badvpn_dns/ncd/extra/build_cmdline.c | 111 - external/badvpn_dns/ncd/extra/build_cmdline.h | 38 - external/badvpn_dns/ncd/extra/make_fast_names.h | 154 - external/badvpn_dns/ncd/extra/value_utils.h | 174 - external/badvpn_dns/ncd/include_linux_input.c | 1 - external/badvpn_dns/ncd/make_name_indices.h | 104 - external/badvpn_dns/ncd/modules/alias.c | 148 - external/badvpn_dns/ncd/modules/arithmetic.c | 404 -- external/badvpn_dns/ncd/modules/assert.c | 105 - external/badvpn_dns/ncd/modules/backtrack.c | 103 - external/badvpn_dns/ncd/modules/blocker.c | 353 -- external/badvpn_dns/ncd/modules/buffer.c | 619 --- .../badvpn_dns/ncd/modules/buffer_chunks_tree.h | 9 - external/badvpn_dns/ncd/modules/call2.c | 498 -- external/badvpn_dns/ncd/modules/choose.c | 145 - external/badvpn_dns/ncd/modules/command_template.c | 218 - external/badvpn_dns/ncd/modules/command_template.h | 62 - external/badvpn_dns/ncd/modules/concat.c | 189 - external/badvpn_dns/ncd/modules/daemon.c | 296 -- external/badvpn_dns/ncd/modules/depend.c | 452 -- external/badvpn_dns/ncd/modules/depend_scope.c | 466 -- external/badvpn_dns/ncd/modules/dynamic_depend.c | 548 --- external/badvpn_dns/ncd/modules/event_template.c | 184 - external/badvpn_dns/ncd/modules/event_template.h | 64 - external/badvpn_dns/ncd/modules/exit.c | 91 - external/badvpn_dns/ncd/modules/explode.c | 232 - external/badvpn_dns/ncd/modules/file.c | 350 -- external/badvpn_dns/ncd/modules/file_open.c | 585 --- external/badvpn_dns/ncd/modules/foreach.c | 715 --- external/badvpn_dns/ncd/modules/from_string.c | 125 - external/badvpn_dns/ncd/modules/getargs.c | 98 - external/badvpn_dns/ncd/modules/getenv.c | 153 - external/badvpn_dns/ncd/modules/if.c | 103 - external/badvpn_dns/ncd/modules/imperative.c | 324 -- external/badvpn_dns/ncd/modules/implode.c | 155 - external/badvpn_dns/ncd/modules/index.c | 164 - external/badvpn_dns/ncd/modules/list.c | 871 ---- external/badvpn_dns/ncd/modules/load_module.c | 313 -- external/badvpn_dns/ncd/modules/log.c | 285 -- external/badvpn_dns/ncd/modules/logical.c | 160 - external/badvpn_dns/ncd/modules/modules.h | 210 - external/badvpn_dns/ncd/modules/multidepend.c | 401 -- .../badvpn_dns/ncd/modules/net_backend_badvpn.c | 281 -- .../badvpn_dns/ncd/modules/net_backend_rfkill.c | 216 - .../ncd/modules/net_backend_waitdevice.c | 187 - .../badvpn_dns/ncd/modules/net_backend_waitlink.c | 155 - .../ncd/modules/net_backend_wpa_supplicant.c | 573 --- external/badvpn_dns/ncd/modules/net_dns.c | 434 -- external/badvpn_dns/ncd/modules/net_iptables.c | 749 --- external/badvpn_dns/ncd/modules/net_ipv4_addr.c | 148 - .../ncd/modules/net_ipv4_addr_in_network.c | 173 - .../badvpn_dns/ncd/modules/net_ipv4_arp_probe.c | 212 - external/badvpn_dns/ncd/modules/net_ipv4_dhcp.c | 351 -- external/badvpn_dns/ncd/modules/net_ipv4_route.c | 211 - external/badvpn_dns/ncd/modules/net_ipv6_addr.c | 148 - .../ncd/modules/net_ipv6_addr_in_network.c | 168 - external/badvpn_dns/ncd/modules/net_ipv6_route.c | 213 - .../ncd/modules/net_ipv6_wait_dynamic_addr.c | 201 - external/badvpn_dns/ncd/modules/net_up.c | 119 - .../badvpn_dns/ncd/modules/net_watch_interfaces.c | 474 -- external/badvpn_dns/ncd/modules/netmask.c | 263 -- external/badvpn_dns/ncd/modules/ondemand.c | 372 -- external/badvpn_dns/ncd/modules/parse.c | 392 -- external/badvpn_dns/ncd/modules/print.c | 207 - external/badvpn_dns/ncd/modules/process_manager.c | 538 --- external/badvpn_dns/ncd/modules/reboot.c | 103 - external/badvpn_dns/ncd/modules/ref.c | 215 - external/badvpn_dns/ncd/modules/regex_match.c | 369 -- external/badvpn_dns/ncd/modules/run.c | 187 - external/badvpn_dns/ncd/modules/runonce.c | 331 -- external/badvpn_dns/ncd/modules/sleep.c | 178 - external/badvpn_dns/ncd/modules/socket.c | 1057 ----- external/badvpn_dns/ncd/modules/spawn.c | 410 -- external/badvpn_dns/ncd/modules/strcmp.c | 107 - external/badvpn_dns/ncd/modules/substr.c | 167 - external/badvpn_dns/ncd/modules/sys_evdev.c | 348 -- .../badvpn_dns/ncd/modules/sys_request_client.c | 646 --- .../badvpn_dns/ncd/modules/sys_request_server.c | 792 ---- .../badvpn_dns/ncd/modules/sys_start_process.c | 1266 ----- .../badvpn_dns/ncd/modules/sys_watch_directory.c | 425 -- external/badvpn_dns/ncd/modules/sys_watch_input.c | 455 -- external/badvpn_dns/ncd/modules/sys_watch_usb.c | 421 -- external/badvpn_dns/ncd/modules/timer.c | 146 - external/badvpn_dns/ncd/modules/to_string.c | 116 - external/badvpn_dns/ncd/modules/try.c | 302 -- external/badvpn_dns/ncd/modules/value.c | 2102 --------- external/badvpn_dns/ncd/modules/value_maptree.h | 11 - external/badvpn_dns/ncd/modules/valuemetic.c | 219 - external/badvpn_dns/ncd/modules/var.c | 163 - external/badvpn_dns/ncd/ncd.c | 463 -- external/badvpn_dns/ncd/ncd.h | 37 - external/badvpn_dns/ncd/parse_linux_input.sh | 94 - external/badvpn_dns/ncd/static_strings.h | 70 - external/badvpn_dns/ncd/tests/addr_in_network.ncd | 60 - external/badvpn_dns/ncd/tests/alias.ncd | 48 - external/badvpn_dns/ncd/tests/arithmetic.ncd | 69 - external/badvpn_dns/ncd/tests/backtracking.ncd | 31 - external/badvpn_dns/ncd/tests/buffer.ncd | 54 - external/badvpn_dns/ncd/tests/call.ncd | 18 - external/badvpn_dns/ncd/tests/concat.ncd | 19 - external/badvpn_dns/ncd/tests/depend.ncd | 64 - external/badvpn_dns/ncd/tests/depend_scope.ncd | 31 - external/badvpn_dns/ncd/tests/escape_and_nulls.ncd | 38 - external/badvpn_dns/ncd/tests/explode.ncd | 23 - external/badvpn_dns/ncd/tests/foreach.ncd | 35 - external/badvpn_dns/ncd/tests/if.ncd | 38 - external/badvpn_dns/ncd/tests/implode.ncd | 15 - external/badvpn_dns/ncd/tests/include.ncd | 16 - .../badvpn_dns/ncd/tests/include_included.ncdi | 5 - .../badvpn_dns/ncd/tests/include_included2.ncdi | 5 - external/badvpn_dns/ncd/tests/logical.ncd | 46 - external/badvpn_dns/ncd/tests/multidepend.ncd | 30 - external/badvpn_dns/ncd/tests/netmask.ncd | 15 - external/badvpn_dns/ncd/tests/parse.ncd | 85 - external/badvpn_dns/ncd/tests/process_manager.ncd | 112 - external/badvpn_dns/ncd/tests/regex.ncd | 48 - external/badvpn_dns/ncd/tests/run_tests | 38 - external/badvpn_dns/ncd/tests/strings.ncd | 47 - external/badvpn_dns/ncd/tests/substr.ncd | 37 - external/badvpn_dns/ncd/tests/turing.ncd | 138 - external/badvpn_dns/ncd/tests/value.ncd | 258 -- external/badvpn_dns/ncd/tests/value_substr.ncd | 25 - external/badvpn_dns/nspr_support/BSSLConnection.c | 1024 ---- external/badvpn_dns/nspr_support/BSSLConnection.h | 116 - external/badvpn_dns/nspr_support/CMakeLists.txt | 5 - external/badvpn_dns/nspr_support/DummyPRFileDesc.c | 176 - external/badvpn_dns/nspr_support/DummyPRFileDesc.h | 61 - external/badvpn_dns/predicate/BPredicate.c | 284 -- external/badvpn_dns/predicate/BPredicate.h | 177 - external/badvpn_dns/predicate/BPredicate.l | 83 - external/badvpn_dns/predicate/BPredicate.y | 345 -- .../badvpn_dns/predicate/BPredicate_internal.h | 154 - external/badvpn_dns/predicate/BPredicate_parser.h | 47 - external/badvpn_dns/predicate/CMakeLists.txt | 6 - .../badvpn_dns/predicate/LexMemoryBufferInput.h | 86 - external/badvpn_dns/protocol/addr.bproto | 11 - external/badvpn_dns/protocol/addr.h | 207 - external/badvpn_dns/protocol/dataproto.h | 91 - external/badvpn_dns/protocol/fragmentproto.h | 100 - external/badvpn_dns/protocol/msgproto.bproto | 43 - external/badvpn_dns/protocol/msgproto.h | 76 - external/badvpn_dns/protocol/packetproto.h | 68 - external/badvpn_dns/protocol/requestproto.h | 50 - external/badvpn_dns/protocol/scproto.h | 266 -- external/badvpn_dns/protocol/spproto.h | 195 - external/badvpn_dns/protocol/udpgw_proto.h | 84 - external/badvpn_dns/random/BRandom2.c | 90 - external/badvpn_dns/random/BRandom2.h | 50 - external/badvpn_dns/random/CMakeLists.txt | 1 - external/badvpn_dns/scripts/cmake | 8 - external/badvpn_dns/scripts/copy_nss | 23 - external/badvpn_dns/scripts/toolchain.cmake | 6 - external/badvpn_dns/security/BEncryption.c | 240 - external/badvpn_dns/security/BEncryption.h | 175 - external/badvpn_dns/security/BHash.c | 69 - external/badvpn_dns/security/BHash.h | 80 - external/badvpn_dns/security/BRandom.c | 42 - external/badvpn_dns/security/BRandom.h | 49 - external/badvpn_dns/security/BSecurity.c | 149 - external/badvpn_dns/security/BSecurity.h | 60 - external/badvpn_dns/security/CMakeLists.txt | 10 - external/badvpn_dns/security/OTPCalculator.c | 118 - external/badvpn_dns/security/OTPCalculator.h | 96 - external/badvpn_dns/security/OTPChecker.c | 297 -- external/badvpn_dns/security/OTPChecker.h | 148 - external/badvpn_dns/security/OTPGenerator.c | 159 - external/badvpn_dns/security/OTPGenerator.h | 134 - external/badvpn_dns/server/CMakeLists.txt | 12 - external/badvpn_dns/server/badvpn-server.8 | 190 - external/badvpn_dns/server/server.c | 2394 ---------- external/badvpn_dns/server/server.h | 186 - .../badvpn_dns/server_connection/CMakeLists.txt | 5 - .../server_connection/SCKeepaliveSource.c | 69 - .../server_connection/SCKeepaliveSource.h | 72 - .../server_connection/ServerConnection.c | 669 --- .../server_connection/ServerConnection.h | 289 -- external/badvpn_dns/socksclient/BSocksClient.c | 608 --- external/badvpn_dns/socksclient/BSocksClient.h | 147 - external/badvpn_dns/socksclient/CMakeLists.txt | 1 - external/badvpn_dns/stringmap/BStringMap.c | 198 - external/badvpn_dns/stringmap/BStringMap.h | 57 - external/badvpn_dns/stringmap/CMakeLists.txt | 1 - external/badvpn_dns/structure/BAVL.h | 797 ---- external/badvpn_dns/structure/CAvl.h | 36 - external/badvpn_dns/structure/CAvl_decl.h | 77 - external/badvpn_dns/structure/CAvl_footer.h | 113 - external/badvpn_dns/structure/CAvl_header.h | 141 - external/badvpn_dns/structure/CAvl_impl.h | 949 ---- external/badvpn_dns/structure/CHash.h | 39 - external/badvpn_dns/structure/CHash_decl.h | 59 - external/badvpn_dns/structure/CHash_footer.h | 74 - external/badvpn_dns/structure/CHash_header.h | 78 - external/badvpn_dns/structure/CHash_impl.h | 312 -- external/badvpn_dns/structure/ChunkBuffer2.h | 317 -- external/badvpn_dns/structure/IndexedList.h | 225 - external/badvpn_dns/structure/IndexedList_tree.h | 15 - external/badvpn_dns/structure/LinkedList0.h | 202 - external/badvpn_dns/structure/LinkedList1.h | 275 -- external/badvpn_dns/structure/LinkedList3.h | 362 -- external/badvpn_dns/structure/SAvl.h | 40 - external/badvpn_dns/structure/SAvl_decl.h | 73 - external/badvpn_dns/structure/SAvl_footer.h | 89 - external/badvpn_dns/structure/SAvl_header.h | 93 - external/badvpn_dns/structure/SAvl_impl.h | 164 - external/badvpn_dns/structure/SAvl_tree.h | 18 - external/badvpn_dns/structure/SLinkedList.h | 38 - external/badvpn_dns/structure/SLinkedList_decl.h | 67 - external/badvpn_dns/structure/SLinkedList_footer.h | 57 - external/badvpn_dns/structure/SLinkedList_header.h | 62 - external/badvpn_dns/structure/SLinkedList_impl.h | 182 - external/badvpn_dns/system/BAddr.h | 808 ---- external/badvpn_dns/system/BConnection.h | 369 -- external/badvpn_dns/system/BConnectionGeneric.h | 144 - external/badvpn_dns/system/BConnection_unix.c | 1057 ----- external/badvpn_dns/system/BConnection_unix.h | 87 - external/badvpn_dns/system/BConnection_win.c | 875 ---- external/badvpn_dns/system/BConnection_win.h | 101 - external/badvpn_dns/system/BDatagram.h | 209 - external/badvpn_dns/system/BDatagram_unix.c | 855 ---- external/badvpn_dns/system/BDatagram_unix.h | 71 - external/badvpn_dns/system/BDatagram_win.c | 755 --- external/badvpn_dns/system/BDatagram_win.h | 99 - external/badvpn_dns/system/BInputProcess.c | 211 - external/badvpn_dns/system/BInputProcess.h | 65 - external/badvpn_dns/system/BLockReactor.c | 131 - external/badvpn_dns/system/BLockReactor.h | 58 - external/badvpn_dns/system/BNetwork.c | 99 - external/badvpn_dns/system/BNetwork.h | 36 - external/badvpn_dns/system/BProcess.c | 400 -- external/badvpn_dns/system/BProcess.h | 200 - external/badvpn_dns/system/BReactor.h | 11 - external/badvpn_dns/system/BReactor_badvpn.c | 1430 ------ external/badvpn_dns/system/BReactor_badvpn.h | 572 --- .../badvpn_dns/system/BReactor_badvpn_timerstree.h | 13 - external/badvpn_dns/system/BReactor_emscripten.c | 176 - external/badvpn_dns/system/BReactor_emscripten.h | 87 - external/badvpn_dns/system/BReactor_glib.c | 524 --- external/badvpn_dns/system/BReactor_glib.h | 148 - external/badvpn_dns/system/BSignal.c | 188 - external/badvpn_dns/system/BSignal.h | 64 - external/badvpn_dns/system/BThreadSignal.c | 136 - external/badvpn_dns/system/BThreadSignal.h | 53 - external/badvpn_dns/system/BTime.c | 38 - external/badvpn_dns/system/BTime.h | 163 - external/badvpn_dns/system/BUnixSignal.c | 406 -- external/badvpn_dns/system/BUnixSignal.h | 132 - external/badvpn_dns/system/CMakeLists.txt | 44 - external/badvpn_dns/tests/CMakeLists.txt | 8 - external/badvpn_dns/tests/bproto_test.bproto | 9 - external/badvpn_dns/tests/bproto_test.c | 76 - external/badvpn_dns/tests/chunkbuffer2_test.c | 86 - external/badvpn_dns/tests/threadwork_test.c | 87 - external/badvpn_dns/threadwork/BThreadWork.c | 451 -- external/badvpn_dns/threadwork/BThreadWork.h | 171 - external/badvpn_dns/threadwork/CMakeLists.txt | 6 - external/badvpn_dns/tun2socks/CMakeLists.txt | 15 - external/badvpn_dns/tun2socks/SocksUdpGwClient.c | 228 - external/badvpn_dns/tun2socks/SocksUdpGwClient.h | 64 - external/badvpn_dns/tun2socks/badvpn-tun2socks.8 | 126 - external/badvpn_dns/tun2socks/tun2socks.c | 2138 --------- external/badvpn_dns/tun2socks/tun2socks.h | 46 - external/badvpn_dns/tunctl/CMakeLists.txt | 6 - external/badvpn_dns/tunctl/tunctl.c | 352 -- external/badvpn_dns/tuntap/BTap.c | 631 --- external/badvpn_dns/tuntap/BTap.h | 199 - external/badvpn_dns/tuntap/CMakeLists.txt | 10 - external/badvpn_dns/tuntap/tapwin32-funcs.c | 227 - external/badvpn_dns/tuntap/tapwin32-funcs.h | 42 - external/badvpn_dns/tuntap/wintap-common.h | 39 - external/badvpn_dns/udevmonitor/CMakeLists.txt | 7 - external/badvpn_dns/udevmonitor/NCDUdevCache.c | 417 -- external/badvpn_dns/udevmonitor/NCDUdevCache.h | 66 - external/badvpn_dns/udevmonitor/NCDUdevManager.c | 547 --- external/badvpn_dns/udevmonitor/NCDUdevManager.h | 84 - external/badvpn_dns/udevmonitor/NCDUdevMonitor.c | 250 - external/badvpn_dns/udevmonitor/NCDUdevMonitor.h | 71 - .../badvpn_dns/udevmonitor/NCDUdevMonitorParser.c | 358 -- .../badvpn_dns/udevmonitor/NCDUdevMonitorParser.h | 76 - external/badvpn_dns/udpgw/CMakeLists.txt | 9 - external/badvpn_dns/udpgw/udpgw.c | 1473 ------ external/badvpn_dns/udpgw/udpgw.h | 52 - external/badvpn_dns/udpgw_client/CMakeLists.txt | 1 - external/badvpn_dns/udpgw_client/UdpGwClient.c | 597 --- external/badvpn_dns/udpgw_client/UdpGwClient.h | 118 - 971 files changed, 227043 deletions(-)
diff --git a/external/badvpn_dns/Android.mk b/external/badvpn_dns/Android.mk deleted file mode 100644 index 3829065..0000000 --- a/external/badvpn_dns/Android.mk +++ /dev/null @@ -1,75 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := tun2socks - -LOCAL_CFLAGS := -std=gnu99 -LOCAL_CFLAGS += -DBADVPN_THREAD_SAFE=0 -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE -LOCAL_CFLAGS += -DBADVPN_USE_SELFPIPE -DBADVPN_USE_EPOLL -LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -LOCAL_CFLAGS += -DPSIPHON - -LOCAL_C_INCLUDES:= \ - $(LOCAL_PATH) \ - $(LOCAL_PATH)/lwip/src/include/ipv4 \ - $(LOCAL_PATH)/lwip/src/include/ipv6 \ - $(LOCAL_PATH)/lwip/src/include \ - $(LOCAL_PATH)/lwip/custom - -LOCAL_SRC_FILES := \ - base/BLog_syslog.c \ - system/BReactor_badvpn.c \ - system/BSignal.c \ - system/BConnection_unix.c \ - system/BTime.c \ - system/BUnixSignal.c \ - system/BNetwork.c \ - flow/StreamRecvInterface.c \ - flow/PacketRecvInterface.c \ - flow/PacketPassInterface.c \ - flow/StreamPassInterface.c \ - flow/SinglePacketBuffer.c \ - flow/BufferWriter.c \ - flow/PacketBuffer.c \ - flow/PacketStreamSender.c \ - flow/PacketPassConnector.c \ - flow/PacketProtoFlow.c \ - flow/PacketPassFairQueue.c \ - flow/PacketProtoEncoder.c \ - flow/PacketProtoDecoder.c \ - socksclient/BSocksClient.c \ - tuntap/BTap.c \ - lwip/src/core/timers.c \ - lwip/src/core/udp.c \ - lwip/src/core/memp.c \ - lwip/src/core/init.c \ - lwip/src/core/pbuf.c \ - lwip/src/core/tcp.c \ - lwip/src/core/tcp_out.c \ - lwip/src/core/netif.c \ - lwip/src/core/def.c \ - lwip/src/core/mem.c \ - lwip/src/core/tcp_in.c \ - lwip/src/core/stats.c \ - lwip/src/core/inet_chksum.c \ - lwip/src/core/ipv4/icmp.c \ - lwip/src/core/ipv4/ip4.c \ - lwip/src/core/ipv4/ip4_addr.c \ - lwip/src/core/ipv4/ip_frag.c \ - lwip/src/core/ipv6/ip6.c \ - lwip/src/core/ipv6/nd6.c \ - lwip/src/core/ipv6/icmp6.c \ - lwip/src/core/ipv6/ip6_addr.c \ - lwip/src/core/ipv6/ip6_frag.c \ - lwip/custom/sys.c \ - tun2socks/tun2socks.c \ - base/DebugObject.c \ - base/BLog.c \ - base/BPending.c \ - flowextra/PacketPassInactivityMonitor.c \ - tun2socks/SocksUdpGwClient.c \ - udpgw_client/UdpGwClient.c - -include $(BUILD_SHARED_LIBRARY) - diff --git a/external/badvpn_dns/CMakeLists.txt b/external/badvpn_dns/CMakeLists.txt deleted file mode 100644 index ebdc0d7..0000000 --- a/external/badvpn_dns/CMakeLists.txt +++ /dev/null @@ -1,408 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(BADVPN C) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules") - -include(TestBigEndian) -include(CheckIncludeFiles) -include(CheckSymbolExists) -include(CheckTypeSize) - -set(BUILD_COMPONENTS) - -macro (build_switch name text default) - if (BUILD_NOTHING_BY_DEFAULT) - option(BUILD_${name} "${text}" OFF) - else () - option(BUILD_${name} "${text}" "${default}") - endif () - list(APPEND BUILD_COMPONENTS "${name}") -endmacro () - -# detect Emscripten -if (CMAKE_C_COMPILER MATCHES "/emcc$") - set(EMSCRIPTEN ON) -else () - set(EMSCRIPTEN OFF) -endif () - -if (EMSCRIPTEN) - set(ON_IF_NOT_EMSCRIPTEN OFF) -else () - set(ON_IF_NOT_EMSCRIPTEN ON) -endif() - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT EMSCRIPTEN) - set(ON_IF_LINUX ON) -else () - set(ON_IF_LINUX OFF) -endif() - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR EMSCRIPTEN) - set(ON_IF_LINUX_OR_EMSCRIPTEN ON) -else () - set(ON_IF_LINUX_OR_EMSCRIPTEN OFF) -endif () - -# define build defaults -build_switch(EXAMPLES "build example programs" ON) -build_switch(TESTS "build some other example programs" ON) -build_switch(SERVER "build badvpn-server" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(CLIENT "build badvpn-client" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(FLOODER "build badvpn-flooder" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(TUN2SOCKS "build badvpn-tun2socks" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(UDPGW "build badvpn-udpgw" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(NCD "build badvpn-ncd" ${ON_IF_LINUX_OR_EMSCRIPTEN}) -build_switch(TUNCTL "build badvpn-tunctl" ${ON_IF_LINUX}) -build_switch(DOSTEST "build dostest-server and dostest-attacker" OFF) - -if (BUILD_NCD AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")) - message(FATAL_ERROR "NCD is only available on Linux") -endif () - -if (BUILD_CLIENT OR BUILD_SERVER) - find_package(OpenSSL REQUIRED) - set(LIBCRYPTO_INCLUDE_DIRS "${OpenSSL_INCLUDE_DIRS}") - set(LIBCRYPTO_LIBRARY_DIRS "${OpenSSL_LIBRARY_DIRS}") - set(LIBCRYPTO_LIBRARIES "${OpenSSL_LIBRARIES}") -endif () - -if (BUILD_SERVER OR BUILD_CLIENT OR BUILD_FLOODER) - find_package(NSPR REQUIRED) - find_package(NSS REQUIRED) -endif () - -# choose reactor -if (DEFINED BREACTOR_BACKEND) - if (NOT (BREACTOR_BACKEND STREQUAL "badvpn" OR BREACTOR_BACKEND STREQUAL "glib")) - message(FATAL_ERROR "unknown reactor backend specified") - endif () -else () - if (EMSCRIPTEN) - set(BREACTOR_BACKEND "emscripten") - else () - set(BREACTOR_BACKEND "badvpn") - endif () -endif () - -if (BREACTOR_BACKEND STREQUAL "badvpn") - add_definitions(-DBADVPN_BREACTOR_BADVPN) -elseif (BREACTOR_BACKEND STREQUAL "glib") - if (NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")) - message(FATAL_ERROR "GLib reactor backend is only available on Linux") - endif () - find_package(GLIB2 REQUIRED) - add_definitions(-DBADVPN_BREACTOR_GLIB) -elseif (BREACTOR_BACKEND STREQUAL "emscripten") - add_definitions(-DBADVPN_BREACTOR_EMSCRIPTEN) -endif () - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${LIBCRYPTO_INCLUDE_DIRS} - ${NSPR_INCLUDE_DIRS} - ${NSS_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIR} - lwip/custom - lwip/src/include - lwip/src/include/ipv4 - lwip/src/include/ipv6 -) - -link_directories( - ${LIBCRYPTO_LIBRARY_DIRS} - ${NSPR_LIBRARY_DIRS} - ${NSS_LIBRARY_DIRS} -) - -test_big_endian(BIG_ENDIAN) - -check_type_size(int INT_SIZE) -if (NOT (INT_SIZE GREATER "3")) - message(FATAL_ERROR "int must be at least 32 bits") -endif () - -check_type_size(size_t SIZE_SIZE) -if (NOT (SIZE_SIZE GREATER INT_SIZE OR SIZE_SIZE EQUAL INT_SIZE)) - message(FATAL_ERROR "size_t must be greater or equal than int") -endif () - -if (MSVC) - add_definitions(/TP -D_CRT_SECURE_NO_WARNINGS /wd4065 /wd4018 /wd4533 /wd4244 /wd4102) -else () - add_definitions(-std=gnu99 -Wall -Wno-unused-value -Wno-parentheses -Wno-switch -Wredundant-decls) - - if (NOT CMAKE_C_COMPILER_ID STREQUAL "PathScale") - add_definitions(-Werror=implicit-function-declaration -Wno-switch-enum -Wno-unused-function - -Wstrict-aliasing) - endif () - - if (CMAKE_C_COMPILER_ID MATCHES "^Clang") - add_definitions(-Wno-initializer-overrides -Wno-tautological-constant-out-of-range-compare) - endif () -endif () - -# platform-specific stuff -if (WIN32) - add_definitions(-DBADVPN_USE_WINAPI -D_WIN32_WINNT=0x600 -DWIN32_LEAN_AND_MEAN) - add_definitions(-DBADVPN_THREAD_SAFE=0) - - set(CMAKE_REQUIRED_DEFINITIONS "-D_WIN32_WINNT=0x600") - check_symbol_exists(WSAID_WSASENDMSG "winsock2.h;mswsock.h" HAVE_MSW_1) - check_symbol_exists(WSAID_WSARECVMSG "winsock2.h;mswsock.h" HAVE_MSW_2) - check_symbol_exists(WSAID_ACCEPTEX "winsock2.h;mswsock.h" HAVE_MSW_3) - check_symbol_exists(WSAID_GETACCEPTEXSOCKADDRS "winsock2.h;mswsock.h" HAVE_MSW_4) - check_symbol_exists(WSAID_CONNECTEX "winsock2.h;mswsock.h" HAVE_MSW_5) - set(CMAKE_REQUIRED_DEFINITIONS "") - if (NOT (HAVE_MSW_1 AND HAVE_MSW_2 AND HAVE_MSW_3 AND HAVE_MSW_4 AND HAVE_MSW_5)) - add_definitions(-DBADVPN_USE_SHIPPED_MSWSOCK) - check_type_size(WSAMSG HAVE_WSAMSG) - if (NOT HAVE_WSAMSG) - add_definitions(-DBADVPN_SHIPPED_MSWSOCK_DECLARE_WSAMSG) - endif () - endif () -else () - set(BADVPN_THREADWORK_USE_PTHREAD 1) - add_definitions(-DBADVPN_THREADWORK_USE_PTHREAD) - add_definitions(-DBADVPN_THREAD_SAFE=1) - - link_libraries(rt) - - if (EMSCRIPTEN) - add_definitions(-DBADVPN_EMSCRIPTEN) - add_definitions(-DBADVPN_NO_PROCESS -DBADVPN_NO_UDEV -DBADVPN_NO_RANDOM) - elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_definitions(-DBADVPN_LINUX) - - check_include_files(sys/signalfd.h HAVE_SYS_SIGNALFD_H) - if (HAVE_SYS_SIGNALFD_H) - add_definitions(-DBADVPN_USE_SIGNALFD) - else () - add_definitions(-DBADVPN_USE_SELFPIPE) - endif () - - check_include_files(sys/epoll.h HAVE_SYS_EPOLL_H) - if (HAVE_SYS_EPOLL_H) - add_definitions(-DBADVPN_USE_EPOLL) - else () - add_definitions(-DBADVPN_USE_POLL) - endif () - - check_include_files(linux/rfkill.h HAVE_LINUX_RFKILL_H) - if (HAVE_LINUX_RFKILL_H) - add_definitions(-DBADVPN_USE_LINUX_RFKILL) - set(BADVPN_USE_LINUX_RFKILL 1) - endif () - - check_include_files(linux/input.h HAVE_LINUX_INPUT_H) - if (HAVE_LINUX_INPUT_H) - add_definitions(-DBADVPN_USE_LINUX_INPUT) - set(BADVPN_USE_LINUX_INPUT 1) - endif () - - check_include_files(sys/inotify.h HAVE_SYS_INOTIFY_H) - if (HAVE_SYS_INOTIFY_H) - add_definitions(-DBADVPN_USE_INOTIFY) - set(BADVPN_USE_INOTIFY 1) - endif () - elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - add_definitions(-DBADVPN_FREEBSD) - - check_symbol_exists(kqueue "sys/types.h;sys/event.h;sys/time.h" HAVE_KQUEUE) - if (NOT HAVE_KQUEUE) - message(FATAL_ERROR "kqueue is required") - endif () - add_definitions(-DBADVPN_USE_KEVENT) - endif () - - if (NOT DEFINED BADVPN_WITHOUT_CRYPTODEV) - check_include_files(crypto/cryptodev.h HAVE_CRYPTO_CRYPTODEV_H) - if (HAVE_CRYPTO_CRYPTODEV_H) - add_definitions(-DBADVPN_USE_CRYPTODEV) - elseif (DEFINED BADVPN_WITH_CRYPTODEV) - message(FATAL_ERROR "crypto/cryptodev.h not found") - endif () - endif () -endif () - -# check for syslog -check_include_files(syslog.h HAVE_SYSLOG_H) -if (HAVE_SYSLOG_H) - add_definitions(-DBADVPN_USE_SYSLOG) -endif () - -# add preprocessor definitions -if (BIG_ENDIAN) - add_definitions(-DBADVPN_BIG_ENDIAN) -else () - add_definitions(-DBADVPN_LITTLE_ENDIAN) -endif () - -# install man pages -install( - FILES badvpn.7 - DESTINATION share/man/man7 -) - -# reset variables indicating whether we're building various libraries, -# and set them in the respective CMakeLists files. This is used to disable -# building examples and tests which require libraries that are not available. -set(BUILDING_SECURITY 0) -set(BUILDING_DHCPCLIENT 0) -set(BUILDING_ARPPROBE 0) -set(BUILDING_BKIO 0) -set(BUILDING_PREDICATE 0) -set(BUILDING_UDEVMONITOR 0) -set(BUILDING_THREADWORK 0) -set(BUILDING_RANDOM 0) - -# Used to register an internal library. -# This will also add a library with the -plugin suffix, which is useful -# for use by dynamic libraries (e.g. NCD modules): -# - If BUILD_SHARED_LIBS is off (default), the libraries ${LIB_NAME} and ${LIB_NAME}-plugin -# are built separately. Both are static libraries but the -plugin variant is build as position -# independent code, so it can be (statically) linked into dynamic libraries. -# - If BUILD_SHARED_LIBS is on, only ${LIB_NAME} is built, as a shared library. -# The ${LIB_NAME}-plugin target is set up as an alias to ${LIB_NAME}. -function(badvpn_add_library LIB_NAME LINK_BADVPN_LIBS LINK_SYS_LIBS LIB_SOURCES) - set(BADVPN_LIBS_EXEC) - set(BADVPN_LIBS_PLUGIN) - foreach(LIB ${LINK_BADVPN_LIBS}) - list(APPEND BADVPN_LIBS_EXEC "${LIB}") - list(APPEND BADVPN_LIBS_PLUGIN "${LIB}-plugin") - endforeach() - - add_library("${LIB_NAME}" ${LIB_SOURCES}) - target_link_libraries("${LIB_NAME}" ${BADVPN_LIBS_EXEC} ${LINK_SYS_LIBS}) - set_target_properties("${LIB_NAME}" PROPERTIES OUTPUT_NAME "badvpn-${LIB_NAME}") - - if (BUILD_SHARED_LIBS) - add_library("${LIB_NAME}-plugin" ALIAS "${LIB_NAME}") - else () - add_library("${LIB_NAME}-plugin" STATIC ${LIB_SOURCES}) - target_link_libraries("${LIB_NAME}-plugin" ${BADVPN_LIBS_PLUGIN} ${LINK_SYS_LIBS}) - set_target_properties("${LIB_NAME}-plugin" PROPERTIES OUTPUT_NAME "badvpn-${LIB_NAME}-plugin") - set_target_properties("${LIB_NAME}-plugin" PROPERTIES POSITION_INDEPENDENT_CODE YES) - set_target_properties("${LIB_NAME}-plugin" PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -DBADVPN_PLUGIN") - endif() -endfunction() - -# internal libraries -add_subdirectory(base) -add_subdirectory(system) -add_subdirectory(flow) -add_subdirectory(flowextra) -if (OpenSSL_FOUND) - set(BUILDING_SECURITY 1) - add_subdirectory(security) -endif () -if (NSS_FOUND) - add_subdirectory(nspr_support) -endif () -if (BUILD_CLIENT OR BUILDING_SECURITY) - set(BUILDING_THREADWORK 1) - add_subdirectory(threadwork) -endif () -if (BUILD_CLIENT OR BUILD_TUN2SOCKS) - add_subdirectory(tuntap) -endif () -if (BUILD_SERVER) - set(BUILDING_PREDICATE 1) - add_subdirectory(predicate) -endif () -if (BUILD_CLIENT OR BUILD_FLOODER) - add_subdirectory(server_connection) -endif () -if (BUILD_NCD AND NOT EMSCRIPTEN) - set(BUILDING_DHCPCLIENT 1) - set(BUILDING_ARPPROBE 1) - set(BUILDING_UDEVMONITOR 1) - set(BUILDING_RANDOM 1) - add_subdirectory(stringmap) - add_subdirectory(udevmonitor) - add_subdirectory(dhcpclient) - add_subdirectory(arpprobe) - add_subdirectory(random) -endif () -if (BUILD_TUN2SOCKS) - add_subdirectory(socksclient) - add_subdirectory(udpgw_client) - add_subdirectory(lwip) -endif () -if (BUILD_TUNCTL) - add_subdirectory(tunctl) -endif () - -# example programs -if (BUILD_EXAMPLES) - add_subdirectory(examples) -endif () - -# tests -if (BUILD_TESTS) - add_subdirectory(tests) -endif () - -# server -if (BUILD_SERVER) - add_subdirectory(server) -endif () - -# client -if (BUILD_CLIENT) - add_subdirectory(client) -endif () - -# flooder -if (BUILD_FLOODER) - add_subdirectory(flooder) -endif () - -# tun2socks -if (BUILD_TUN2SOCKS) - add_subdirectory(tun2socks) -endif () - -# udpgw -if (BUILD_UDPGW) - add_subdirectory(udpgw) -endif () - -# ncd -if (BUILD_NCD) - add_subdirectory(ncd) - if (NOT EMSCRIPTEN) - add_subdirectory(ncd-request) - endif () -endif () - -# dostest -if (BUILD_DOSTEST) - add_subdirectory(dostest) -endif () - -message(STATUS "Building components:") - -# print what we're building and what not -foreach (name ${BUILD_COMPONENTS}) - # to lower name - string(TOLOWER "${name}" name_withspaces) - - # append spaces to name - #while (TRUE) - # string(LENGTH "${name_withspaces}" length) - # if (NOT (length LESS 12)) - # break() - # endif () - # set(name_withspaces "${name_withspaces} ") - #endwhile () - - # determine if we're building - if (BUILD_${name}) - set(building "yes") - else () - set(building "no") - endif () - - message(STATUS " ${name_withspaces} ${building}") -endforeach () diff --git a/external/badvpn_dns/COPYING b/external/badvpn_dns/COPYING deleted file mode 100644 index f973347..0000000 --- a/external/badvpn_dns/COPYING +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2009, Ambroz Bizjak ambrop7@gmail.com -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/badvpn_dns/ChangeLog b/external/badvpn_dns/ChangeLog deleted file mode 100644 index 4c4b96b..0000000 --- a/external/badvpn_dns/ChangeLog +++ /dev/null @@ -1,216 +0,0 @@ -Version 1.999.129: - -- ncd: modules: file_open: Fix typo in assertion. - -- server: Fix bug forgetting to call BSSLConnection_ReleaseBuffers(). Unless threads are enabled, this is an assert failure if NDEBUG is not defined an a non-issue otherwise. - -- ncd: Look for various programs in PATH instead of hardcoded paths. - -- Add compile-udpgw.sh. - -- ncd: modules: net_dns: Implement net.dns.resolvconf() forspecification of arbitrary resolv.conf lines - -Version 1.999.128: - -- tun2socks: add option --append-source-to-username to give the SOCKS server the source IP of the connection - -- tun2socks: IPv6 support, and updated to newer version of lwIP - -- tun2socks: fix some bugs/crashes - -- tun2socks, udpgw: transparent DNS forwarding, though no Windows support on udpgw side (contributed by Kerem Hadimli) - -- NCD: preliminary support for dynamically loading commands - -Version 1.999.127: - -- client, server: implement experimental support for performing SSL operations in worker threads. Currently it's rather inefficient. - -- NCD: modules: value: implement value::append() for appending to a list - -- NCD: modules: net_iptables: add single-argument form of append and insert commands, allowing for generic use - -- NCD: modules: net_iptables: implement net.iptables.insert() and net.ebtables.insert() - -- NCD: modules: sys_start_process: implement options, including username, term_on_deinit and deinit_kill_time - -- NCD: modules: sys_request_server: implement _caller in request handler - -- NCD: modules: add getenv() - -- NCD: modules: daemon: implement options, including username option - -- NCD: modules: runonce: add new options format with a map, implement username option - -- NCD: modules: add buffer(), which exposes a buffer with efficient appending and removing from the beginning. - -- NCD: add a new internal string representation called ComposedString. This allows modules to expose the concatenation of multiple memroy buffers as a single string value, efficiently. - -- fix many, hopefully all, strict aliasing violations. In particular, this fixes a bug where the DHCP client integrated into NCD won't work correctly, subject to optimization flags. - -- NCD: modules: sleep: interpret empty string as no sleeping, add sleep(ms_start) with one argument - -- NCD: modules: add log(), log_r() and log_fr() commands for logging via the BLog system - -Version 1.999.126: - -- NCD: modules: sleep: interpret empty string time as no sleeping, add sleep(ms_start) with one argument - -- NCD: modules: add log module for message logging using the BLog system - -- NCD: implement the "include" and "include_guard" directives, which allow separating reusable code into files - -- NCD: modules: call2: implement call_with_caller_target(), which makes it easier to write reusable code that calls back user-provided code - -- NCD: modules: call2: remove call2_if(), call2_ifelse(), embcall2(), embcall2_if(), embcall2_ifelse() - -- NCD: modules: add sys.start_process(), which implements starting and controlling external processes and reading/writing their stdout/stdin - -- tun2socks: implement SOCKS password authentication - -- NCD: track the depth of values and limit the maximum depth. This avoids stack overflow with very deeply nested values. - -- NCD: modules: add substr() - -- NCD: process_manager: add 2-argument start() method which doesn't take a process identifier - -- NCD: process_manager: allow process identifiers to be any value not just strings - -- NCD: multidepend, depend_scope: fix immediate effect order when a depend finishes backtracking - -- NCD: add depend_scope module to do exactly what the multidepend module does, but with separate non-global dependency name scopes - -- NCD: multidepend: allow dependency names to be any value not just strings - -- NCD: implement value::insert(what) for appending to a list - -- NCD: change the format of addresses in sys.request_server() and sys.request_client() to be the same as in the socket module - -- NCD: add socket module (sys.connect() and sys.listen()) - -- NCD: fix bug where duplicate template/process names would not be detected and weird behaviour would result - -- NCD: add backtrack_point() for simple backtracking - -- NCD: add file_open() for more complete file I/O - -- NCD: implement parse_ipv6_addr() and parse_ipv6_cidr_addr() - -- NCD: port to Emscripten/Javascript, for the in-browser demo - -- NCD: many performance and memory usage improvements - -- NCD: add assert_false() - -- NCD: don't link to OpenSSL to for random number generator. Use /dev/urandom instead to generate XIDs for DHCP. - -- NCD: deprecate ip_in_network() and instead add net.ipv{4,6}.addr_in_network(), net.ipv{4,6}.ifnot_addr_in_network() - -- NCD: implement some IPv6 modules: net.ipv6.addr(), net.ipv6.route() - -- NCD: support CIDR style addr/prefix addresses in various modules - -- NCD: recognize Elif and Else with capital first letter to be consistent with other reserved keywords - -Version 1.999.123: - -- NCD: performance improvements related to finding modules for statements - -- NCD: performance improvements related to resolving object names - -- NCD: performance improvements related to instantiating statement arguments - -- NCD: add value::replace_this() and value::replace_this_undo() - -- NCD: add value::reset() - -- NCD: add value::replace() and value::replace_undo() - -- Port to compile with MSVC for Windows. - -- NCD: add Foreach clause - -- NCD: implement _caller in spawn(), add spawn::join() - -- NCD: add explode() - -- NCD: add hard_reboot() and hard_poweroff() - -- NCD: add file_stat() and file_lstat() - -- NCD: fix regex_replace() semantics. It was very broken because it did a complete replacement pass for every regex on the list, so it would match parts that have already been replaced, producing unexpected results. - -- NCD: small performance improvement - -Version 1.999.121: - -- NCD: improve error handling semantics; see http://code.google.com/p/badvpn/source/detail?r=1376 - -- NCD: fix assertion failure in sys.evdev() if a device error occurs (e.g. device unplugged) while an event is being processed. Similar fix in some other modules, but these may not be reproducable. - -- NCD: some more performance improvements - -- NCD: some performance improvements (~30% faster interpretation of cpu-bound code) - -- NCD: implemented If..elif..else clause. - -- NCD: net.backend.wpa_supplicant: fix to work with wpa_supplicant>=1.0 - -Version 1.999.115: - -- NCD: Many improvements; new statements, including call(), alias(), foreach(), choose(). - -Version 1.999.113: - -- NCD: when starting child processes, make sure that file descriptors for standard - streams are always open in the child, by opening /dev/null if they are not. - -- Improve build system to allow selective building of components. - By default, everything is built, unless -DBUILD_NOTHING_BY_DEFAULT=1 is given. - Individual components can then be enabled or disabled using -DBUILD_COMPONENT=1 - and -DBUILD_COMPONENT=0. - -- When starting any BadVPN program, make sure that file descriptors for standard - streams are always open in the child, by opening /dev/null if they are not. - -- NCD: net.backend.wpa_supplicant(): add 'bssid' and 'ssid' variables to allow - determining what wireless network wpa_supplicant connected to. - -- NCD: net.backend.wpa_supplicant(): do not require the user to start wpa_supplicant via - stdbuf, but do it automatically. - -Version 1.999.111: - -- Improved protocol such that peers can use SSL when comminicating via the server. This - improves security, as compromising the server will not allow the attacker to see secret - data shared by peers (in particular, encryption keys and OTP seeds when in UDP mode). - - Compatibility is preserved if an only if the following conditions are met: - - The server is using the latest version. - - If the network is using SSL, all clients using the new version are using the - "--allow-peer-talk-without-ssl" command line option. - - Be aware, however, that using the "--allow-peer-talk-without-ssl" option negates the - security benefits of the new SSL support - not only between pairs of peers where one - peer is using the old version, but also between pairs where both peers are capable - of SSL. This is because the server can re-initialize the pair, telling them not to use - SSL. - -Version 1.999.107: - -- Added Windows IOCP support, removing the limitation on ~64 connections. This is important - for tun2socks, which may have to handle several hundred connections. - -Version 1.999.105.2: - -- Fixed an assertion failure in tun2socks related to sending data to SOCKS. - -Version 1.999.101.3: - -- Fixed UDP transport on Windows 7 which didn't work (was only tested on XP). - -Version 1.999.101: - -- Fixed a protocol issue present in versions <=1.999.100.3. Compatibility is preserved in - case of a new server and old clients, but it is not possible to connect to an old server - with a new client. diff --git a/external/badvpn_dns/INSTALL b/external/badvpn_dns/INSTALL deleted file mode 100644 index 3605f4e..0000000 --- a/external/badvpn_dns/INSTALL +++ /dev/null @@ -1,76 +0,0 @@ -1 Requirements - -1.1 Operating system - -Linux: -- Linux kernel 2.6. Kernel 2.4 will work, but performance will suffer. -- tested on x86, x86_64 and ARM architectures. Not tested on any big-endian architecture. - -Windows: -- Windows XP or newer; tested on Windows XP and Windows 7 - -FreeBSD: -- Not regularly tested. - -Other systems are not supported. - -1.2 Compilers - -Linux: - - gcc - - clang, except >=3.0 (clang bug http://llvm.org/bugs/show_bug.cgi?id=11535) - -Windows: - - gcc from the mingw-w64 project for 32-bit targets - -C language features used: - - Standard (all part of C99): - - designated initializers - - stdint.h, inttypes.h, stddef.h - - intermingled declarations and code - - for loop initial declaration - - one-line "//" comments - - Extensions: - - packed structure attribute (to pack a structure and allow unaligned access) - -1.3 CMake - -The build system uses CMake. - -1.4 OpenSSL - -Libcrypto (part of OpenSSL) is used for block ciphers, hash functions and random data generation. - -1.5 Network Security Services (NSS) - -The NSS library from Mozilla is used for TLS support. NSS command-line tools are also needed -for setting up certificates. - -1.6 TAP-Win32 (Windows only) (runtime only) - -The TAP-Win32 driver, part of OpenVPN. - -2 Compilation - -2.1 Compiling on Linux - -$ tar xf badvpn-<version>.tar.bz2 -$ mkdir build -$ cd build -$ cmake ../badvpn-<version> -DCMAKE_INSTALL_PREFIX=/usr/local -$ make -If you want to install it, run as root: -# make install - -If you only want NCD or tun2socks and not the VPN system, you can avoid the NSS dependency by passing -the following to the cmake command: --DBUILD_NCD=1 -DBUILD_TUN2SOCKS=1 -DBUILD_NOTHING_BY_DEFAULT=1 - -2.2 Compiling for Windows - -See the file INSTALL-WINDOWS for detailed instructions. - -3 Usage - -The primary documentation is on the BadVPN homepage, http://code.google.com/p/badvpn/ . -Additionally, some man pages are installed (badvpn(7), badvpn-server(8), badvpn-client(8)). diff --git a/external/badvpn_dns/INSTALL-WINDOWS b/external/badvpn_dns/INSTALL-WINDOWS deleted file mode 100644 index 9f0d5cf..0000000 --- a/external/badvpn_dns/INSTALL-WINDOWS +++ /dev/null @@ -1,72 +0,0 @@ -There are many ways to build BadVPN for Windows. It can be built with MSVC or GCC compilers, -and it be built natively from Windows or cross-compiled from Linux. However, this document -only describes building natively from Windows using MSVC. - -1. Get a MSVC compiler, e.g. from Visual Studio, Visual Studio Express or from the Windows SDK. - -2. Choose a directory where built stuff will be installed into; we call it <root>. - -3. Build the NSS library. - NOTE: you can also use the prebuilt version in the BadVPN windows download. - - - Install MozillaBuild: - http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildS... . - - - Download the NSS source code that includes NSPR. As of the time of writing the latest version was 3.13.5: - https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_13_5_RTM... . - - Extract it to c:\ so that you have C:\mozilla . - - - Open a terminal with access to the Visual Studio compilers and other tools. E.g. if you use the Windows SDK, - activate the following start menu item: Programs -> Microsoft Windows SDK v7.1 -> Windows SDK 7.1 Command Prompt. - - - In this terminal, run: - - > c:\mozilla-build\start-l10n.bat - - - Either a new terminal opens with a bash shell, or a bash shell starts in the existing terminal. Either way, - enter the following commands to finally build NSS: (here paths are written as /driveletter/...) - - $ export OS_TARGET=WINNT - $ export BUILD_OPT=1 - $ cd <nss_source_dir>/mozilla/security/nss - $ make nss_build_all - - Now use a script shipped with the BadVPN source to copy the resulting files into appropriate directories within <root>: - - $ <badvpn_source_dir>/scripts/copy_nss ../../dist <root> - -4. Build the OpenSSL library. - NOTE: you can also use the prebuilt version in the BadVPN windows download. - - - Install ActivePerl. - - - Download the OpenSSL source code and extract it. - - - Open a compiler terminal, as was done when building NSS. Inside it, run: - - > cd <openssl_source_dir> - > perl Configure VC-WIN32 --prefix=<root> - > ms\do_ms - > nmake -f ms\ntdll.mak - - To copy the results into <root>: - - > nmake -f ms\ntdll.mak install - -5. Build BadVPN. - - - Install CMake. During installation, select the option to include cmake in PATH - to avoid having to type a long path into the terminal. - - - Create an empty folder where BadVPN will be built; call it <build>. - - - Open a compiler terminal. Inside it, run: - - > cd <build> - > cmake <badvpn_source_dir> -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=<root> -DCMAKE_BUILD_TYPE=Release - > nmake - - To copy the results into <root>: - - > nmake install diff --git a/external/badvpn_dns/arpprobe/BArpProbe.c b/external/badvpn_dns/arpprobe/BArpProbe.c deleted file mode 100644 index 2e6feb4..0000000 --- a/external/badvpn_dns/arpprobe/BArpProbe.c +++ /dev/null @@ -1,359 +0,0 @@ -/** - * @file BArpProbe.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <sys/ioctl.h> -#include <linux/filter.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/ethernet_proto.h> -#include <misc/ipv4_proto.h> -#include <misc/udp_proto.h> -#include <misc/get_iface_info.h> -#include <base/BLog.h> - -#include "BArpProbe.h" - -#include <generated/blog_channel_BArpProbe.h> - -#define STATE_INITIAL 1 -#define STATE_NOEXIST 2 -#define STATE_EXIST 3 -#define STATE_EXIST_PANIC 4 - -static void dgram_handler (BArpProbe *o, int event) -{ - DebugObject_Access(&o->d_obj); - - BLog(BLOG_ERROR, "packet socket error"); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BARPPROBE_EVENT_ERROR)); - return; -} - -static void send_request (BArpProbe *o) -{ - if (o->send_sending) { - BLog(BLOG_ERROR, "cannot send packet while another packet is being sent!"); - return; - } - - // build packet - struct arp_packet *arp = &o->send_packet; - arp->hardware_type = hton16(ARP_HARDWARE_TYPE_ETHERNET); - arp->protocol_type = hton16(ETHERTYPE_IPV4); - arp->hardware_size = hton8(6); - arp->protocol_size = hton8(4); - arp->opcode = hton16(ARP_OPCODE_REQUEST); - memcpy(arp->sender_mac, o->if_mac, 6); - arp->sender_ip = hton32(0); - memset(arp->target_mac, 0, sizeof(arp->target_mac)); - arp->target_ip = o->addr; - - // send packet - PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)&o->send_packet, sizeof(o->send_packet)); - - // set sending - o->send_sending = 1; -} - -static void send_if_handler_done (BArpProbe *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send_sending) - - // set not sending - o->send_sending = 0; -} - -static void recv_if_handler_done (BArpProbe *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= 0) - ASSERT(data_len <= sizeof(struct arp_packet)) - - // receive next packet - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)&o->recv_packet); - - if (data_len != sizeof(struct arp_packet)) { - BLog(BLOG_WARNING, "receive: wrong size"); - return; - } - - struct arp_packet *arp = &o->recv_packet; - - if (ntoh16(arp->hardware_type) != ARP_HARDWARE_TYPE_ETHERNET) { - BLog(BLOG_WARNING, "receive: wrong hardware type"); - return; - } - - if (ntoh16(arp->protocol_type) != ETHERTYPE_IPV4) { - BLog(BLOG_WARNING, "receive: wrong protocol type"); - return; - } - - if (ntoh8(arp->hardware_size) != 6) { - BLog(BLOG_WARNING, "receive: wrong hardware size"); - return; - } - - if (ntoh8(arp->protocol_size) != 4) { - BLog(BLOG_WARNING, "receive: wrong protocol size"); - return; - } - - if (ntoh16(arp->opcode) != ARP_OPCODE_REPLY) { - return; - } - - if (arp->sender_ip != o->addr) { - return; - } - - int old_state = o->state; - - // set minus one missed - o->num_missed = -1; - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITSEND); - - // set state exist - o->state = STATE_EXIST; - - // report exist if needed - if (old_state == STATE_INITIAL || old_state == STATE_NOEXIST) { - o->handler(o->user, BARPPROBE_EVENT_EXIST); - return; - } -} - -static void timer_handler (BArpProbe *o) -{ - DebugObject_Access(&o->d_obj); - - // send request - send_request(o); - - switch (o->state) { - case STATE_INITIAL: { - ASSERT(o->num_missed >= 0) - ASSERT(o->num_missed < BARPPROBE_INITIAL_NUM_ATTEMPTS) - - // increment missed - o->num_missed++; - - // all attempts failed? - if (o->num_missed == BARPPROBE_INITIAL_NUM_ATTEMPTS) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - - // set state noexist - o->state = STATE_NOEXIST; - - // report noexist - o->handler(o->user, BARPPROBE_EVENT_NOEXIST); - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_INITIAL_WAITRECV); - } break; - - case STATE_NOEXIST: { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - } break; - - case STATE_EXIST: { - ASSERT(o->num_missed >= -1) - ASSERT(o->num_missed < BARPPROBE_EXIST_NUM_NOREPLY) - - // increment missed - o->num_missed++; - - // all missed? - if (o->num_missed == BARPPROBE_EXIST_NUM_NOREPLY) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV); - - // set zero missed - o->num_missed = 0; - - // set state panic - o->state = STATE_EXIST_PANIC; - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITRECV); - } break; - - case STATE_EXIST_PANIC: { - ASSERT(o->num_missed >= 0) - ASSERT(o->num_missed < BARPPROBE_EXIST_PANIC_NUM_NOREPLY) - - // increment missed - o->num_missed++; - - // all missed? - if (o->num_missed == BARPPROBE_EXIST_PANIC_NUM_NOREPLY) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - - // set state panic - o->state = STATE_NOEXIST; - - // report noexist - o->handler(o->user, BARPPROBE_EVENT_NOEXIST); - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV); - } break; - } -} - -int BArpProbe_Init (BArpProbe *o, const char *ifname, uint32_t addr, BReactor *reactor, void *user, BArpProbe_handler handler) -{ - ASSERT(ifname) - ASSERT(handler) - - // init arguments - o->addr = addr; - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // get interface information - int if_mtu; - int if_index; - if (!badvpn_get_iface_info(ifname, o->if_mac, &if_mtu, &if_index)) { - BLog(BLOG_ERROR, "failed to get interface information"); - goto fail0; - } - - uint8_t *if_mac = o->if_mac; - BLog(BLOG_INFO, "if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d", - if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index); - - // check MTU - if (if_mtu < sizeof(struct arp_packet)) { - BLog(BLOG_ERROR, "MTU is too small for ARP !?!"); - goto fail0; - } - - // init dgram - if (!BDatagram_Init(&o->dgram, BADDR_TYPE_PACKET, o->reactor, o, (BDatagram_handler)dgram_handler)) { - BLog(BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // bind dgram - BAddr bind_addr; - BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_ARP), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac); - if (!BDatagram_Bind(&o->dgram, bind_addr)) { - BLog(BLOG_ERROR, "BDatagram_Bind failed"); - goto fail1; - } - - // set dgram send addresses - BAddr dest_addr; - uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BAddr_InitPacket(&dest_addr, hton16(ETHERTYPE_ARP), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_BROADCAST, broadcast_mac); - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, dest_addr, local_addr); - - // init send interface - BDatagram_SendAsync_Init(&o->dgram, sizeof(struct arp_packet)); - o->send_if = BDatagram_SendAsync_GetIf(&o->dgram); - PacketPassInterface_Sender_Init(o->send_if, (PacketPassInterface_handler_done)send_if_handler_done, o); - - // set not sending - o->send_sending = 0; - - // init recv interface - BDatagram_RecvAsync_Init(&o->dgram, sizeof(struct arp_packet)); - o->recv_if = BDatagram_RecvAsync_GetIf(&o->dgram); - PacketRecvInterface_Receiver_Init(o->recv_if, (PacketRecvInterface_handler_done)recv_if_handler_done, o); - - // init timer - BTimer_Init(&o->timer, 0, (BTimer_handler)timer_handler, o); - - // receive first packet - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)&o->recv_packet); - - // send request - send_request(o); - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_INITIAL_WAITRECV); - - // set zero missed - o->num_missed = 0; - - // set state initial - o->state = STATE_INITIAL; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void BArpProbe_Free (BArpProbe *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free timer - BReactor_RemoveTimer(o->reactor, &o->timer); - - // free recv interface - BDatagram_RecvAsync_Free(&o->dgram); - - // free send interface - BDatagram_SendAsync_Free(&o->dgram); - - // free dgram - BDatagram_Free(&o->dgram); -} diff --git a/external/badvpn_dns/arpprobe/BArpProbe.h b/external/badvpn_dns/arpprobe/BArpProbe.h deleted file mode 100644 index 2ec3ffa..0000000 --- a/external/badvpn_dns/arpprobe/BArpProbe.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file BArpProbe.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BARPPROBE_H -#define BADVPN_BARPPROBE_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <misc/arp_proto.h> -#include <misc/ethernet_proto.h> -#include <base/DebugObject.h> -#include <system/BDatagram.h> -#include <system/BReactor.h> - -#define BARPPROBE_INITIAL_WAITRECV 1000 -#define BARPPROBE_INITIAL_NUM_ATTEMPTS 6 -#define BARPPROBE_NOEXIST_WAITRECV 15000 -#define BARPPROBE_EXIST_WAITSEND 15000 -#define BARPPROBE_EXIST_WAITRECV 10000 -#define BARPPROBE_EXIST_NUM_NOREPLY 2 -#define BARPPROBE_EXIST_PANIC_WAITRECV 1000 -#define BARPPROBE_EXIST_PANIC_NUM_NOREPLY 6 - -#define BARPPROBE_EVENT_EXIST 1 -#define BARPPROBE_EVENT_NOEXIST 2 -#define BARPPROBE_EVENT_ERROR 3 - -typedef void (*BArpProbe_handler) (void *user, int event); - -typedef struct { - uint32_t addr; - BReactor *reactor; - void *user; - BArpProbe_handler handler; - BDatagram dgram; - uint8_t if_mac[6]; - PacketPassInterface *send_if; - int send_sending; - struct arp_packet send_packet; - PacketRecvInterface *recv_if; - struct arp_packet recv_packet; - BTimer timer; - int state; - int num_missed; - DebugError d_err; - DebugObject d_obj; -} BArpProbe; - -int BArpProbe_Init (BArpProbe *o, const char *ifname, uint32_t addr, BReactor *reactor, void *user, BArpProbe_handler handler) WARN_UNUSED; -void BArpProbe_Free (BArpProbe *o); - -#endif diff --git a/external/badvpn_dns/arpprobe/CMakeLists.txt b/external/badvpn_dns/arpprobe/CMakeLists.txt deleted file mode 100644 index a090f10..0000000 --- a/external/badvpn_dns/arpprobe/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(arpprobe "base;system;flow" "" BArpProbe.c) diff --git a/external/badvpn_dns/badvpn.7 b/external/badvpn_dns/badvpn.7 deleted file mode 100644 index c421a35..0000000 --- a/external/badvpn_dns/badvpn.7 +++ /dev/null @@ -1,324 +0,0 @@ -.TH badvpn 7 "6 October 2010" -.SH NAME -BadVPN - peer-to-peer VPN system -.SH DESCRIPTION -.P -BadVPN is a peer-to-peer VPN system. It provides a Layer 2 (Ethernet) network between -the peers (VPN network nodes). The peers connect to a central server which acts as a chat -server for them to establish direct connections between each other (data connections). -These connections are used for transferring network data (Ethernet frames). -.SS "Features" -.P -.B "Data connections" -.P -Peers can transfer network data either over UDP or TCP. For both there are ways of -securing the data (see below). -.P -.B "IPv6 support" -.P -IPv6 can be used for both server connections and data connections, alongside with IPv4. -Additionally, both can be combined to allow gradual migration to IPv6. -.P -.B "Address selection" -.P -Because NATs and firewalls are widespread, it is harder for peer-to-peer services to operate. -In general, for two computers to be able to communicate, one computer must -.I bind -to one of its addresses, and the other computer must -.I connect -to the computer that binded (both for TCP and UDP). In a network with point-to-point -connectivity, the connecting computer can connect to the same address as the binding computer -bound to, so it is sufficient for the binding computer to send its address to the connecting -computer. However, NATs and firewalls break point-to-point connectivity. When a network is -behind a NAT, it is, by default, impossible for computers outside of that network to connect -to computers inside the network. This is because computers inside the network have no externally -visible IP address, and only communicate with the outside world through the external IP address -of the NAT router. It is however possible to manually configure the NAT router to -.I forward -a specific port number on its external IP address to a specific computer inside the network. -This makes it possible for a computer outside of the network to connect to a computer inside -a network, however, it must connect to the external address of the NAT router (rather than -the address the computer inside bound to, which is its internal address). So there needs -to be some way for the connecting peer to know what address to connect to. -.P -BadVPN solves this problem with so-called -.IR "address scopes" "." -The peer that binds must have a list of external addresses for each address it can bind to, -possibly ordered from best to worst. Each external address has its scope name. A scope name -represents part of a network from which an external address can be reached. On the other hand, -the peer that connects must have a list of scopes which it can reach. When a peer binds to an -address, it sends the other peer a list of external addresses along with scope names. That peer -than chooses the first external address whose scope it recognizes and attempts to connect to it -(if there is one). -.P -BadVPN also allows a peer to have multiple addresses for binding to. It is possible to specify -both an IPv4 and an IPv6 address to work in a multi-protocol environment. -.P -.B "Relaying" -.P -BadVPN can be configured to allow pairs of peers that cannot communicate directly (i.e. because of -NATs or firewalls) to relay network data through a third peer. Relaying is only attempted if -none of the two peers recognize any of the other peer's external addresses (or there are none). -For relaying to work, for each of the two peers (P1, other one P2) there must be at least one -third peer (R) that P1 it is allowed to relay through and can communicate directly with, and all -such peers R must be able to communicate directly with P2. -.P -.B "IGMP snooping" -.P -BadVPN nodes perform IGMP snooping in order to efficiently deliver multicast frames. For example, -this makes it possible to use BadVPN as a tunnel into an IPTV network of an Internet Service Provider -for you to watch TV from wherever you want (given sufficient link quality). -.P -.B "Code quality" -.P -BadVPN has great focus on code quality and reliability. BadVPN is written in the C programming -language. It is a single-threaded event-driven program. This allows for low resource usage and -fast response times. Even though C is a relatively low-level language, the programs are made of -small, highly cohesive and loosely coupled modules that are combined into a complete program on -a high level. Modules are accesed and communicate through small, simple and to-the-point interfaces. -It utilizes a flow-based design which greatly simplifies processing of data and input and output -of the programs. -.SS "Security features" -.P -BadVPN contains many security features, all of which are optional. The included security -features are described here. -.P -.B TLS for client-server connections -.P -It is possible for the peers to communicate with the chat server securely with TLS. It is -highly recommended that this feature is used if any security whatsoever is needed. Not -using it renders all other security features useless, since clients exchange keys -unencrypted via the server. When enabled, the chat server requires each client to identify -itself with a certificate. -.P -BadVPN uses Mozilla's NSS library for TLS support. This means that the required certificates -and keys must be available in a NSS database. The database and certificates can be -generated with the -.B certutil -command. See the examples section on how to generate and distribute the certificates. -.P -.B TLS for peer messaging -.P -If TLS is being used for client-server connections, it will also be used between each pair of -peers communicating via the server, on top of the TLS connections to the server. This secures -the messages from the server itself. It is important because the messages may include -encryption keys and other private data. -.P -.B TLS for TCP data connections -.P -If TCP is used for data connections between the peers, the data connections can be secured -with TLS. This requires using TLS for client-server connections. The clients need to trust -each others' certificates to be able to connect. Additionally, each client must identify to -its peers with the same certificates it used for connecting to the server. -.P -.B Encryption for UDP data connections -.P -If UDP is used for data connections, it is possible for each pair of peers to encrypt their -UDP packets with a symmetric block cipher. Note that the encryption keys are transmitted -through the server unencrypted, so for this to be useful, server connections must be secured -with TLS. The encryption aims to prevent third parties from seeing the real contents of -the network data being transfered. -.P -.B Hashes for UDP data connections -.P -If UDP is used for data connections, it is possible to include hashes in packets. Note that -hashes are only useful together with encryption. If enabled, the hash is calculated on the -packet with the hash field zeroed and then written to the hash field. Hashes are calculated -and included before encryption (if enabled). Combined with encryption, hashes aim to prevent -third parties from tampering with the packets and injecting them into the network. -.P -.B One-time passwords for UDP data connections -.P -If UDP is used for data connections, it is possible to include one-time passwords in packets. -Note that for this to be useful, server connections must be secured with TLS. -One-time passwords are generated from a seed value by encrypting zero data with a block cipher. -The seed contains the encryption key for the block cipher and the initialization vector. -Only a fixed number of passwords are used from a single seed. The peers exchange seeds through -the server. One-time passwords aim to prevent replay attacks. -.P -.B Control over peer communication -.P -It is possible to instruct the chat server to only allow certain peers to communicate. This -will break end-to-end connectivity in the virtual network. It is useful in certain cases -to improve security, for example when the VPN is used only to allow clients to securely connect -to a central service. -.SH "EXAMPLES" -.SS "Setting up certificates" -.P -If you want to use TLS for server connections (recommended), the server and all the peers will -need certificates. This section explains how to generate and distribute the certificates using -NSS command line tools. -.P -.B Setting up the Certificate Authority (CA) -.P -On the system that will host the CA, create a NSS database for the CA and generate a CA certificate -valid for 24 months: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -N -.br -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "vpnca" -s "CN=vpnca" -t "TC,," -x -2 -v 24 -.br -> Is this a CA certificate [y/N]? y -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -1 -.br -> Is this a critical extension [y/N]? n -.P -Export the public CA certificate (this file is public): -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -L -n vpnca -a > ca.pem -.P -.B Setting up the server certificate -.P -On the CA system, generate a certificate for the server valid for 24 months, with TLS server usage context: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "<insert_server_name>" -s "CN=<insert_server_name>" -c "vpnca" -t ",," -2 -6 -v 24 -.br -> 0 -.br -> -1 -.br -> Is this a critical extension [y/N]? n -.br -> Is this a CA certificate [y/N]? n -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -.br -> Is this a critical extension [y/N]? n -.P -Export the server certificate to a PKCS#12 file (this file must be kept secret): -.P -vpnca $ pk12util -d sql:/home/vpnca/nssdb -o server.p12 -n "<insert_server_name>" -.P -On the system that will run the server, create a NSS database and import the CA certificate -and the server cerificate: -.P -vpnserver $ certutil -d sql:/home/vpnserver/nssdb -N -.br -vpnserver $ certutil -d sql:/home/vpnserver/nssdb -A -t "CT,," -n "vpnca" -i /path/to/ca.pem -.br -vpnserver $ pk12util -d sql:/home/vpnserver/nssdb -i /path/to/server.p12 -.P -.B Setting up peer certificates -.P -On the CA system, generate a certificate for the peer valid for 24 months, with TLS client and -TLS server usage contexts: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "peer-<insert_name>" -s "CN=peer-<insert_name>" -c "vpnca" -t ",," -2 -6 -v 24 -.br -> 0 -.br -> 1 -.br -> -1 -.br -> Is this a critical extension [y/N]? n -.br -> Is this a CA certificate [y/N]? n -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -.br -> Is this a critical extension [y/N]? n -.P -Export the peer certificate to a PKCS#12 file (this file must be kept secret): -.P -vpnca $ pk12util -d sql:/home/vpnca/nssdb -o peer-<insert_name>.p12 -n "peer-<insert_name>" -.P -On the system that will run the VPN client, create a NSS database and import the CA certificate -and the peer cerificate: -.P -vpnclient $ certutil -d sql:/home/vpnclient/nssdb -N -.br -vpnclient $ certutil -d sql:/home/vpnclient/nssdb -A -t "CT,," -n "vpnca" -i /path/to/ca.pem -.br -vpnclient $ pk12util -d sql:/home/vpnclient/nssdb -i /path/to/peer-<insert_name>.p12 -.SS "Setting up TAP devices" -.P -You need to create and configure TAP devices on all computers that will participate in the virtual network -(i.e. run the client program). See -.BR badvpn-client (8), -section `TAP DEVICE CONFIGURATION` for details. -.SS "Example: Local IPv4 network, UDP transport, zero security" -.P -.B Starting the server: -.P -badvpn-server --listen-addr 0.0.0.0:7000 -.P -.B Starting the peers: -.P -badvpn-client -.RS ---server-addr <insert_server_local_address>:7000 -.br ---transport-mode udp --encryption-mode none --hash-mode none -.br ---scope local1 -.br ---bind-addr 0.0.0.0:8000 --num-ports 30 --ext-addr {server_reported}:8000 local1 -.br ---tapdev tap0 -.RE -.SS "Example: Adding TLS and UDP security" -.P -.B Starting the server (other options as above): -.P -badvpn-server ... -.RS ---ssl --nssdb sql:/home/vpnserver/nssdb --server-cert-name "<insert_server_name>" -.RE -.P -.B Starting the peers (other options as above): -.P -badvpn-client ... -.RS ---ssl --nssdb sql:/home/vpnclient/nssdb --client-cert-name "peer-<insert_name>" -.br ---encryption-mode blowfish --hash-mode md5 --otp blowfish 3000 2000 -.RE -.SS "Example: Multiple local networks behind NATs, all connected to the Internet" -.P -For each peer in the existing local network, configure the NAT router to forward its -range of ports to it (assuming their port ranges do not overlap). The clients also need -to know the external IP address of the NAT router. If you don't have a static one, -you'll need to discover it before starting the clients. Also forward the server port to -the server. -.P -.B Starting the peers in the local network (other options as above): -.P -badvpn-client -.RS -.RB "..." -.br ---scope internet -.br -.RB "..." -.br ---ext-addr <insert_NAT_routers_external_IP>:<insert_start_of_forwarded_port_range> internet -.br -.RB "..." -.RE -.P -The --ext-addr option applies to the previously specified --bind-addr option, and must come after -the first --ext-addr option which specifies a local address. -.P -Now perform a similar setup in some other local network behind a NAT. However: -.br -- Don't set up a new server, instead make the peers connect to the existing server in the first -local network. -.br -- You can't use {server_reported} for the local address --ext-addr options, because the server -would report the NAT router's external address rather than the peer's internal address. Instead -each peer has to know its internal IP address. -.br -- Use a different scope name for it, e.g. "local2" instead of "local1". -.P -If setup correctly, all peers will be able to communicate: those in the same local network will -communicate directly through local addresses, and those in different local networks will -communicate through the Internet. -.SH "PROTOCOL" -The protocols used in BadVPN are described in the source code in the protocol/ directory. -.SH "SEE ALSO" -.BR badvpn-server (8), -.BR badvpn-client (8) -.SH AUTHORS -Ambroz Bizjak ambrop7@gmail.com diff --git a/external/badvpn_dns/base/BLog.c b/external/badvpn_dns/base/BLog.c deleted file mode 100644 index 94242d5..0000000 --- a/external/badvpn_dns/base/BLog.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file BLog.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stddef.h> - -#include "BLog.h" - -#ifndef BADVPN_PLUGIN - -struct _BLog_channel blog_channel_list[] = { -#include <generated/blog_channels_list.h> -}; - -struct _BLog_global blog_global = { - #ifndef NDEBUG - 0 - #endif -}; - -#endif - -// keep in sync with level numbers in BLog.h! -static char *level_names[] = { NULL, "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG" }; - -static void stdout_log (int channel, int level, const char *msg) -{ - fprintf(stdout, "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -} - -static void stderr_log (int channel, int level, const char *msg) -{ - fprintf(stderr, "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -} - -static void stdout_stderr_free (void) -{ -} - -void BLog_InitStdout (void) -{ - BLog_Init(stdout_log, stdout_stderr_free); -} - -void BLog_InitStderr (void) -{ - BLog_Init(stderr_log, stdout_stderr_free); -} - -// ==== PSIPHON ==== -#ifdef PSIPHON - -void PsiphonLog(const char *level, const char *channel, const char *msg); - -static void psiphon_log (int channel, int level, const char *msg) -{ - PsiphonLog(level_names[level], blog_global.channels[channel].name, msg); -} - -static void psiphon_free (void) -{ -} - -void BLog_InitPsiphon (void) -{ - BLog_Init(psiphon_log, psiphon_free); -} - -#endif -// ==== PSIPHON ==== diff --git a/external/badvpn_dns/base/BLog.h b/external/badvpn_dns/base/BLog.h deleted file mode 100644 index dd2e4d0..0000000 --- a/external/badvpn_dns/base/BLog.h +++ /dev/null @@ -1,402 +0,0 @@ -/** - * @file BLog.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A global object for logging. - */ - -#ifndef BADVPN_BLOG_H -#define BADVPN_BLOG_H - -#include <stdarg.h> -#include <string.h> - -#include <misc/debug.h> -#include <base/BMutex.h> - -// auto-generated channel numbers and number of channels -#include <generated/blog_channels_defines.h> - -// keep in sync with level names in BLog.c! -#define BLOG_ERROR 1 -#define BLOG_WARNING 2 -#define BLOG_NOTICE 3 -#define BLOG_INFO 4 -#define BLOG_DEBUG 5 - -#define BLog(...) BLog_LogToChannel(BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define BContextLog(context, ...) BLog_ContextLog((context), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define BLOG_CCCC(context) BLog_MakeChannelContext((context), BLOG_CURRENT_CHANNEL) - -typedef void (*_BLog_log_func) (int channel, int level, const char *msg); -typedef void (*_BLog_free_func) (void); - -struct _BLog_channel { - const char *name; - int loglevel; -}; - -struct _BLog_global { - #ifndef NDEBUG - int initialized; // initialized statically - #endif - struct _BLog_channel channels[BLOG_NUM_CHANNELS]; - _BLog_log_func log_func; - _BLog_free_func free_func; - BMutex mutex; -#ifndef NDEBUG - int logging; -#endif - char logbuf[2048]; - int logbuf_pos; -}; - -extern struct _BLog_channel blog_channel_list[]; -extern struct _BLog_global blog_global; - -typedef void (*BLog_logfunc) (void *); - -typedef struct { - BLog_logfunc logfunc; - void *logfunc_user; -} BLogContext; - -typedef struct { - BLogContext context; - int channel; -} BLogChannelContext; - -static int BLogGlobal_GetChannelByName (const char *channel_name); - -static void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func); -static void BLog_Free (void); -static void BLog_SetChannelLoglevel (int channel, int loglevel); -static int BLog_WouldLog (int channel, int level); -static void BLog_Begin (void); -static void BLog_AppendVarArg (const char *fmt, va_list vl); -static void BLog_Append (const char *fmt, ...); -static void BLog_AppendBytes (const char *data, size_t len); -static void BLog_Finish (int channel, int level); -static void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl); -static void BLog_LogToChannel (int channel, int level, const char *fmt, ...); -static void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl); -static void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...); -static BLogContext BLog_RootContext (void); -static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user); -static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl); -static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...); -static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel); -static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl); -static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...); - -void BLog_InitStdout (void); -void BLog_InitStderr (void); - -// PSIPHON -void BLog_InitPsiphon (void); - -int BLogGlobal_GetChannelByName (const char *channel_name) -{ - int i; - for (i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (!strcmp(blog_channel_list[i].name, channel_name)) { - return i; - } - } - - return -1; -} - -void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func) -{ - ASSERT(!blog_global.initialized) - - #ifndef NDEBUG - blog_global.initialized = 1; - #endif - - // initialize channels - memcpy(blog_global.channels, blog_channel_list, BLOG_NUM_CHANNELS * sizeof(struct _BLog_channel)); - - blog_global.log_func = log_func; - blog_global.free_func = free_func; -#ifndef NDEBUG - blog_global.logging = 0; -#endif - blog_global.logbuf_pos = 0; - blog_global.logbuf[0] = '\0'; - - ASSERT_FORCE(BMutex_Init(&blog_global.mutex)) -} - -void BLog_Free (void) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(!blog_global.logging) -#endif - - BMutex_Free(&blog_global.mutex); - - #ifndef NDEBUG - blog_global.initialized = 0; - #endif - - blog_global.free_func(); -} - -void BLog_SetChannelLoglevel (int channel, int loglevel) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(loglevel >= 0 && loglevel <= BLOG_DEBUG) - - blog_global.channels[channel].loglevel = loglevel; -} - -int BLog_WouldLog (int channel, int level) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - return (level <= blog_global.channels[channel].loglevel); -} - -void BLog_Begin (void) -{ - ASSERT(blog_global.initialized) - - BMutex_Lock(&blog_global.mutex); - -#ifndef NDEBUG - ASSERT(!blog_global.logging) - blog_global.logging = 1; -#endif -} - -void BLog_AppendVarArg (const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - - int w = vsnprintf(blog_global.logbuf + blog_global.logbuf_pos, sizeof(blog_global.logbuf) - blog_global.logbuf_pos, fmt, vl); - - if (w >= sizeof(blog_global.logbuf) - blog_global.logbuf_pos) { - blog_global.logbuf_pos = sizeof(blog_global.logbuf) - 1; - } else { - blog_global.logbuf_pos += w; - } -} - -void BLog_Append (const char *fmt, ...) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - - va_list vl; - va_start(vl, fmt); - BLog_AppendVarArg(fmt, vl); - va_end(vl); -} - -void BLog_AppendBytes (const char *data, size_t len) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - - size_t avail = (sizeof(blog_global.logbuf) - 1) - blog_global.logbuf_pos; - len = (len > avail ? avail : len); - - memcpy(blog_global.logbuf + blog_global.logbuf_pos, data, len); - blog_global.logbuf_pos += len; - blog_global.logbuf[blog_global.logbuf_pos] = '\0'; -} - -void BLog_Finish (int channel, int level) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - ASSERT(BLog_WouldLog(channel, level)) - - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - ASSERT(blog_global.logbuf[blog_global.logbuf_pos] == '\0') - - blog_global.log_func(channel, level, blog_global.logbuf); - -#ifndef NDEBUG - blog_global.logging = 0; -#endif - blog_global.logbuf_pos = 0; - blog_global.logbuf[0] = '\0'; - - BMutex_Unlock(&blog_global.mutex); -} - -void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - BLog_Begin(); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); -} - -void BLog_LogToChannel (int channel, int level, const char *fmt, ...) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - va_list vl; - va_start(vl, fmt); - - BLog_Begin(); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); - - va_end(vl); -} - -void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - BLog_Begin(); - func(arg); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); -} - -void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - va_list vl; - va_start(vl, fmt); - - BLog_Begin(); - func(arg); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); - - va_end(vl); -} - -static void BLog__root_logfunc (void *unused) -{ -} - -static BLogContext BLog_RootContext (void) -{ - return BLog_MakeContext(BLog__root_logfunc, NULL); -} - -static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user) -{ - ASSERT(logfunc) - - BLogContext context; - context.logfunc = logfunc; - context.logfunc_user = logfunc_user; - return context; -} - -static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl) -{ - BLog_LogViaFuncVarArg(context.logfunc, context.logfunc_user, channel, level, fmt, vl); -} - -static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_ContextLogVarArg(context, channel, level, fmt, vl); - va_end(vl); -} - -static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel) -{ - BLogChannelContext ccontext; - ccontext.context = context; - ccontext.channel = channel; - return ccontext; -} - -static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl) -{ - BLog_ContextLogVarArg(ccontext.context, ccontext.channel, level, fmt, vl); -} - -static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_ChannelContextLogVarArg(ccontext, level, fmt, vl); - va_end(vl); -} - -#endif diff --git a/external/badvpn_dns/base/BLog_syslog.c b/external/badvpn_dns/base/BLog_syslog.c deleted file mode 100644 index d7a954b..0000000 --- a/external/badvpn_dns/base/BLog_syslog.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file BLog_syslog.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdio.h> -#include <syslog.h> - -#include <misc/debug.h> - -#include "BLog_syslog.h" - -static int resolve_facility (char *str, int *out) -{ - if (!strcmp(str, "authpriv")) { - *out = LOG_AUTHPRIV; - } - else if (!strcmp(str, "cron")) { - *out = LOG_CRON; - } - else if (!strcmp(str, "daemon")) { - *out = LOG_DAEMON; - } - else if (!strcmp(str, "ftp")) { - *out = LOG_FTP; - } - else if (!strcmp(str, "local0")) { - *out = LOG_LOCAL0; - } - else if (!strcmp(str, "local1")) { - *out = LOG_LOCAL1; - } - else if (!strcmp(str, "local2")) { - *out = LOG_LOCAL2; - } - else if (!strcmp(str, "local3")) { - *out = LOG_LOCAL3; - } - else if (!strcmp(str, "local4")) { - *out = LOG_LOCAL4; - } - else if (!strcmp(str, "local5")) { - *out = LOG_LOCAL5; - } - else if (!strcmp(str, "local6")) { - *out = LOG_LOCAL6; - } - else if (!strcmp(str, "local7")) { - *out = LOG_LOCAL7; - } - else if (!strcmp(str, "lpr")) { - *out = LOG_LPR; - } - else if (!strcmp(str, "mail")) { - *out = LOG_MAIL; - } - else if (!strcmp(str, "news")) { - *out = LOG_NEWS; - } - else if (!strcmp(str, "syslog")) { - *out = LOG_SYSLOG; - } - else if (!strcmp(str, "user")) { - *out = LOG_USER; - } - else if (!strcmp(str, "uucp")) { - *out = LOG_UUCP; - } - else { - return 0; - } - - return 1; -} - -static int convert_level (int level) -{ - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - switch (level) { - case BLOG_ERROR: - return LOG_ERR; - case BLOG_WARNING: - return LOG_WARNING; - case BLOG_NOTICE: - return LOG_NOTICE; - case BLOG_INFO: - return LOG_INFO; - case BLOG_DEBUG: - return LOG_DEBUG; - default: - ASSERT(0) - return 0; - } -} - -static struct { - char ident[200]; -} syslog_global; - -static void syslog_log (int channel, int level, const char *msg) -{ - syslog(convert_level(level), "%s: %s", blog_global.channels[channel].name, msg); -} - -static void syslog_free (void) -{ - closelog(); -} - -int BLog_InitSyslog (char *ident, char *facility_str) -{ - int facility; - if (!resolve_facility(facility_str, &facility)) { - return 0; - } - - snprintf(syslog_global.ident, sizeof(syslog_global.ident), "%s", ident); - - openlog(syslog_global.ident, 0, facility); - - BLog_Init(syslog_log, syslog_free); - - return 1; -} diff --git a/external/badvpn_dns/base/BLog_syslog.h b/external/badvpn_dns/base/BLog_syslog.h deleted file mode 100644 index 1adf04e..0000000 --- a/external/badvpn_dns/base/BLog_syslog.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file BLog_syslog.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * BLog syslog backend. - */ - -#ifndef BADVPN_BLOG_SYSLOG_H -#define BADVPN_BLOG_SYSLOG_H - -#include <misc/debug.h> -#include <base/BLog.h> - -int BLog_InitSyslog (char *ident, char *facility) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/base/BMutex.h b/external/badvpn_dns/base/BMutex.h deleted file mode 100644 index fbcbd05..0000000 --- a/external/badvpn_dns/base/BMutex.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file BMutex.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BMUTEX_H -#define BADVPN_BMUTEX_H - -#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1) -#error BADVPN_THREAD_SAFE is not defined or incorrect -#endif - -#if BADVPN_THREAD_SAFE -#include <pthread.h> -#endif - -#include <misc/debug.h> -#include <base/DebugObject.h> - -typedef struct { -#if BADVPN_THREAD_SAFE - pthread_mutex_t pthread_mutex; -#endif - DebugObject d_obj; -} BMutex; - -static int BMutex_Init (BMutex *o) WARN_UNUSED; -static void BMutex_Free (BMutex *o); -static void BMutex_Lock (BMutex *o); -static void BMutex_Unlock (BMutex *o); - -static int BMutex_Init (BMutex *o) -{ -#if BADVPN_THREAD_SAFE - if (pthread_mutex_init(&o->pthread_mutex, NULL) != 0) { - return 0; - } -#endif - - DebugObject_Init(&o->d_obj); - return 1; -} - -static void BMutex_Free (BMutex *o) -{ - DebugObject_Free(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_destroy(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -static void BMutex_Lock (BMutex *o) -{ - DebugObject_Access(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_lock(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -static void BMutex_Unlock (BMutex *o) -{ - DebugObject_Access(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_unlock(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -#endif diff --git a/external/badvpn_dns/base/BPending.c b/external/badvpn_dns/base/BPending.c deleted file mode 100644 index 6711604..0000000 --- a/external/badvpn_dns/base/BPending.c +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @file BPending.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/offset.h> - -#include "BPending.h" - -#include "BPending_list.h" -#include <structure/SLinkedList_impl.h> - -void BPendingGroup_Init (BPendingGroup *g) -{ - // init jobs list - BPending__List_Init(&g->jobs); - - // init pending counter - DebugCounter_Init(&g->pending_ctr); - - // init debug object - DebugObject_Init(&g->d_obj); -} - -void BPendingGroup_Free (BPendingGroup *g) -{ - DebugCounter_Free(&g->pending_ctr); - ASSERT(BPending__List_IsEmpty(&g->jobs)) - DebugObject_Free(&g->d_obj); -} - -int BPendingGroup_HasJobs (BPendingGroup *g) -{ - DebugObject_Access(&g->d_obj); - - return !BPending__List_IsEmpty(&g->jobs); -} - -void BPendingGroup_ExecuteJob (BPendingGroup *g) -{ - ASSERT(!BPending__List_IsEmpty(&g->jobs)) - DebugObject_Access(&g->d_obj); - - // get a job - BSmallPending *p = BPending__List_First(&g->jobs); - ASSERT(!BPending__ListIsRemoved(p)) - ASSERT(p->pending) - - // remove from jobs list - BPending__List_RemoveFirst(&g->jobs); - - // set not pending - BPending__ListMarkRemoved(p); -#ifndef NDEBUG - p->pending = 0; -#endif - - // execute job - p->handler(p->user); - return; -} - -BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g) -{ - DebugObject_Access(&g->d_obj); - - return BPending__List_First(&g->jobs); -} - -void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user) -{ - // init arguments - o->handler = handler; - o->user = user; - - // set not pending - BPending__ListMarkRemoved(o); -#ifndef NDEBUG - o->pending = 0; -#endif - - // increment pending counter - DebugCounter_Increment(&g->pending_ctr); - - // init debug object - DebugObject_Init(&o->d_obj); -} - -void BSmallPending_Free (BSmallPending *o, BPendingGroup *g) -{ - DebugCounter_Decrement(&g->pending_ctr); - DebugObject_Free(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - // remove from jobs list - if (!BPending__ListIsRemoved(o)) { - BPending__List_Remove(&g->jobs, o); - } -} - -void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - // set handler - o->handler = handler; - o->user = user; -} - -void BSmallPending_Set (BSmallPending *o, BPendingGroup *g) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - // remove from jobs list - if (!BPending__ListIsRemoved(o)) { - BPending__List_Remove(&g->jobs, o); - } - - // insert to jobs list - BPending__List_Prepend(&g->jobs, o); - - // set pending -#ifndef NDEBUG - o->pending = 1; -#endif -} - -void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - if (!BPending__ListIsRemoved(o)) { - // remove from jobs list - BPending__List_Remove(&g->jobs, o); - - // set not pending - BPending__ListMarkRemoved(o); -#ifndef NDEBUG - o->pending = 0; -#endif - } -} - -int BSmallPending_IsSet (BSmallPending *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - return !BPending__ListIsRemoved(o); -} - -void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user) -{ - BSmallPending_Init(&o->base, g, handler, user); - o->g = g; -} - -void BPending_Free (BPending *o) -{ - BSmallPending_Free(&o->base, o->g); -} - -void BPending_Set (BPending *o) -{ - BSmallPending_Set(&o->base, o->g); -} - -void BPending_Unset (BPending *o) -{ - BSmallPending_Unset(&o->base, o->g); -} - -int BPending_IsSet (BPending *o) -{ - return BSmallPending_IsSet(&o->base); -} diff --git a/external/badvpn_dns/base/BPending.h b/external/badvpn_dns/base/BPending.h deleted file mode 100644 index 07644be..0000000 --- a/external/badvpn_dns/base/BPending.h +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file BPending.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module for managing a queue of jobs pending execution. - */ - -#ifndef BADVPN_BPENDING_H -#define BADVPN_BPENDING_H - -#include <stdint.h> - -#include <misc/debugcounter.h> -#include <structure/SLinkedList.h> -#include <base/DebugObject.h> - -struct BSmallPending_s; - -#include "BPending_list.h" -#include <structure/SLinkedList_decl.h> - -/** - * Job execution handler. - * It is guaranteed that the associated {@link BSmallPending} object was - * in set state. - * The {@link BSmallPending} object enters not set state before the handler - * is called. - * - * @param user as in {@link BSmallPending_Init} - */ -typedef void (*BSmallPending_handler) (void *user); - -/** - * Job execution handler. - * It is guaranteed that the associated {@link BPending} object was - * in set state. - * The {@link BPending} object enters not set state before the handler - * is called. - * - * @param user as in {@link BPending_Init} - */ -typedef void (*BPending_handler) (void *user); - -/** - * Object that contains a list of jobs pending execution. - */ -typedef struct { - BPending__List jobs; - DebugCounter pending_ctr; - DebugObject d_obj; -} BPendingGroup; - -/** - * Object for queuing a job for execution. - */ -typedef struct BSmallPending_s { - BPending_handler handler; - void *user; - BPending__ListNode pending_node; // optimization: if not pending, .next is this -#ifndef NDEBUG - uint8_t pending; -#endif - DebugObject d_obj; -} BSmallPending; - -/** - * Object for queuing a job for execution. This is a convenience wrapper - * around {@link BSmallPending} with an extra field to remember the - * {@link BPendingGroup} being used. - */ -typedef struct { - BSmallPending base; - BPendingGroup *g; -} BPending; - -/** - * Initializes the object. - * - * @param g the object - */ -void BPendingGroup_Init (BPendingGroup *g); - -/** - * Frees the object. - * There must be no {@link BPending} or {@link BSmallPending} objects using - * this group. - * - * @param g the object - */ -void BPendingGroup_Free (BPendingGroup *g); - -/** - * Checks if there is at least one job in the queue. - * - * @param g the object - * @return 1 if there is at least one job, 0 if not - */ -int BPendingGroup_HasJobs (BPendingGroup *g); - -/** - * Executes the top job on the job list. - * The job is removed from the list and enters - * not set state before being executed. - * There must be at least one job in job list. - * - * @param g the object - */ -void BPendingGroup_ExecuteJob (BPendingGroup *g); - -/** - * Returns the top job on the job list, or NULL if there are none. - * - * @param g the object - * @return the top job if there is at least one job, NULL if not - */ -BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g); - -/** - * Initializes the object. - * The object is initialized in not set state. - * - * @param o the object - * @param g pending group to use - * @param handler job execution handler - * @param user value to pass to handler - */ -void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user); - -/** - * Frees the object. - * The execution handler will not be called after the object - * is freed. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Free (BSmallPending *o, BPendingGroup *g); - -/** - * Changes the job execution handler. - * - * @param o the object - * @param handler job execution handler - * @param user value to pass to handler - */ -void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user); - -/** - * Enables the job, pushing it to the top of the job list. - * If the object was already in set state, the job is removed from its - * current position in the list before being pushed. - * The object enters set state. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Set (BSmallPending *o, BPendingGroup *g); - -/** - * Disables the job, removing it from the job list. - * If the object was not in set state, nothing is done. - * The object enters not set state. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g); - -/** - * Checks if the job is in set state. - * - * @param o the object - * @return 1 if in set state, 0 if not - */ -int BSmallPending_IsSet (BSmallPending *o); - -/** - * Initializes the object. - * The object is initialized in not set state. - * - * @param o the object - * @param g pending group to use - * @param handler job execution handler - * @param user value to pass to handler - */ -void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user); - -/** - * Frees the object. - * The execution handler will not be called after the object - * is freed. - * - * @param o the object - */ -void BPending_Free (BPending *o); - -/** - * Enables the job, pushing it to the top of the job list. - * If the object was already in set state, the job is removed from its - * current position in the list before being pushed. - * The object enters set state. - * - * @param o the object - */ -void BPending_Set (BPending *o); - -/** - * Disables the job, removing it from the job list. - * If the object was not in set state, nothing is done. - * The object enters not set state. - * - * @param o the object - */ -void BPending_Unset (BPending *o); - -/** - * Checks if the job is in set state. - * - * @param o the object - * @return 1 if in set state, 0 if not - */ -int BPending_IsSet (BPending *o); - -#endif diff --git a/external/badvpn_dns/base/BPending_list.h b/external/badvpn_dns/base/BPending_list.h deleted file mode 100644 index eadac61..0000000 --- a/external/badvpn_dns/base/BPending_list.h +++ /dev/null @@ -1,4 +0,0 @@ -#define SLINKEDLIST_PARAM_NAME BPending__List -#define SLINKEDLIST_PARAM_FEATURE_LAST 0 -#define SLINKEDLIST_PARAM_TYPE_ENTRY struct BSmallPending_s -#define SLINKEDLIST_PARAM_MEMBER_NODE pending_node diff --git a/external/badvpn_dns/base/CMakeLists.txt b/external/badvpn_dns/base/CMakeLists.txt deleted file mode 100644 index cf1f0f0..0000000 --- a/external/badvpn_dns/base/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(BASE_ADDITIONAL_SOURCES) - -if (HAVE_SYSLOG_H) - list(APPEND BASE_ADDITIONAL_SOURCES BLog_syslog.c) -endif () - -set(BASE_SOURCES - DebugObject.c - BLog.c - BPending.c - ${BASE_ADDITIONAL_SOURCES} -) -badvpn_add_library(base "" "" "${BASE_SOURCES}") diff --git a/external/badvpn_dns/base/DebugObject.c b/external/badvpn_dns/base/DebugObject.c deleted file mode 100644 index e694617..0000000 --- a/external/badvpn_dns/base/DebugObject.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file DebugObject.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "DebugObject.h" - -#ifndef BADVPN_PLUGIN -#ifndef NDEBUG -DebugCounter debugobject_counter = DEBUGCOUNTER_STATIC; -#if BADVPN_THREAD_SAFE -pthread_mutex_t debugobject_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif -#endif -#endif diff --git a/external/badvpn_dns/base/DebugObject.h b/external/badvpn_dns/base/DebugObject.h deleted file mode 100644 index b8db287..0000000 --- a/external/badvpn_dns/base/DebugObject.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file DebugObject.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used for detecting leaks. - */ - -#ifndef BADVPN_DEBUGOBJECT_H -#define BADVPN_DEBUGOBJECT_H - -#include <stdint.h> - -#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1) -#error BADVPN_THREAD_SAFE is not defined or incorrect -#endif - -#if BADVPN_THREAD_SAFE -#include <pthread.h> -#endif - -#include <misc/debug.h> -#include <misc/debugcounter.h> - -#define DEBUGOBJECT_VALID UINT32_C(0x31415926) - -/** - * Object used for detecting leaks. - */ -typedef struct { - #ifndef NDEBUG - uint32_t c; - #endif -} DebugObject; - -/** - * Initializes the object. - * - * @param obj the object - */ -static void DebugObject_Init (DebugObject *obj); - -/** - * Frees the object. - * - * @param obj the object - */ -static void DebugObject_Free (DebugObject *obj); - -/** - * Does nothing. - * - * @param obj the object - */ -static void DebugObject_Access (const DebugObject *obj); - -/** - * Does nothing. - * There must be no {@link DebugObject}'s initialized. - */ -static void DebugObjectGlobal_Finish (void); - -#ifndef NDEBUG -extern DebugCounter debugobject_counter; -#if BADVPN_THREAD_SAFE -extern pthread_mutex_t debugobject_mutex; -#endif -#endif - -void DebugObject_Init (DebugObject *obj) -{ - #ifndef NDEBUG - - obj->c = DEBUGOBJECT_VALID; - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0) - #endif - - DebugCounter_Increment(&debugobject_counter); - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0) - #endif - - #endif -} - -void DebugObject_Free (DebugObject *obj) -{ - ASSERT(obj->c == DEBUGOBJECT_VALID) - - #ifndef NDEBUG - - obj->c = 0; - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0) - #endif - - DebugCounter_Decrement(&debugobject_counter); - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0) - #endif - - #endif -} - -void DebugObject_Access (const DebugObject *obj) -{ - ASSERT(obj->c == DEBUGOBJECT_VALID) -} - -void DebugObjectGlobal_Finish (void) -{ - #ifndef NDEBUG - DebugCounter_Free(&debugobject_counter); - #endif -} - -#endif diff --git a/external/badvpn_dns/blog_channels.txt b/external/badvpn_dns/blog_channels.txt deleted file mode 100644 index 96313b5..0000000 --- a/external/badvpn_dns/blog_channels.txt +++ /dev/null @@ -1,145 +0,0 @@ -server 4 -client 4 -flooder 4 -tun2socks 4 -ncd 4 -ncd_var 4 -ncd_list 4 -ncd_depend 4 -ncd_multidepend 4 -ncd_dynamic_depend 4 -ncd_concat 4 -ncd_if 4 -ncd_strcmp 4 -ncd_regex_match 4 -ncd_logical 4 -ncd_sleep 4 -ncd_print 4 -ncd_blocker 4 -ncd_run 4 -ncd_runonce 4 -ncd_daemon 4 -ncd_spawn 4 -ncd_imperative 4 -ncd_ref 4 -ncd_index 4 -ncd_alias 4 -ncd_process_manager 4 -ncd_ondemand 4 -ncd_foreach 4 -ncd_choose 4 -ncd_net_backend_waitdevice 4 -ncd_net_backend_waitlink 4 -ncd_net_backend_badvpn 4 -ncd_net_backend_wpa_supplicant 4 -ncd_net_backend_rfkill 4 -ncd_net_up 4 -ncd_net_dns 4 -ncd_net_iptables 4 -ncd_net_ipv4_addr 4 -ncd_net_ipv4_route 4 -ncd_net_ipv4_dhcp 4 -ncd_net_ipv4_arp_probe 4 -ncd_net_watch_interfaces 4 -ncd_sys_watch_input 4 -ncd_sys_watch_usb 4 -ncd_sys_evdev 4 -ncd_sys_watch_directory 4 -StreamPeerIO 4 -DatagramPeerIO 4 -BReactor 3 -BSignal 3 -FragmentProtoAssembler 4 -BPredicate 3 -ServerConnection 4 -Listener 4 -DataProto 4 -FrameDecider 4 -BSocksClient 4 -BDHCPClientCore 4 -BDHCPClient 4 -NCDIfConfig 4 -BUnixSignal 4 -BProcess 4 -PRStreamSink 4 -PRStreamSource 4 -PacketProtoDecoder 4 -DPRelay 4 -BThreadWork 4 -DPReceive 4 -BInputProcess 4 -NCDUdevMonitorParser 4 -NCDUdevMonitor 4 -NCDUdevCache 4 -NCDUdevManager 4 -BTime 4 -BEncryption 4 -SPProtoDecoder 4 -LineBuffer 4 -BTap 4 -lwip 4 -NCDConfigTokenizer 4 -NCDConfigParser 4 -NCDValParser 4 -nsskey 4 -addr 4 -PasswordListener 4 -NCDInterfaceMonitor 4 -NCDRfkillMonitor 4 -udpgw 4 -UdpGwClient 4 -SocksUdpGwClient 4 -BNetwork 4 -BConnection 4 -BSSLConnection 4 -BDatagram 4 -PeerChat 4 -BArpProbe 4 -NCDModuleIndex 4 -NCDModuleProcess 4 -NCDValGenerator 4 -ncd_from_string 4 -ncd_to_string 4 -ncd_value 4 -ncd_try 4 -ncd_sys_request_server 4 -NCDRequest 4 -ncd_net_ipv6_wait_dynamic_addr 4 -NCDRequestClient 4 -ncd_request 4 -ncd_sys_request_client 4 -ncd_exit 4 -ncd_getargs 4 -ncd_arithmetic 4 -ncd_parse 4 -ncd_valuemetic 4 -ncd_file 4 -ncd_netmask 4 -ncd_implode 4 -ncd_call2 4 -ncd_assert 4 -ncd_reboot 4 -ncd_explode 4 -NCDPlaceholderDb 4 -NCDVal 4 -ncd_net_ipv6_addr 4 -ncd_net_ipv6_route 4 -ncd_net_ipv4_addr_in_network 4 -ncd_net_ipv6_addr_in_network 4 -dostest_server 4 -dostest_attacker 4 -ncd_timer 4 -ncd_file_open 4 -ncd_backtrack 4 -ncd_socket 4 -ncd_depend_scope 4 -ncd_substr 4 -ncd_sys_start_process 4 -NCDBuildProgram 4 -ncd_log 4 -ncd_log_msg 4 -ncd_buffer 4 -ncd_getenv 4 -BThreadSignal 4 -BLockReactor 4 -ncd_load_module 4 diff --git a/external/badvpn_dns/blog_generator/blog.php b/external/badvpn_dns/blog_generator/blog.php deleted file mode 100644 index fd436bc..0000000 --- a/external/badvpn_dns/blog_generator/blog.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php - -require_once "blog_functions.php"; - -function assert_failure ($script, $line, $message) -{ - if ($message == "") { - fatal_error("Assertion failure at {$script}:{$line}"); - } else { - fatal_error("Assertion failure at {$script}:{$line}: {$message}"); - } -} - -assert_options(ASSERT_CALLBACK, "assert_failure"); - -function print_help ($name) -{ - echo <<<EOD -Usage: {$name} - --input-file <file> Input channels file. - --output-dir <dir> Destination directory for generated files. - -EOD; -} - -$input_file = ""; -$output_dir = ""; - -for ($i = 1; $i < $argc;) { - $arg = $argv[$i++]; - switch ($arg) { - case "--input-file": - $input_file = $argv[$i++]; - break; - case "--output-dir": - $output_dir = $argv[$i++]; - break; - case "--help": - print_help($argv[0]); - exit(0); - default: - fatal_error("Unknown option: {$arg}"); - } -} - -if ($input_file == "") { - fatal_error("--input-file missing"); -} - -if ($output_dir == "") { - fatal_error("--output-dir missing"); -} - -if (($data = file_get_contents($input_file)) === FALSE) { - fatal_error("Failed to read input file"); -} - -if (!tokenize($data, $tokens)) { - fatal_error("Failed to tokenize"); -} - -$i = 0; -$channels_defines = ""; -$channels_list = ""; - -reset($tokens); - -while (1) { - if (($ch_name = current($tokens)) === FALSE) { - break; - } - next($tokens); - if (($ch_priority = current($tokens)) === FALSE) { - fatal_error("missing priority"); - } - next($tokens); - if ($ch_name[0] != "name") { - fatal_error("name is not a name"); - } - if ($ch_priority[0] != "number") { - fatal_error("priority is not a number"); - } - - $channel_file = <<<EOD -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_{$ch_name[1]} - -EOD; - - $channels_defines .= <<<EOD -#define BLOG_CHANNEL_{$ch_name[1]} {$i} - -EOD; - - $channels_list .= <<<EOD -{"{$ch_name[1]}", {$ch_priority[1]}}, - -EOD; - - if (file_put_contents("{$output_dir}/blog_channel_{$ch_name[1]}.h", $channel_file) === NULL) { - fatal_error("{$input_file}: Failed to write channel file"); - } - - $i++; -} - -$channels_defines .= <<<EOD -#define BLOG_NUM_CHANNELS {$i} - -EOD; - -if (file_put_contents("{$output_dir}/blog_channels_defines.h", $channels_defines) === NULL) { - fatal_error("{$input_file}: Failed to write channels defines file"); -} - -if (file_put_contents("{$output_dir}/blog_channels_list.h", $channels_list) === NULL) { - fatal_error("{$input_file}: Failed to write channels list file"); -} - diff --git a/external/badvpn_dns/blog_generator/blog_functions.php b/external/badvpn_dns/blog_generator/blog_functions.php deleted file mode 100644 index ba4be89..0000000 --- a/external/badvpn_dns/blog_generator/blog_functions.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -function tokenize ($str, &$out) { - $out = array(); - - while (strlen($str) > 0) { - if (preg_match('/^\\/\\/.*/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\\s+/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[0-9]+/', $str, $matches)) { - $out[] = array('number', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*/', $str, $matches)) { - $out[] = array('name', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else { - return FALSE; - } - } - - return TRUE; -} - -function fatal_error ($message) -{ - fwrite(STDERR, "Fatal error: $message\n"); - - ob_get_clean(); - exit(1); -} diff --git a/external/badvpn_dns/bproto/BProto.h b/external/badvpn_dns/bproto/BProto.h deleted file mode 100644 index 5f2a696..0000000 --- a/external/badvpn_dns/bproto/BProto.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file BProto.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for BProto serialization. - */ - -#ifndef BADVPN_BPROTO_BPROTO_H -#define BADVPN_BPROTO_BPROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define BPROTO_TYPE_UINT8 1 -#define BPROTO_TYPE_UINT16 2 -#define BPROTO_TYPE_UINT32 3 -#define BPROTO_TYPE_UINT64 4 -#define BPROTO_TYPE_DATA 5 -#define BPROTO_TYPE_CONSTDATA 6 - -B_START_PACKED -struct BProto_header_s { - uint16_t id; - uint16_t type; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint8_s { - uint8_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint16_s { - uint16_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint32_s { - uint32_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint64_s { - uint64_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_data_header_s { - uint32_t len; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/bproto_generator/ProtoParser.lime b/external/badvpn_dns/bproto_generator/ProtoParser.lime deleted file mode 100644 index f039e1d..0000000 --- a/external/badvpn_dns/bproto_generator/ProtoParser.lime +++ /dev/null @@ -1,99 +0,0 @@ -%class ProtoParser -%start file - -file = - directives messages { - $$ = array( - "directives" => $1, - "messages" => $2 - ); - }. - -directives = - { - $$ = array(); - } | - directive semicolon directives { - $$ = array_merge(array($1), $3); - }. - -directive = - include string { - $$ = array( - "type" => "include", - "file" => $2 - ); - }. - -messages = - msgspec { - $$ = array($1); - } | - msgspec messages { - $$ = array_merge(array($1), $2); - }. - -msgspec = - message name spar entries epar semicolon { - $$ = array( - "name" => $2, - "entries" => $4 - ); -}. - -entries = - entry { - $$ = array($1); - } | - entry entries { - $$ = array_merge(array($1), $2); - }. - -entry = - cardinality type name equals number semicolon { - $$ = array( - "cardinality" => $1, - "type" => $2, - "name" => $3, - "id" => $5 - ); - }. - -cardinality = - repeated { - $$ = "repeated"; - } | - optional { - $$ = "optional"; - } | - required { - $$ = "required"; - } | - required repeated { - $$ = "required repeated"; - }. - -type = - uint { - $$ = array( - "type" => "uint", - "size" => $1 - ); - } | - data { - $$ = array( - "type" => "data" - ); - } | - data srpar string erpar { - $$ = array( - "type" => "constdata", - "size" => $3 - ); - } | - message name { - $$ = array( - "type" => "message", - "message" => $2 - ); - }. diff --git a/external/badvpn_dns/bproto_generator/ProtoParser.php b/external/badvpn_dns/bproto_generator/ProtoParser.php deleted file mode 100644 index 0477dba..0000000 --- a/external/badvpn_dns/bproto_generator/ProtoParser.php +++ /dev/null @@ -1,560 +0,0 @@ -<?php - - -/* - -DON'T EDIT THIS FILE! - -This file was automatically generated by the Lime parser generator. -The real source code you should be looking at is in one or more -grammar files in the Lime format. - -THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar -file that your error happened, because there are enough comments to -help you debug your grammar. - -If you ignore this warning, you're shooting yourself in the brain, -not the foot. - -*/ - -class ProtoParser extends lime_parser { -var $qi = 0; -var $i = array ( - 0 => - array ( - 'directives' => 's 1', - 'directive' => 's 30', - 'include' => 's 33', - 'file' => 's 35', - '\'start\'' => 'a \'start\'', - 'message' => 'r 1', - ), - 1 => - array ( - 'messages' => 's 2', - 'msgspec' => 's 3', - 'message' => 's 5', - ), - 2 => - array ( - '#' => 'r 0', - ), - 3 => - array ( - 'msgspec' => 's 3', - 'messages' => 's 4', - 'message' => 's 5', - '#' => 'r 4', - ), - 4 => - array ( - '#' => 'r 5', - ), - 5 => - array ( - 'name' => 's 6', - ), - 6 => - array ( - 'spar' => 's 7', - ), - 7 => - array ( - 'entries' => 's 8', - 'entry' => 's 11', - 'cardinality' => 's 13', - 'repeated' => 's 26', - 'optional' => 's 27', - 'required' => 's 28', - ), - 8 => - array ( - 'epar' => 's 9', - ), - 9 => - array ( - 'semicolon' => 's 10', - ), - 10 => - array ( - 'message' => 'r 6', - '#' => 'r 6', - ), - 11 => - array ( - 'entry' => 's 11', - 'entries' => 's 12', - 'cardinality' => 's 13', - 'repeated' => 's 26', - 'optional' => 's 27', - 'required' => 's 28', - 'epar' => 'r 7', - ), - 12 => - array ( - 'epar' => 'r 8', - ), - 13 => - array ( - 'type' => 's 14', - 'uint' => 's 19', - 'data' => 's 20', - 'message' => 's 24', - ), - 14 => - array ( - 'name' => 's 15', - ), - 15 => - array ( - 'equals' => 's 16', - ), - 16 => - array ( - 'number' => 's 17', - ), - 17 => - array ( - 'semicolon' => 's 18', - ), - 18 => - array ( - 'repeated' => 'r 9', - 'optional' => 'r 9', - 'required' => 'r 9', - 'epar' => 'r 9', - ), - 19 => - array ( - 'name' => 'r 14', - ), - 20 => - array ( - 'srpar' => 's 21', - 'name' => 'r 15', - ), - 21 => - array ( - 'string' => 's 22', - ), - 22 => - array ( - 'erpar' => 's 23', - ), - 23 => - array ( - 'name' => 'r 16', - ), - 24 => - array ( - 'name' => 's 25', - ), - 25 => - array ( - 'name' => 'r 17', - ), - 26 => - array ( - 'uint' => 'r 10', - 'data' => 'r 10', - 'message' => 'r 10', - ), - 27 => - array ( - 'uint' => 'r 11', - 'data' => 'r 11', - 'message' => 'r 11', - ), - 28 => - array ( - 'repeated' => 's 29', - 'uint' => 'r 12', - 'data' => 'r 12', - 'message' => 'r 12', - ), - 29 => - array ( - 'uint' => 'r 13', - 'data' => 'r 13', - 'message' => 'r 13', - ), - 30 => - array ( - 'semicolon' => 's 31', - ), - 31 => - array ( - 'directive' => 's 30', - 'directives' => 's 32', - 'include' => 's 33', - 'message' => 'r 1', - ), - 32 => - array ( - 'message' => 'r 2', - ), - 33 => - array ( - 'string' => 's 34', - ), - 34 => - array ( - 'semicolon' => 'r 3', - ), - 35 => - array ( - '#' => 'r 18', - ), -); -function reduce_0_file_1($tokens, &$result) { -# -# (0) file := directives messages -# -$result = reset($tokens); - - $result = array( - "directives" => $tokens[0], - "messages" => $tokens[1] - ); - -} - -function reduce_1_directives_1($tokens, &$result) { -# -# (1) directives := -# -$result = reset($tokens); - - $result = array(); - -} - -function reduce_2_directives_2($tokens, &$result) { -# -# (2) directives := directive semicolon directives -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[2]); - -} - -function reduce_3_directive_1($tokens, &$result) { -# -# (3) directive := include string -# -$result = reset($tokens); - - $result = array( - "type" => "include", - "file" => $tokens[1] - ); - -} - -function reduce_4_messages_1($tokens, &$result) { -# -# (4) messages := msgspec -# -$result = reset($tokens); - - $result = array($tokens[0]); - -} - -function reduce_5_messages_2($tokens, &$result) { -# -# (5) messages := msgspec messages -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[1]); - -} - -function reduce_6_msgspec_1($tokens, &$result) { -# -# (6) msgspec := message name spar entries epar semicolon -# -$result = reset($tokens); - - $result = array( - "name" => $tokens[1], - "entries" => $tokens[3] - ); - -} - -function reduce_7_entries_1($tokens, &$result) { -# -# (7) entries := entry -# -$result = reset($tokens); - - $result = array($tokens[0]); - -} - -function reduce_8_entries_2($tokens, &$result) { -# -# (8) entries := entry entries -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[1]); - -} - -function reduce_9_entry_1($tokens, &$result) { -# -# (9) entry := cardinality type name equals number semicolon -# -$result = reset($tokens); - - $result = array( - "cardinality" => $tokens[0], - "type" => $tokens[1], - "name" => $tokens[2], - "id" => $tokens[4] - ); - -} - -function reduce_10_cardinality_1($tokens, &$result) { -# -# (10) cardinality := repeated -# -$result = reset($tokens); - - $result = "repeated"; - -} - -function reduce_11_cardinality_2($tokens, &$result) { -# -# (11) cardinality := optional -# -$result = reset($tokens); - - $result = "optional"; - -} - -function reduce_12_cardinality_3($tokens, &$result) { -# -# (12) cardinality := required -# -$result = reset($tokens); - - $result = "required"; - -} - -function reduce_13_cardinality_4($tokens, &$result) { -# -# (13) cardinality := required repeated -# -$result = reset($tokens); - - $result = "required repeated"; - -} - -function reduce_14_type_1($tokens, &$result) { -# -# (14) type := uint -# -$result = reset($tokens); - - $result = array( - "type" => "uint", - "size" => $tokens[0] - ); - -} - -function reduce_15_type_2($tokens, &$result) { -# -# (15) type := data -# -$result = reset($tokens); - - $result = array( - "type" => "data" - ); - -} - -function reduce_16_type_3($tokens, &$result) { -# -# (16) type := data srpar string erpar -# -$result = reset($tokens); - - $result = array( - "type" => "constdata", - "size" => $tokens[2] - ); - -} - -function reduce_17_type_4($tokens, &$result) { -# -# (17) type := message name -# -$result = reset($tokens); - - $result = array( - "type" => "message", - "message" => $tokens[1] - ); - -} - -function reduce_18_start_1($tokens, &$result) { -# -# (18) 'start' := file -# -$result = reset($tokens); - -} - -var $method = array ( - 0 => 'reduce_0_file_1', - 1 => 'reduce_1_directives_1', - 2 => 'reduce_2_directives_2', - 3 => 'reduce_3_directive_1', - 4 => 'reduce_4_messages_1', - 5 => 'reduce_5_messages_2', - 6 => 'reduce_6_msgspec_1', - 7 => 'reduce_7_entries_1', - 8 => 'reduce_8_entries_2', - 9 => 'reduce_9_entry_1', - 10 => 'reduce_10_cardinality_1', - 11 => 'reduce_11_cardinality_2', - 12 => 'reduce_12_cardinality_3', - 13 => 'reduce_13_cardinality_4', - 14 => 'reduce_14_type_1', - 15 => 'reduce_15_type_2', - 16 => 'reduce_16_type_3', - 17 => 'reduce_17_type_4', - 18 => 'reduce_18_start_1', -); -var $a = array ( - 0 => - array ( - 'symbol' => 'file', - 'len' => 2, - 'replace' => true, - ), - 1 => - array ( - 'symbol' => 'directives', - 'len' => 0, - 'replace' => true, - ), - 2 => - array ( - 'symbol' => 'directives', - 'len' => 3, - 'replace' => true, - ), - 3 => - array ( - 'symbol' => 'directive', - 'len' => 2, - 'replace' => true, - ), - 4 => - array ( - 'symbol' => 'messages', - 'len' => 1, - 'replace' => true, - ), - 5 => - array ( - 'symbol' => 'messages', - 'len' => 2, - 'replace' => true, - ), - 6 => - array ( - 'symbol' => 'msgspec', - 'len' => 6, - 'replace' => true, - ), - 7 => - array ( - 'symbol' => 'entries', - 'len' => 1, - 'replace' => true, - ), - 8 => - array ( - 'symbol' => 'entries', - 'len' => 2, - 'replace' => true, - ), - 9 => - array ( - 'symbol' => 'entry', - 'len' => 6, - 'replace' => true, - ), - 10 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 11 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 12 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 13 => - array ( - 'symbol' => 'cardinality', - 'len' => 2, - 'replace' => true, - ), - 14 => - array ( - 'symbol' => 'type', - 'len' => 1, - 'replace' => true, - ), - 15 => - array ( - 'symbol' => 'type', - 'len' => 1, - 'replace' => true, - ), - 16 => - array ( - 'symbol' => 'type', - 'len' => 4, - 'replace' => true, - ), - 17 => - array ( - 'symbol' => 'type', - 'len' => 2, - 'replace' => true, - ), - 18 => - array ( - 'symbol' => '\'start\'', - 'len' => 1, - 'replace' => true, - ), -); -} diff --git a/external/badvpn_dns/bproto_generator/bproto.php b/external/badvpn_dns/bproto_generator/bproto.php deleted file mode 100644 index 76f8c6e..0000000 --- a/external/badvpn_dns/bproto_generator/bproto.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php -/** - * @file bproto.php - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -require_once "lime/parse_engine.php"; -require_once "ProtoParser.php"; -require_once "bproto_functions.php"; - -function assert_failure ($script, $line, $message) -{ - if ($message == "") { - fatal_error("Assertion failure at {$script}:{$line}"); - } else { - fatal_error("Assertion failure at {$script}:{$line}: {$message}"); - } -} - -assert_options(ASSERT_CALLBACK, "assert_failure"); - -function print_help ($name) -{ - echo <<<EOD -Usage: {$name} - --name <string> Output file prefix. - --input-file <file> Message file to generate source for. - --output-dir <dir> Destination directory for generated files. - -EOD; -} - -$name = ""; -$input_file = ""; -$output_dir = ""; - -for ($i = 1; $i < $argc;) { - $arg = $argv[$i++]; - switch ($arg) { - case "--name": - $name = $argv[$i++]; - break; - case "--input-file": - $input_file = $argv[$i++]; - break; - case "--output-dir": - $output_dir = $argv[$i++]; - break; - case "--help": - print_help($argv[0]); - exit(0); - default: - fatal_error("Unknown option: {$arg}"); - } -} - -if ($name == "") { - fatal_error("--name missing"); -} - -if ($input_file == "") { - fatal_error("--input-file missing"); -} - -if ($output_dir == "") { - fatal_error("--output-dir missing"); -} - -if (($data = file_get_contents($input_file)) === FALSE) { - fatal_error("Failed to read input file"); -} - -if (!tokenize($data, $tokens)) { - fatal_error("Failed to tokenize"); -} - -$parser = new parse_engine(new ProtoParser()); - -try { - foreach ($tokens as $token) { - $parser->eat($token[0], $token[1]); - } - $parser->eat_eof(); -} catch (parse_error $e) { - fatal_error("$input_file: Parse error: ".$e->getMessage()); -} - -$data = generate_header($name, $parser->semantic["directives"], $parser->semantic["messages"]); -if (file_put_contents("{$output_dir}/{$name}.h", $data) === NULL) { - fatal_error("{$input_file}: Failed to write .h file"); -} diff --git a/external/badvpn_dns/bproto_generator/bproto_functions.php b/external/badvpn_dns/bproto_generator/bproto_functions.php deleted file mode 100644 index 490c1bf..0000000 --- a/external/badvpn_dns/bproto_generator/bproto_functions.php +++ /dev/null @@ -1,777 +0,0 @@ -<?php - -function tokenize ($str, &$out) { - $out = array(); - - while (strlen($str) > 0) { - if (preg_match('/^\\/\\/.*/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\\s+/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^include/', $str, $matches)) { - $out[] = array('include', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^message/', $str, $matches)) { - $out[] = array('message', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^repeated/', $str, $matches)) { - $out[] = array('repeated', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^required/', $str, $matches)) { - $out[] = array('required', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^optional/', $str, $matches)) { - $out[] = array('optional', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^{/', $str, $matches)) { - $out[] = array('spar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^}/', $str, $matches)) { - $out[] = array('epar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\(/', $str, $matches)) { - $out[] = array('srpar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\)/', $str, $matches)) { - $out[] = array('erpar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^=/', $str, $matches)) { - $out[] = array('equals', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^;/', $str, $matches)) { - $out[] = array('semicolon', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^uint(8|16|32|64)/', $str, $matches)) { - $out[] = array('uint', $matches[1]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^data/', $str, $matches)) { - $out[] = array('data', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[0-9]+/', $str, $matches)) { - $out[] = array('number', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*/', $str, $matches)) { - $out[] = array('name', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^"([^"]*)"/', $str, $matches)) { - $out[] = array('string', $matches[1]); - $str = substr($str, strlen($matches[0])); - } - else { - return FALSE; - } - } - - return TRUE; -} - -function fatal_error ($message) -{ - fwrite(STDERR, "Fatal error: $message\n"); - - ob_get_clean(); - exit(1); -} - -function make_writer_decl ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "void {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o, uint{$entry["type"]["size"]}_t v)"; - case "data": - return "uint8_t * {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o, int len)"; - case "constdata": - return "uint8_t * {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o)"; - default: - assert(0); - } -} - -function make_parser_decl ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint{$entry["type"]["size"]}_t *v)"; - case "data": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint8_t **data, int *data_len)"; - case "constdata": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint8_t **data)"; - default: - assert(0); - } -} - -function make_parser_reset_decl ($msg, $entry) -{ - return "void {$msg["name"]}Parser_Reset{$entry["name"]} ({$msg["name"]}Parser *o)"; -} - -function make_parser_forward_decl ($msg, $entry) -{ - return "void {$msg["name"]}Parser_Forward{$entry["name"]} ({$msg["name"]}Parser *o)"; -} - -function make_type_name ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "BPROTO_TYPE_UINT{$entry["type"]["size"]}"; - case "data": - return "BPROTO_TYPE_DATA"; - case "constdata": - return "BPROTO_TYPE_CONSTDATA"; - default: - assert(0); - } -} - -function make_finish_assert ($msg, $entry) -{ - switch ($entry["cardinality"]) { - case "repeated": - return "ASSERT(o->{$entry["name"]}_count >= 0)"; - case "required repeated": - return "ASSERT(o->{$entry["name"]}_count >= 1)"; - case "optional": - return "ASSERT(o->{$entry["name"]}_count >= 0 && o->{$entry["name"]}_count <= 1)"; - case "required": - return "ASSERT(o->{$entry["name"]}_count == 1)"; - default: - assert(0); - } -} - -function make_add_count_assert ($msg, $entry) -{ - if (in_array($entry["cardinality"], array("optional", "required"))) { - return "ASSERT(o->{$entry["name"]}_count == 0)"; - } - return ""; -} - -function make_add_length_assert ($msg, $entry) -{ - if ($entry["type"]["type"] == "data") { - return "ASSERT(len >= 0 && len <= UINT32_MAX)"; - } - return ""; -} - -function make_size_define ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "#define {$msg["name"]}_SIZE{$entry["name"]} (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint{$entry["type"]["size"]}_s))"; - case "data": - return "#define {$msg["name"]}_SIZE{$entry["name"]}(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len))"; - case "constdata": - return "#define {$msg["name"]}_SIZE{$entry["name"]} (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + ({$entry["type"]["size"]}))"; - default: - assert(0); - } -} - -function generate_header ($name, $directives, $messages) { - ob_start(); - - echo <<<EOD -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <bproto/BProto.h> - - -EOD; - - foreach ($directives as $directive) { - if ($directive["type"] == "include") { - echo <<<EOD -#include "{$directive["file"]}" - -EOD; - } - } - - echo <<<EOD - - -EOD; - - foreach ($messages as $msg) { - - foreach ($msg["entries"] as $entry) { - $def = make_size_define($msg, $entry); - echo <<<EOD -{$def} - -EOD; - } - - echo <<<EOD - -typedef struct { - uint8_t *out; - int used; - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<<EOD - int {$entry["name"]}_count; - -EOD; - } - - echo <<<EOD -} {$msg["name"]}Writer; - -static void {$msg["name"]}Writer_Init ({$msg["name"]}Writer *o, uint8_t *out); -static int {$msg["name"]}Writer_Finish ({$msg["name"]}Writer *o); - -EOD; - - foreach ($msg["entries"] as $entry) { - $decl = make_writer_decl($msg, $entry); - echo <<<EOD -static {$decl}; - -EOD; - } - - echo <<<EOD - -typedef struct { - uint8_t *buf; - int buf_len; - -EOD; - foreach ($msg["entries"] as $entry) { - echo <<<EOD - int {$entry["name"]}_start; - int {$entry["name"]}_span; - int {$entry["name"]}_pos; - -EOD; - } - - echo <<<EOD -} {$msg["name"]}Parser; - -static int {$msg["name"]}Parser_Init ({$msg["name"]}Parser *o, uint8_t *buf, int buf_len); -static int {$msg["name"]}Parser_GotEverything ({$msg["name"]}Parser *o); - -EOD; - - foreach ($msg["entries"] as $entry) { - $decl = make_parser_decl($msg, $entry); - $reset_decl = make_parser_reset_decl($msg, $entry); - $forward_decl = make_parser_forward_decl($msg, $entry); - echo <<<EOD -static {$decl}; -static {$reset_decl}; -static {$forward_decl}; - -EOD; - } - - echo <<<EOD - -void {$msg["name"]}Writer_Init ({$msg["name"]}Writer *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<<EOD - o->{$entry["name"]}_count = 0; - -EOD; - } - - echo <<<EOD -} - -int {$msg["name"]}Writer_Finish ({$msg["name"]}Writer *o) -{ - ASSERT(o->used >= 0) - -EOD; - - foreach ($msg["entries"] as $entry) { - $ass = make_finish_assert($msg, $entry); - echo <<<EOD - {$ass} - -EOD; - } - - echo <<<EOD - - return o->used; -} - - -EOD; - - foreach ($msg["entries"] as $entry) { - $decl = make_writer_decl($msg, $entry); - $type = make_type_name($msg, $entry); - $add_count_assert = make_add_count_assert($msg, $entry); - $add_length_assert = make_add_length_assert($msg, $entry); - - echo <<<EOD -{$decl} -{ - ASSERT(o->used >= 0) - {$add_count_assert} - {$add_length_assert} - - struct BProto_header_s header; - header.id = htol16({$entry["id"]}); - header.type = htol16({$type}); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - -EOD; - switch ($entry["type"]["type"]) { - case "uint": - echo <<<EOD - struct BProto_uint{$entry["type"]["size"]}_s data; - data.v = htol{$entry["type"]["size"]}(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint{$entry["type"]["size"]}_s); - -EOD; - break; - case "data": - echo <<<EOD - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - -EOD; - break; - case "constdata": - echo <<<EOD - struct BProto_data_header_s data; - data.len = htol32({$entry["type"]["size"]}); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += ({$entry["type"]["size"]}); - -EOD; - break; - default: - assert(0); - } - - echo <<<EOD - - o->{$entry["name"]}_count++; - -EOD; - if (in_array($entry["type"]["type"], array("data", "constdata"))) { - echo <<<EOD - - return dest; - -EOD; - } - - echo <<<EOD -} - - -EOD; - } - - echo <<<EOD -int {$msg["name"]}Parser_Init ({$msg["name"]}Parser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<<EOD - o->{$entry["name"]}_start = o->buf_len; - o->{$entry["name"]}_span = 0; - o->{$entry["name"]}_pos = 0; - -EOD; - } - - echo <<<EOD - - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<<EOD - int {$entry["name"]}_count = 0; - -EOD; - } - - echo <<<EOD - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - -EOD; - - foreach (array(8, 16, 32, 64) as $bits) { - echo <<<EOD - case BPROTO_TYPE_UINT{$bits}: { - if (!(left >= sizeof(struct BProto_uint{$bits}_s))) { - return 0; - } - pos += sizeof(struct BProto_uint{$bits}_s); - left -= sizeof(struct BProto_uint{$bits}_s); - - switch (id) { - -EOD; - - foreach ($msg["entries"] as $entry) { - if (!($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits)) { - continue; - } - $type = make_type_name($msg, $entry); - echo <<<EOD - case {$entry["id"]}: - if (o->{$entry["name"]}_start == o->buf_len) { - o->{$entry["name"]}_start = entry_pos; - } - o->{$entry["name"]}_span = pos - o->{$entry["name"]}_start; - {$entry["name"]}_count++; - break; - -EOD; - } - - echo <<<EOD - default: - return 0; - } - } break; - -EOD; - } - - echo <<<EOD - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - -EOD; - - foreach ($msg["entries"] as $entry) { - if (!in_array($entry["type"]["type"], array("data", "constdata"))) { - continue; - } - $type = make_type_name($msg, $entry); - echo <<<EOD - case {$entry["id"]}: - if (!(type == {$type})) { - return 0; - } - -EOD; - if ($entry["type"]["type"] == "constdata") { - echo <<<EOD - if (!(payload_len == ({$entry["type"]["size"]}))) { - return 0; - } - -EOD; - } - echo <<<EOD - if (o->{$entry["name"]}_start == o->buf_len) { - o->{$entry["name"]}_start = entry_pos; - } - o->{$entry["name"]}_span = pos - o->{$entry["name"]}_start; - {$entry["name"]}_count++; - break; - -EOD; - } - - echo <<<EOD - default: - return 0; - } - } break; - default: - return 0; - } - } - - -EOD; - - foreach ($msg["entries"] as $entry) { - $cond = ""; - switch ($entry["cardinality"]) { - case "repeated": - break; - case "required repeated": - $cond = "{$entry["name"]}_count >= 1"; - break; - case "optional": - $cond = "{$entry["name"]}_count <= 1"; - break; - case "required": - $cond = "{$entry["name"]}_count == 1"; - break; - default: - assert(0); - } - if ($cond) { - echo <<<EOD - if (!({$cond})) { - return 0; - } - -EOD; - } - } - - echo <<<EOD - - return 1; -} - -int {$msg["name"]}Parser_GotEverything ({$msg["name"]}Parser *o) -{ - return ( - -EOD; - - $first = 1; - foreach ($msg["entries"] as $entry) { - if ($first) { - $first = 0; - } else { - echo <<<EOD - && - -EOD; - } - echo <<<EOD - o->{$entry["name"]}_pos == o->{$entry["name"]}_span - -EOD; - } - - - echo <<<EOD - ); -} - - -EOD; - - foreach ($msg["entries"] as $entry) { - $decl = make_parser_decl($msg, $entry); - $reset_decl = make_parser_reset_decl($msg, $entry); - $forward_decl = make_parser_forward_decl($msg, $entry); - $type = make_type_name($msg, $entry); - - echo <<<EOD -{$decl} -{ - ASSERT(o->{$entry["name"]}_pos >= 0) - ASSERT(o->{$entry["name"]}_pos <= o->{$entry["name"]}_span) - - int left = o->{$entry["name"]}_span - o->{$entry["name"]}_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(header)); - o->{$entry["name"]}_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - -EOD; - - foreach (array(8, 16, 32, 64) as $bits) { - echo <<<EOD - case BPROTO_TYPE_UINT{$bits}: { - ASSERT(left >= sizeof(struct BProto_uint{$bits}_s)) - -EOD; - if ($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits) { - echo <<<EOD - struct BProto_uint{$bits}_s val; - memcpy(&val, o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(val)); - -EOD; - } - echo <<<EOD - o->{$entry["name"]}_pos += sizeof(struct BProto_uint{$bits}_s); - left -= sizeof(struct BProto_uint{$bits}_s); - -EOD; - if ($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits) { - echo <<<EOD - - if (id == {$entry["id"]}) { - *v = ltoh{$bits}(val.v); - return 1; - } - -EOD; - } - - echo <<<EOD - } break; - -EOD; - } - - echo <<<EOD - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(val)); - o->{$entry["name"]}_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - -EOD; - if ($entry["type"]["type"] == "data" || $entry["type"]["type"] == "constdata") { - echo <<<EOD - uint8_t *payload = o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos; - -EOD; - } - echo <<<EOD - o->{$entry["name"]}_pos += payload_len; - left -= payload_len; - -EOD; - if ($entry["type"]["type"] == "data") { - echo <<<EOD - - if (type == BPROTO_TYPE_DATA && id == {$entry["id"]}) { - *data = payload; - *data_len = payload_len; - return 1; - } - -EOD; - } - else if ($entry["type"]["type"] == "constdata") { - echo <<<EOD - - if (type == BPROTO_TYPE_CONSTDATA && id == {$entry["id"]}) { - *data = payload; - return 1; - } - -EOD; - } - - echo <<<EOD - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -{$reset_decl} -{ - o->{$entry["name"]}_pos = 0; -} - -{$forward_decl} -{ - o->{$entry["name"]}_pos = o->{$entry["name"]}_span; -} - - -EOD; - } - } - - return ob_get_clean(); -} diff --git a/external/badvpn_dns/client/CMakeLists.txt b/external/badvpn_dns/client/CMakeLists.txt deleted file mode 100644 index 3cec1a9..0000000 --- a/external/badvpn_dns/client/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -add_executable(badvpn-client - client.c - StreamPeerIO.c - DatagramPeerIO.c - PasswordListener.c - DataProto.c - FrameDecider.c - DPRelay.c - DPReceive.c - FragmentProtoDisassembler.c - FragmentProtoAssembler.c - SPProtoEncoder.c - SPProtoDecoder.c - DataProtoKeepaliveSource.c - PeerChat.c - SCOutmsgEncoder.c - SimpleStreamBuffer.c - SinglePacketSource.c -) -target_link_libraries(badvpn-client system flow flowextra tuntap server_conection security threadwork ${NSPR_LIBRARIES} ${NSS_LIBRARIES}) - -install( - TARGETS badvpn-client - RUNTIME DESTINATION bin -) - -install( - FILES badvpn-client.8 - DESTINATION share/man/man8 -) diff --git a/external/badvpn_dns/client/DPReceive.c b/external/badvpn_dns/client/DPReceive.c deleted file mode 100644 index da70c74..0000000 --- a/external/badvpn_dns/client/DPReceive.c +++ /dev/null @@ -1,324 +0,0 @@ -/** - * @file DPReceive.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <limits.h> -#include <string.h> - -#include <protocol/dataproto.h> -#include <misc/byteorder.h> -#include <misc/offset.h> -#include <base/BLog.h> - -#include <client/DPReceive.h> - -#include <generated/blog_channel_DPReceive.h> - -static DPReceivePeer * find_peer (DPReceiveDevice *o, peerid_t id) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->peers_list); node; node = LinkedList1Node_Next(node)) { - DPReceivePeer *p = UPPER_OBJECT(node, DPReceivePeer, list_node); - if (p->peer_id == id) { - return p; - } - } - - return NULL; -} - -static void receiver_recv_handler_send (DPReceiveReceiver *o, uint8_t *packet, int packet_len) -{ - DebugObject_Access(&o->d_obj); - DPReceivePeer *peer = o->peer; - DPReceiveDevice *device = peer->device; - ASSERT(packet_len >= 0) - ASSERT(packet_len <= device->packet_mtu) - - uint8_t *data = packet; - int data_len = packet_len; - - int local = 0; - DPReceivePeer *src_peer; - DPReceivePeer *relay_dest_peer = NULL; - - // check header - if (data_len < sizeof(struct dataproto_header)) { - BLog(BLOG_WARNING, "no dataproto header"); - goto out; - } - struct dataproto_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t flags = ltoh8(header.flags); - peerid_t from_id = ltoh16(header.from_id); - int num_ids = ltoh16(header.num_peer_ids); - - // check destination ID - if (!(num_ids == 0 || num_ids == 1)) { - BLog(BLOG_WARNING, "wrong number of destinations"); - goto out; - } - peerid_t to_id = 0; // to remove warning - if (num_ids == 1) { - if (data_len < sizeof(struct dataproto_peer_id)) { - BLog(BLOG_WARNING, "missing destination"); - goto out; - } - struct dataproto_peer_id id; - memcpy(&id, data, sizeof(id)); - to_id = ltoh16(id.id); - data += sizeof(id); - data_len -= sizeof(id); - } - - // check remaining data - if (data_len > device->device_mtu) { - BLog(BLOG_WARNING, "frame too large"); - goto out; - } - - // inform sink of received packet - if (peer->dp_sink) { - DataProtoSink_Received(peer->dp_sink, !!(flags & DATAPROTO_FLAGS_RECEIVING_KEEPALIVES)); - } - - if (num_ids == 1) { - // find source peer - if (!(src_peer = find_peer(device, from_id))) { - BLog(BLOG_INFO, "source peer %d not known", (int)from_id); - goto out; - } - - // is frame for device or another peer? - if (device->have_peer_id && to_id == device->peer_id) { - // let the frame decider analyze the frame - FrameDeciderPeer_Analyze(src_peer->decider_peer, data, data_len); - - // pass frame to device - local = 1; - } else { - // check if relaying is allowed - if (!peer->is_relay_client) { - BLog(BLOG_WARNING, "relaying not allowed"); - goto out; - } - - // provided source ID must be the peer sending the frame - if (src_peer != peer) { - BLog(BLOG_WARNING, "relay source must be the sending peer"); - goto out; - } - - // find destination peer - DPReceivePeer *dest_peer = find_peer(device, to_id); - if (!dest_peer) { - BLog(BLOG_INFO, "relay destination peer not known"); - goto out; - } - - // destination cannot be source - if (dest_peer == src_peer) { - BLog(BLOG_WARNING, "relay destination cannot be the source"); - goto out; - } - - relay_dest_peer = dest_peer; - } - } - -out: - // accept packet - PacketPassInterface_Done(&o->recv_if); - - // pass packet to device - if (local) { - o->device->output_func(o->device->output_func_user, data, data_len); - } - - // relay frame - if (relay_dest_peer) { - DPRelayRouter_SubmitFrame(&device->relay_router, &src_peer->relay_source, &relay_dest_peer->relay_sink, data, data_len, device->relay_flow_buffer_size, device->relay_flow_inactivity_time); - } -} - -int DPReceiveDevice_Init (DPReceiveDevice *o, int device_mtu, DPReceiveDevice_output_func output_func, void *output_func_user, BReactor *reactor, int relay_flow_buffer_size, int relay_flow_inactivity_time) -{ - ASSERT(device_mtu >= 0) - ASSERT(device_mtu <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - ASSERT(output_func) - ASSERT(relay_flow_buffer_size > 0) - - // init arguments - o->device_mtu = device_mtu; - o->output_func = output_func; - o->output_func_user = output_func_user; - o->reactor = reactor; - o->relay_flow_buffer_size = relay_flow_buffer_size; - o->relay_flow_inactivity_time = relay_flow_inactivity_time; - - // remember packet MTU - o->packet_mtu = DATAPROTO_MAX_OVERHEAD + o->device_mtu; - - // init relay router - if (!DPRelayRouter_Init(&o->relay_router, o->device_mtu, o->reactor)) { - BLog(BLOG_ERROR, "DPRelayRouter_Init failed"); - goto fail0; - } - - // have no peer ID - o->have_peer_id = 0; - - // init peers list - LinkedList1_Init(&o->peers_list); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void DPReceiveDevice_Free (DPReceiveDevice *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(LinkedList1_IsEmpty(&o->peers_list)) - - // free relay router - DPRelayRouter_Free(&o->relay_router); -} - -void DPReceiveDevice_SetPeerID (DPReceiveDevice *o, peerid_t peer_id) -{ - DebugObject_Access(&o->d_obj); - - // remember peer ID - o->peer_id = peer_id; - o->have_peer_id = 1; -} - -void DPReceivePeer_Init (DPReceivePeer *o, DPReceiveDevice *device, peerid_t peer_id, FrameDeciderPeer *decider_peer, int is_relay_client) -{ - DebugObject_Access(&device->d_obj); - ASSERT(is_relay_client == 0 || is_relay_client == 1) - - // init arguments - o->device = device; - o->peer_id = peer_id; - o->decider_peer = decider_peer; - o->is_relay_client = is_relay_client; - - // init relay source - DPRelaySource_Init(&o->relay_source, &device->relay_router, o->peer_id, device->reactor); - - // init relay sink - DPRelaySink_Init(&o->relay_sink, o->peer_id); - - // have no sink - o->dp_sink = NULL; - - // insert to peers list - LinkedList1_Append(&device->peers_list, &o->list_node); - - DebugCounter_Init(&o->d_receivers_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPReceivePeer_Free (DPReceivePeer *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_receivers_ctr); - ASSERT(!o->dp_sink) - - // remove from peers list - LinkedList1_Remove(&o->device->peers_list, &o->list_node); - - // free relay sink - DPRelaySink_Free(&o->relay_sink); - - // free relay source - DPRelaySource_Free(&o->relay_source); -} - -void DPReceivePeer_AttachSink (DPReceivePeer *o, DataProtoSink *dp_sink) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->dp_sink) - ASSERT(dp_sink) - - // attach relay sink - DPRelaySink_Attach(&o->relay_sink, dp_sink); - - o->dp_sink = dp_sink; -} - -void DPReceivePeer_DetachSink (DPReceivePeer *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->dp_sink) - - // detach relay sink - DPRelaySink_Detach(&o->relay_sink); - - o->dp_sink = NULL; -} - -void DPReceiveReceiver_Init (DPReceiveReceiver *o, DPReceivePeer *peer) -{ - DebugObject_Access(&peer->d_obj); - DPReceiveDevice *device = peer->device; - - // init arguments - o->peer = peer; - - // remember device - o->device = device; - - // init receive interface - PacketPassInterface_Init(&o->recv_if, device->packet_mtu, (PacketPassInterface_handler_send)receiver_recv_handler_send, o, BReactor_PendingGroup(device->reactor)); - - DebugCounter_Increment(&peer->d_receivers_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPReceiveReceiver_Free (DPReceiveReceiver *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->peer->d_receivers_ctr); - - // free receive interface - PacketPassInterface_Free(&o->recv_if); -} - -PacketPassInterface * DPReceiveReceiver_GetInput (DPReceiveReceiver *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->recv_if; -} diff --git a/external/badvpn_dns/client/DPReceive.h b/external/badvpn_dns/client/DPReceive.h deleted file mode 100644 index ecc5a05..0000000 --- a/external/badvpn_dns/client/DPReceive.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file DPReceive.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Receive processing for the VPN client. - */ - -#ifndef BADVPN_CLIENT_DPRECEIVE_H -#define BADVPN_CLIENT_DPRECEIVE_H - -#include <protocol/scproto.h> -#include <misc/debugcounter.h> -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <client/DataProto.h> -#include <client/DPRelay.h> -#include <client/FrameDecider.h> - -typedef void (*DPReceiveDevice_output_func) (void *output_user, uint8_t *data, int data_len); - -struct DPReceiveReceiver_s; - -typedef struct { - int device_mtu; - DPReceiveDevice_output_func output_func; - void *output_func_user; - BReactor *reactor; - int relay_flow_buffer_size; - int relay_flow_inactivity_time; - int packet_mtu; - DPRelayRouter relay_router; - int have_peer_id; - peerid_t peer_id; - LinkedList1 peers_list; - DebugObject d_obj; -} DPReceiveDevice; - -typedef struct { - DPReceiveDevice *device; - peerid_t peer_id; - FrameDeciderPeer *decider_peer; - int is_relay_client; - DPRelaySource relay_source; - DPRelaySink relay_sink; - DataProtoSink *dp_sink; - LinkedList1Node list_node; - DebugObject d_obj; - DebugCounter d_receivers_ctr; -} DPReceivePeer; - -typedef struct DPReceiveReceiver_s { - DPReceivePeer *peer; - DPReceiveDevice *device; - PacketPassInterface recv_if; - DebugObject d_obj; -} DPReceiveReceiver; - -int DPReceiveDevice_Init (DPReceiveDevice *o, int device_mtu, DPReceiveDevice_output_func output_func, void *output_func_user, BReactor *reactor, int relay_flow_buffer_size, int relay_flow_inactivity_time) WARN_UNUSED; -void DPReceiveDevice_Free (DPReceiveDevice *o); -void DPReceiveDevice_SetPeerID (DPReceiveDevice *o, peerid_t peer_id); - -void DPReceivePeer_Init (DPReceivePeer *o, DPReceiveDevice *device, peerid_t peer_id, FrameDeciderPeer *decider_peer, int is_relay_client); -void DPReceivePeer_Free (DPReceivePeer *o); -void DPReceivePeer_AttachSink (DPReceivePeer *o, DataProtoSink *dp_sink); -void DPReceivePeer_DetachSink (DPReceivePeer *o); - -void DPReceiveReceiver_Init (DPReceiveReceiver *o, DPReceivePeer *peer); -void DPReceiveReceiver_Free (DPReceiveReceiver *o); -PacketPassInterface * DPReceiveReceiver_GetInput (DPReceiveReceiver *o); - -#endif diff --git a/external/badvpn_dns/client/DPRelay.c b/external/badvpn_dns/client/DPRelay.c deleted file mode 100644 index 983e3ad..0000000 --- a/external/badvpn_dns/client/DPRelay.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - * @file DPRelay.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <base/BLog.h> - -#include <client/DPRelay.h> - -#include <generated/blog_channel_DPRelay.h> - -static void flow_inactivity_handler (struct DPRelay_flow *flow); - -static struct DPRelay_flow * create_flow (DPRelaySource *src, DPRelaySink *sink, int num_packets, int inactivity_time) -{ - ASSERT(num_packets > 0) - - // allocate structure - struct DPRelay_flow *flow = (struct DPRelay_flow *)malloc(sizeof(*flow)); - if (!flow) { - BLog(BLOG_ERROR, "relay flow %d->%d: malloc failed", (int)src->source_id, (int)sink->dest_id); - goto fail0; - } - - // set src and sink - flow->src = src; - flow->sink = sink; - - // init DataProtoFlow - if (!DataProtoFlow_Init(&flow->dp_flow, &src->router->dp_source, src->source_id, sink->dest_id, num_packets, inactivity_time, flow, (DataProtoFlow_handler_inactivity)flow_inactivity_handler)) { - BLog(BLOG_ERROR, "relay flow %d->%d: DataProtoFlow_Init failed", (int)src->source_id, (int)sink->dest_id); - goto fail1; - } - - // insert to source list - LinkedList1_Append(&src->flows_list, &flow->src_list_node); - - // insert to sink list - LinkedList1_Append(&sink->flows_list, &flow->sink_list_node); - - // attach flow if needed - if (sink->dp_sink) { - DataProtoFlow_Attach(&flow->dp_flow, sink->dp_sink); - } - - BLog(BLOG_INFO, "relay flow %d->%d: created", (int)src->source_id, (int)sink->dest_id); - - return flow; - -fail1: - free(flow); -fail0: - return NULL; -} - -static void free_flow (struct DPRelay_flow *flow) -{ - // detach flow if needed - if (flow->sink->dp_sink) { - DataProtoFlow_Detach(&flow->dp_flow); - } - - // remove posible router reference - if (flow->src->router->current_flow == flow) { - flow->src->router->current_flow = NULL; - } - - // remove from sink list - LinkedList1_Remove(&flow->sink->flows_list, &flow->sink_list_node); - - // remove from source list - LinkedList1_Remove(&flow->src->flows_list, &flow->src_list_node); - - // free DataProtoFlow - DataProtoFlow_Free(&flow->dp_flow); - - // free structore - free(flow); -} - -static void flow_inactivity_handler (struct DPRelay_flow *flow) -{ - BLog(BLOG_INFO, "relay flow %d->%d: timed out", (int)flow->src->source_id, (int)flow->sink->dest_id); - - free_flow(flow); -} - -static struct DPRelay_flow * source_find_flow (DPRelaySource *o, DPRelaySink *sink) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, src_list_node); - ASSERT(flow->src == o) - if (flow->sink == sink) { - return flow; - } - } - - return NULL; -} - -static void router_dp_source_handler (DPRelayRouter *o, const uint8_t *frame, int frame_len) -{ - DebugObject_Access(&o->d_obj); - - if (!o->current_flow) { - return; - } - - // route frame to current flow - DataProtoFlow_Route(&o->current_flow->dp_flow, 0); - - // set no current flow - o->current_flow = NULL; -} - -int DPRelayRouter_Init (DPRelayRouter *o, int frame_mtu, BReactor *reactor) -{ - ASSERT(frame_mtu >= 0) - ASSERT(frame_mtu <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - - // init arguments - o->frame_mtu = frame_mtu; - - // init BufferWriter - BufferWriter_Init(&o->writer, frame_mtu, BReactor_PendingGroup(reactor)); - - // init DataProtoSource - if (!DataProtoSource_Init(&o->dp_source, BufferWriter_GetOutput(&o->writer), (DataProtoSource_handler)router_dp_source_handler, o, reactor)) { - BLog(BLOG_ERROR, "DataProtoSource_Init failed"); - goto fail1; - } - - // have no current flow - o->current_flow = NULL; - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - BufferWriter_Free(&o->writer); - return 0; -} - -void DPRelayRouter_Free (DPRelayRouter *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - ASSERT(!o->current_flow) // have no sources - - // free DataProtoSource - DataProtoSource_Free(&o->dp_source); - - // free BufferWriter - BufferWriter_Free(&o->writer); -} - -void DPRelayRouter_SubmitFrame (DPRelayRouter *o, DPRelaySource *src, DPRelaySink *sink, uint8_t *data, int data_len, int num_packets, int inactivity_time) -{ - DebugObject_Access(&o->d_obj); - DebugObject_Access(&src->d_obj); - DebugObject_Access(&sink->d_obj); - ASSERT(!o->current_flow) - ASSERT(src->router == o) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->frame_mtu) - ASSERT(num_packets > 0) - - // get memory location - uint8_t *out; - if (!BufferWriter_StartPacket(&o->writer, &out)) { - BLog(BLOG_ERROR, "BufferWriter_StartPacket failed for frame %d->%d !?", (int)src->source_id, (int)sink->dest_id); - return; - } - - // write frame - memcpy(out, data, data_len); - - // submit frame - BufferWriter_EndPacket(&o->writer, data_len); - - // get a flow - // this comes _after_ writing the packet, in case flow initialization schedules jobs - struct DPRelay_flow *flow = source_find_flow(src, sink); - if (!flow) { - if (!(flow = create_flow(src, sink, num_packets, inactivity_time))) { - return; - } - } - - // remember flow so we know where to route the frame in router_dp_source_handler - o->current_flow = flow; -} - -void DPRelaySource_Init (DPRelaySource *o, DPRelayRouter *router, peerid_t source_id, BReactor *reactor) -{ - DebugObject_Access(&router->d_obj); - - // init arguments - o->router = router; - o->source_id = source_id; - - // init flows list - LinkedList1_Init(&o->flows_list); - - DebugCounter_Increment(&o->router->d_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPRelaySource_Free (DPRelaySource *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->router->d_ctr); - - // free flows, detaching them if needed - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&o->flows_list)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, src_list_node); - free_flow(flow); - } -} - -void DPRelaySink_Init (DPRelaySink *o, peerid_t dest_id) -{ - // init arguments - o->dest_id = dest_id; - - // init flows list - LinkedList1_Init(&o->flows_list); - - // have no sink - o->dp_sink = NULL; - - DebugObject_Init(&o->d_obj); -} - -void DPRelaySink_Free (DPRelaySink *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(!o->dp_sink) - - // free flows - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&o->flows_list)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - free_flow(flow); - } -} - -void DPRelaySink_Attach (DPRelaySink *o, DataProtoSink *dp_sink) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->dp_sink) - ASSERT(dp_sink) - - // attach flows - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - DataProtoFlow_Attach(&flow->dp_flow, dp_sink); - } - - // set sink - o->dp_sink = dp_sink; -} - -void DPRelaySink_Detach (DPRelaySink *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->dp_sink) - - // detach flows - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - DataProtoFlow_Detach(&flow->dp_flow); - } - - // set no sink - o->dp_sink = NULL; -} diff --git a/external/badvpn_dns/client/DPRelay.h b/external/badvpn_dns/client/DPRelay.h deleted file mode 100644 index c5e16eb..0000000 --- a/external/badvpn_dns/client/DPRelay.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file DPRelay.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_CLIENT_DPRELAY_H -#define BADVPN_CLIENT_DPRELAY_H - -#include <stdint.h> -#include <limits.h> - -#include <protocol/scproto.h> -#include <protocol/dataproto.h> -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <flow/BufferWriter.h> -#include <client/DataProto.h> - -struct DPRelay_flow; - -typedef struct { - int frame_mtu; - BufferWriter writer; - DataProtoSource dp_source; - struct DPRelay_flow *current_flow; - DebugObject d_obj; - DebugCounter d_ctr; -} DPRelayRouter; - -typedef struct { - DPRelayRouter *router; - peerid_t source_id; - LinkedList1 flows_list; - DebugObject d_obj; -} DPRelaySource; - -typedef struct { - peerid_t dest_id; - LinkedList1 flows_list; - DataProtoSink *dp_sink; - DebugObject d_obj; -} DPRelaySink; - -struct DPRelay_flow { - DPRelaySource *src; - DPRelaySink *sink; - DataProtoFlow dp_flow; - LinkedList1Node src_list_node; - LinkedList1Node sink_list_node; -}; - -int DPRelayRouter_Init (DPRelayRouter *o, int frame_mtu, BReactor *reactor) WARN_UNUSED; -void DPRelayRouter_Free (DPRelayRouter *o); -void DPRelayRouter_SubmitFrame (DPRelayRouter *o, DPRelaySource *src, DPRelaySink *sink, uint8_t *data, int data_len, int num_packets, int inactivity_time); - -void DPRelaySource_Init (DPRelaySource *o, DPRelayRouter *router, peerid_t source_id, BReactor *reactor); -void DPRelaySource_Free (DPRelaySource *o); - -void DPRelaySink_Init (DPRelaySink *o, peerid_t dest_id); -void DPRelaySink_Free (DPRelaySink *o); -void DPRelaySink_Attach (DPRelaySink *o, DataProtoSink *dp_sink); -void DPRelaySink_Detach (DPRelaySink *o); - -#endif diff --git a/external/badvpn_dns/client/DataProto.c b/external/badvpn_dns/client/DataProto.c deleted file mode 100644 index 255045a..0000000 --- a/external/badvpn_dns/client/DataProto.c +++ /dev/null @@ -1,566 +0,0 @@ -/** - * @file DataProto.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <protocol/dataproto.h> -#include <misc/byteorder.h> -#include <base/BLog.h> - -#include <client/DataProto.h> - -#include <generated/blog_channel_DataProto.h> - -static void monitor_handler (DataProtoSink *o); -static void refresh_up_job (DataProtoSink *o); -static void receive_timer_handler (DataProtoSink *o); -static void notifier_handler (DataProtoSink *o, uint8_t *data, int data_len); -static void up_job_handler (DataProtoSink *o); -static void flow_buffer_free (struct DataProtoFlow_buffer *b); -static void flow_buffer_attach (struct DataProtoFlow_buffer *b, DataProtoSink *sink); -static void flow_buffer_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_schedule_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_finish_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_qflow_handler_busy (struct DataProtoFlow_buffer *b); - -void monitor_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - - // send keep-alive - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); -} - -void refresh_up_job (DataProtoSink *o) -{ - if (o->up != o->up_report) { - BPending_Set(&o->up_job); - } else { - BPending_Unset(&o->up_job); - } -} - -void receive_timer_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - - // consider down - o->up = 0; - - refresh_up_job(o); -} - -void notifier_handler (DataProtoSink *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= sizeof(struct dataproto_header)) - - int flags = 0; - - // if we are receiving keepalives, set the flag - if (BTimer_IsRunning(&o->receive_timer)) { - flags |= DATAPROTO_FLAGS_RECEIVING_KEEPALIVES; - } - - // modify existing packet here - struct dataproto_header header; - memcpy(&header, data, sizeof(header)); - header.flags = hton8(flags); - memcpy(data, &header, sizeof(header)); -} - -void up_job_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up != o->up_report) - - o->up_report = o->up; - - o->handler(o->user, o->up); - return; -} - -void source_router_handler (DataProtoSource *o, uint8_t *buf, int recv_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(buf) - ASSERT(recv_len >= 0) - ASSERT(recv_len <= o->frame_mtu) - - // remember packet - o->current_buf = buf; - o->current_recv_len = recv_len; - - // call handler - o->handler(o->user, buf + DATAPROTO_MAX_OVERHEAD, recv_len); - return; -} - -void flow_buffer_free (struct DataProtoFlow_buffer *b) -{ - ASSERT(!b->sink) - - // free route buffer - RouteBuffer_Free(&b->rbuf); - - // free inactivity monitor - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Free(&b->monitor); - } - - // free connector - PacketPassConnector_Free(&b->connector); - - // free buffer structure - free(b); -} - -void flow_buffer_attach (struct DataProtoFlow_buffer *b, DataProtoSink *sink) -{ - ASSERT(!b->sink) - - // init queue flow - PacketPassFairQueueFlow_Init(&b->sink_qflow, &sink->queue); - - // connect to queue flow - PacketPassConnector_ConnectOutput(&b->connector, PacketPassFairQueueFlow_GetInput(&b->sink_qflow)); - - // set DataProto - b->sink = sink; -} - -void flow_buffer_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - // disconnect from queue flow - PacketPassConnector_DisconnectOutput(&b->connector); - - // free queue flow - PacketPassFairQueueFlow_Free(&b->sink_qflow); - - // clear reference to this buffer in the sink - if (b->sink->detaching_buffer == b) { - b->sink->detaching_buffer = NULL; - } - - // set no DataProto - b->sink = NULL; -} - -void flow_buffer_schedule_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) - ASSERT(!b->sink->detaching_buffer || b->sink->detaching_buffer == b) - - if (b->sink->detaching_buffer == b) { - return; - } - - // request cancel - PacketPassFairQueueFlow_RequestCancel(&b->sink_qflow); - - // set busy handler - PacketPassFairQueueFlow_SetBusyHandler(&b->sink_qflow, (PacketPassFairQueue_handler_busy)flow_buffer_qflow_handler_busy, b); - - // remember this buffer in the sink so it can handle us if it goes away - b->sink->detaching_buffer = b; -} - -void flow_buffer_finish_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(b->sink->detaching_buffer == b) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - // detach - flow_buffer_detach(b); - - if (!b->flow) { - // free - flow_buffer_free(b); - } else if (b->flow->sink_desired) { - // attach - flow_buffer_attach(b, b->flow->sink_desired); - } -} - -void flow_buffer_qflow_handler_busy (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(b->sink->detaching_buffer == b) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - flow_buffer_finish_detach(b); -} - -int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface *output, btime_t keepalive_time, btime_t tolerance_time, DataProtoSink_handler handler, void *user) -{ - ASSERT(PacketPassInterface_HasCancel(output)) - ASSERT(PacketPassInterface_GetMTU(output) >= DATAPROTO_MAX_OVERHEAD) - - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // set frame MTU - o->frame_mtu = PacketPassInterface_GetMTU(output) - DATAPROTO_MAX_OVERHEAD; - - // init notifier - PacketPassNotifier_Init(&o->notifier, output, BReactor_PendingGroup(o->reactor)); - PacketPassNotifier_SetHandler(&o->notifier, (PacketPassNotifier_handler_notify)notifier_handler, o); - - // init monitor - PacketPassInactivityMonitor_Init(&o->monitor, PacketPassNotifier_GetInput(&o->notifier), o->reactor, keepalive_time, (PacketPassInactivityMonitor_handler)monitor_handler, o); - PacketPassInactivityMonitor_Force(&o->monitor); - - // init queue - if (!PacketPassFairQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->monitor), BReactor_PendingGroup(o->reactor), 1, 1)) { - BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed"); - goto fail1; - } - - // init keepalive queue flow - PacketPassFairQueueFlow_Init(&o->ka_qflow, &o->queue); - - // init keepalive source - DataProtoKeepaliveSource_Init(&o->ka_source, BReactor_PendingGroup(o->reactor)); - - // init keepalive blocker - PacketRecvBlocker_Init(&o->ka_blocker, DataProtoKeepaliveSource_GetOutput(&o->ka_source), BReactor_PendingGroup(o->reactor)); - - // init keepalive buffer - if (!SinglePacketBuffer_Init(&o->ka_buffer, PacketRecvBlocker_GetOutput(&o->ka_blocker), PacketPassFairQueueFlow_GetInput(&o->ka_qflow), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init receive timer - BTimer_Init(&o->receive_timer, tolerance_time, (BTimer_handler)receive_timer_handler, o); - - // init handler job - BPending_Init(&o->up_job, BReactor_PendingGroup(o->reactor), (BPending_handler)up_job_handler, o); - - // set not up - o->up = 0; - o->up_report = 0; - - // set no detaching buffer - o->detaching_buffer = NULL; - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - PacketRecvBlocker_Free(&o->ka_blocker); - DataProtoKeepaliveSource_Free(&o->ka_source); - PacketPassFairQueueFlow_Free(&o->ka_qflow); - PacketPassFairQueue_Free(&o->queue); -fail1: - PacketPassInactivityMonitor_Free(&o->monitor); - PacketPassNotifier_Free(&o->notifier); - return 0; -} - -void DataProtoSink_Free (DataProtoSink *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - - // allow freeing queue flows - PacketPassFairQueue_PrepareFree(&o->queue); - - // release detaching buffer - if (o->detaching_buffer) { - ASSERT(!o->detaching_buffer->flow || o->detaching_buffer->flow->sink_desired != o) - flow_buffer_finish_detach(o->detaching_buffer); - } - - // free handler job - BPending_Free(&o->up_job); - - // free receive timer - BReactor_RemoveTimer(o->reactor, &o->receive_timer); - - // free keepalive buffer - SinglePacketBuffer_Free(&o->ka_buffer); - - // free keepalive blocker - PacketRecvBlocker_Free(&o->ka_blocker); - - // free keepalive source - DataProtoKeepaliveSource_Free(&o->ka_source); - - // free keepalive queue flow - PacketPassFairQueueFlow_Free(&o->ka_qflow); - - // free queue - PacketPassFairQueue_Free(&o->queue); - - // free monitor - PacketPassInactivityMonitor_Free(&o->monitor); - - // free notifier - PacketPassNotifier_Free(&o->notifier); -} - -void DataProtoSink_Received (DataProtoSink *o, int peer_receiving) -{ - ASSERT(peer_receiving == 0 || peer_receiving == 1) - DebugObject_Access(&o->d_obj); - - // reset receive timer - BReactor_SetTimer(o->reactor, &o->receive_timer); - - if (!peer_receiving) { - // peer reports not receiving, consider down - o->up = 0; - // send keep-alive to converge faster - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); - } else { - // consider up - o->up = 1; - } - - refresh_up_job(o); -} - -int DataProtoSource_Init (DataProtoSource *o, PacketRecvInterface *input, DataProtoSource_handler handler, void *user, BReactor *reactor) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - ASSERT(handler) - - // init arguments - o->handler = handler; - o->user = user; - o->reactor = reactor; - - // remember frame MTU - o->frame_mtu = PacketRecvInterface_GetMTU(input); - - // init router - if (!PacketRouter_Init(&o->router, DATAPROTO_MAX_OVERHEAD + o->frame_mtu, DATAPROTO_MAX_OVERHEAD, input, (PacketRouter_handler)source_router_handler, o, BReactor_PendingGroup(reactor))) { - BLog(BLOG_ERROR, "PacketRouter_Init failed"); - goto fail0; - } - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void DataProtoSource_Free (DataProtoSource *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - - // free router - PacketRouter_Free(&o->router); -} - -int DataProtoFlow_Init (DataProtoFlow *o, DataProtoSource *source, peerid_t source_id, peerid_t dest_id, int num_packets, int inactivity_time, void *user, - DataProtoFlow_handler_inactivity handler_inactivity) -{ - DebugObject_Access(&source->d_obj); - ASSERT(num_packets > 0) - ASSERT(!(inactivity_time >= 0) || handler_inactivity) - - // init arguments - o->source = source; - o->source_id = source_id; - o->dest_id = dest_id; - - // set no desired sink - o->sink_desired = NULL; - - // allocate buffer structure - struct DataProtoFlow_buffer *b = (struct DataProtoFlow_buffer *)malloc(sizeof(*b)); - if (!b) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - o->b = b; - - // set parent - b->flow = o; - - // remember inactivity time - b->inactivity_time = inactivity_time; - - // init connector - PacketPassConnector_Init(&b->connector, DATAPROTO_MAX_OVERHEAD + source->frame_mtu, BReactor_PendingGroup(source->reactor)); - - // init inactivity monitor - PacketPassInterface *buf_out = PacketPassConnector_GetInput(&b->connector); - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Init(&b->monitor, buf_out, source->reactor, b->inactivity_time, handler_inactivity, user); - buf_out = PacketPassInactivityMonitor_GetInput(&b->monitor); - } - - // init route buffer - if (!RouteBuffer_Init(&b->rbuf, DATAPROTO_MAX_OVERHEAD + source->frame_mtu, buf_out, num_packets)) { - BLog(BLOG_ERROR, "RouteBuffer_Init failed"); - goto fail1; - } - - // set no sink - b->sink = NULL; - - DebugCounter_Increment(&source->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Free(&b->monitor); - } - PacketPassConnector_Free(&b->connector); - free(b); -fail0: - return 0; -} - -void DataProtoFlow_Free (DataProtoFlow *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->source->d_ctr); - ASSERT(!o->sink_desired) - struct DataProtoFlow_buffer *b = o->b; - - if (b->sink) { - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach, free buffer after detach - flow_buffer_schedule_detach(b); - b->flow = NULL; - - // remove inactivity handler - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_SetHandler(&b->monitor, NULL, NULL); - } - } else { - // detach and free buffer now - flow_buffer_detach(b); - flow_buffer_free(b); - } - } else { - // free buffer - flow_buffer_free(b); - } -} - -void DataProtoFlow_Route (DataProtoFlow *o, int more) -{ - DebugObject_Access(&o->d_obj); - PacketRouter_AssertRoute(&o->source->router); - ASSERT(o->source->current_buf) - ASSERT(more == 0 || more == 1) - struct DataProtoFlow_buffer *b = o->b; - - // write header. Don't set flags, it will be set in notifier_handler. - struct dataproto_header header; - struct dataproto_peer_id id; - header.from_id = htol16(o->source_id); - header.num_peer_ids = htol16(1); - id.id = htol16(o->dest_id); - memcpy(o->source->current_buf, &header, sizeof(header)); - memcpy(o->source->current_buf + sizeof(header), &id, sizeof(id)); - - // route - uint8_t *next_buf; - if (!PacketRouter_Route(&o->source->router, DATAPROTO_MAX_OVERHEAD + o->source->current_recv_len, &b->rbuf, - &next_buf, DATAPROTO_MAX_OVERHEAD, (more ? o->source->current_recv_len : 0) - )) { - BLog(BLOG_NOTICE, "buffer full: %d->%d", (int)o->source_id, (int)o->dest_id); - return; - } - - // remember next buffer, or don't allow further routing if more==0 - o->source->current_buf = (more ? next_buf : NULL); -} - -void DataProtoFlow_Attach (DataProtoFlow *o, DataProtoSink *sink) -{ - DebugObject_Access(&o->d_obj); - DebugObject_Access(&sink->d_obj); - ASSERT(!o->sink_desired) - ASSERT(sink) - ASSERT(o->source->frame_mtu <= sink->frame_mtu) - struct DataProtoFlow_buffer *b = o->b; - - if (b->sink) { - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach and reattach - flow_buffer_schedule_detach(b); - } else { - // detach and reattach now - flow_buffer_detach(b); - flow_buffer_attach(b, sink); - } - } else { - // attach - flow_buffer_attach(b, sink); - } - - // set desired sink - o->sink_desired = sink; - - DebugCounter_Increment(&sink->d_ctr); -} - -void DataProtoFlow_Detach (DataProtoFlow *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->sink_desired) - struct DataProtoFlow_buffer *b = o->b; - ASSERT(b->sink) - - DataProtoSink *sink = o->sink_desired; - - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach - flow_buffer_schedule_detach(b); - } else { - // detach now - flow_buffer_detach(b); - } - - // set no desired sink - o->sink_desired = NULL; - - DebugCounter_Decrement(&sink->d_ctr); -} diff --git a/external/badvpn_dns/client/DataProto.h b/external/badvpn_dns/client/DataProto.h deleted file mode 100644 index 0da3a20..0000000 --- a/external/badvpn_dns/client/DataProto.h +++ /dev/null @@ -1,237 +0,0 @@ -/** - * @file DataProto.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Mudule for frame sending used in the VPN client program. - */ - -#ifndef BADVPN_CLIENT_DATAPROTO_H -#define BADVPN_CLIENT_DATAPROTO_H - -#include <stdint.h> - -#include <misc/debugcounter.h> -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <flow/PacketPassFairQueue.h> -#include <flow/PacketPassNotifier.h> -#include <flow/PacketRecvBlocker.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketPassConnector.h> -#include <flow/PacketRouter.h> -#include <flowextra/PacketPassInactivityMonitor.h> -#include <client/DataProtoKeepaliveSource.h> - -typedef void (*DataProtoSink_handler) (void *user, int up); -typedef void (*DataProtoSource_handler) (void *user, const uint8_t *frame, int frame_len); -typedef void (*DataProtoFlow_handler_inactivity) (void *user); - -struct DataProtoFlow_buffer; - -/** - * Frame destination. - * Represents a peer as a destination for sending frames to. - */ -typedef struct { - BReactor *reactor; - int frame_mtu; - PacketPassFairQueue queue; - PacketPassInactivityMonitor monitor; - PacketPassNotifier notifier; - DataProtoKeepaliveSource ka_source; - PacketRecvBlocker ka_blocker; - SinglePacketBuffer ka_buffer; - PacketPassFairQueueFlow ka_qflow; - BTimer receive_timer; - int up; - int up_report; - DataProtoSink_handler handler; - void *user; - BPending up_job; - struct DataProtoFlow_buffer *detaching_buffer; - DebugObject d_obj; - DebugCounter d_ctr; -} DataProtoSink; - -/** - * Receives frames from a {@link PacketRecvInterface} input and - * allows the user to route them to buffers in {@link DataProtoFlow}'s. - */ -typedef struct { - DataProtoSource_handler handler; - void *user; - BReactor *reactor; - int frame_mtu; - PacketRouter router; - uint8_t *current_buf; - int current_recv_len; - DebugObject d_obj; - DebugCounter d_ctr; -} DataProtoSource; - -/** - * Contains a buffer for frames from a specific peer to a specific peer. - * Receives frames from a {@link DataProtoSource} as routed by the user. - * Can be attached to a {@link DataProtoSink} to send out frames. - */ -typedef struct { - DataProtoSource *source; - peerid_t source_id; - peerid_t dest_id; - DataProtoSink *sink_desired; - struct DataProtoFlow_buffer *b; - DebugObject d_obj; -} DataProtoFlow; - -struct DataProtoFlow_buffer { - DataProtoFlow *flow; - int inactivity_time; - RouteBuffer rbuf; - PacketPassInactivityMonitor monitor; - PacketPassConnector connector; - DataProtoSink *sink; - PacketPassFairQueueFlow sink_qflow; -}; - -/** - * Initializes the sink. - * - * @param o the object - * @param reactor reactor we live in - * @param output output interface. Must support cancel functionality. Its MTU must be - * >=DATAPROTO_MAX_OVERHEAD. - * @param keepalive_time keepalive time - * @param tolerance_time after how long of not having received anything from the peer - * to consider the link down - * @param handler up state handler - * @param user value to pass to handler - * @return 1 on success, 0 on failure - */ -int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface *output, btime_t keepalive_time, btime_t tolerance_time, DataProtoSink_handler handler, void *user) WARN_UNUSED; - -/** - * Frees the sink. - * There must be no local sources attached. - * - * @param o the object - */ -void DataProtoSink_Free (DataProtoSink *o); - -/** - * Notifies the sink that a packet was received from the peer. - * Must not be in freeing state. - * - * @param o the object - * @param peer_receiving whether the DATAPROTO_FLAGS_RECEIVING_KEEPALIVES flag was set in the packet. - * Must be 0 or 1. - */ -void DataProtoSink_Received (DataProtoSink *o, int peer_receiving); - -/** - * Initiazes the source. - * - * @param o the object - * @param input frame input. Its input MTU must be <= INT_MAX - DATAPROTO_MAX_OVERHEAD. - * @param handler handler called when a frame arrives to allow the user to route it to - * appropriate {@link DataProtoFlow}'s. - * @param user value passed to handler - * @param reactor reactor we live in - * @return 1 on success, 0 on failure - */ -int DataProtoSource_Init (DataProtoSource *o, PacketRecvInterface *input, DataProtoSource_handler handler, void *user, BReactor *reactor) WARN_UNUSED; - -/** - * Frees the source. - * There must be no {@link DataProtoFlow}'s using this source. - * - * @param o the object - */ -void DataProtoSource_Free (DataProtoSource *o); - -/** - * Initializes the flow. - * The flow is initialized in not attached state. - * - * @param o the object - * @param source source to receive frames from - * @param source_id source peer ID to encode in the headers (i.e. our ID) - * @param dest_id destination peer ID to encode in the headers (i.e. ID if the peer this - * flow belongs to) - * @param num_packets number of packets the buffer should hold. Must be >0. - * @param inactivity_time milliseconds of output inactivity after which to call the - * inactivity handler; <0 to disable. Note that the flow is considered - * active as long as its buffer is non-empty, even if is not attached to - * a {@link DataProtoSink}. - * @param user value to pass to handler - * @param handler_inactivity inactivity handler, if inactivity_time >=0 - * @return 1 on success, 0 on failure - */ -int DataProtoFlow_Init (DataProtoFlow *o, DataProtoSource *source, peerid_t source_id, peerid_t dest_id, int num_packets, int inactivity_time, void *user, - DataProtoFlow_handler_inactivity handler_inactivity) WARN_UNUSED; - -/** - * Frees the flow. - * The flow must be in not attached state. - * - * @param o the object - */ -void DataProtoFlow_Free (DataProtoFlow *o); - -/** - * Routes a frame from the flow's source to this flow. - * Must be called from within the job context of the {@link DataProtoSource_handler} handler. - * Must not be called after this has been called with more=0 for the current frame. - * - * @param o the object - * @param more whether the current frame may have to be routed to more - * flows. If 0, must not be called again until the handler is - * called for the next frame. Must be 0 or 1. - */ -void DataProtoFlow_Route (DataProtoFlow *o, int more); - -/** - * Attaches the flow to a sink. - * The flow must be in not attached state. - * - * @param o the object - * @param sink sink to attach to. This flow's frame_mtu must be <= - * (output MTU of sink) - DATAPROTO_MAX_OVERHEAD. - */ -void DataProtoFlow_Attach (DataProtoFlow *o, DataProtoSink *sink); - -/** - * Detaches the flow from a destination. - * The flow must be in attached state. - * - * @param o the object - */ -void DataProtoFlow_Detach (DataProtoFlow *o); - -#endif diff --git a/external/badvpn_dns/client/DataProtoKeepaliveSource.c b/external/badvpn_dns/client/DataProtoKeepaliveSource.c deleted file mode 100644 index 834c42f..0000000 --- a/external/badvpn_dns/client/DataProtoKeepaliveSource.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file DataProtoKeepaliveSource.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <protocol/dataproto.h> -#include <misc/byteorder.h> - -#include "DataProtoKeepaliveSource.h" - -static void output_handler_recv (DataProtoKeepaliveSource *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - struct dataproto_header header; - header.flags = htol8(0); - header.from_id = htol16(0); - header.num_peer_ids = htol16(0); - memcpy(data, &header, sizeof(header)); - - // finish packet - PacketRecvInterface_Done(&o->output, sizeof(struct dataproto_header)); -} - -void DataProtoKeepaliveSource_Init (DataProtoKeepaliveSource *o, BPendingGroup *pg) -{ - // init output - PacketRecvInterface_Init(&o->output, sizeof(struct dataproto_header), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DataProtoKeepaliveSource_Free (DataProtoKeepaliveSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * DataProtoKeepaliveSource_GetOutput (DataProtoKeepaliveSource *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/client/DataProtoKeepaliveSource.h b/external/badvpn_dns/client/DataProtoKeepaliveSource.h deleted file mode 100644 index 4488e24..0000000 --- a/external/badvpn_dns/client/DataProtoKeepaliveSource.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file DataProtoKeepaliveSource.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketRecvInterface} source which provides DataProto keepalive packets. - */ - -#ifndef BADVPN_DATAPROTOKEEPALIVESOURCE_H -#define BADVPN_DATAPROTOKEEPALIVESOURCE_H - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * A {@link PacketRecvInterface} source which provides DataProto keepalive packets. - * These packets have no payload, no destination peers and flags zero. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface output; -} DataProtoKeepaliveSource; - -/** - * Initializes the object. - * - * @param o the object - * @param pg pending group - */ -void DataProtoKeepaliveSource_Init (DataProtoKeepaliveSource *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void DataProtoKeepaliveSource_Free (DataProtoKeepaliveSource *o); - -/** - * Returns the output interface. - * The MTU of the output interface will be sizeof(struct dataproto_header). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * DataProtoKeepaliveSource_GetOutput (DataProtoKeepaliveSource *o); - -#endif diff --git a/external/badvpn_dns/client/DatagramPeerIO.c b/external/badvpn_dns/client/DatagramPeerIO.c deleted file mode 100644 index e3a8f68..0000000 --- a/external/badvpn_dns/client/DatagramPeerIO.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @file DatagramPeerIO.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <client/DatagramPeerIO.h> - -#include <generated/blog_channel_DatagramPeerIO.h> - -#define DATAGRAMPEERIO_MODE_NONE 0 -#define DATAGRAMPEERIO_MODE_CONNECT 1 -#define DATAGRAMPEERIO_MODE_BIND 2 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void init_io (DatagramPeerIO *o); -static void free_io (DatagramPeerIO *o); -static void dgram_handler (DatagramPeerIO *o, int event); -static void reset_mode (DatagramPeerIO *o); -static void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len); - -void init_io (DatagramPeerIO *o) -{ - // init dgram recv interface - BDatagram_RecvAsync_Init(&o->dgram, o->effective_socket_mtu); - - // connect source - PacketRecvConnector_ConnectInput(&o->recv_connector, BDatagram_RecvAsync_GetIf(&o->dgram)); - - // init dgram send interface - BDatagram_SendAsync_Init(&o->dgram, o->effective_socket_mtu); - - // connect sink - PacketPassConnector_ConnectOutput(&o->send_connector, BDatagram_SendAsync_GetIf(&o->dgram)); -} - -void free_io (DatagramPeerIO *o) -{ - // disconnect sink - PacketPassConnector_DisconnectOutput(&o->send_connector); - - // free dgram send interface - BDatagram_SendAsync_Free(&o->dgram); - - // disconnect source - PacketRecvConnector_DisconnectInput(&o->recv_connector); - - // free dgram recv interface - BDatagram_RecvAsync_Free(&o->dgram); -} - -void dgram_handler (DatagramPeerIO *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND) - - PeerLog(o, BLOG_NOTICE, "error"); - - // reset mode - reset_mode(o); - - // report error - if (o->handler_error) { - o->handler_error(o->user); - return; - } -} - -void reset_mode (DatagramPeerIO *o) -{ - ASSERT(o->mode == DATAGRAMPEERIO_MODE_NONE || o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND) - - if (o->mode == DATAGRAMPEERIO_MODE_NONE) { - return; - } - - // remove recv notifier handler - PacketPassNotifier_SetHandler(&o->recv_notifier, NULL, NULL); - - // free I/O - free_io(o); - - // free datagram object - BDatagram_Free(&o->dgram); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_NONE; -} - -void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len) -{ - ASSERT(o->mode == DATAGRAMPEERIO_MODE_BIND) - DebugObject_Access(&o->d_obj); - - // obtain addresses from last received packet - BAddr addr; - BIPAddr local_addr; - ASSERT_EXECUTE(BDatagram_GetLastReceiveAddrs(&o->dgram, &addr, &local_addr)) - - // check address family just in case - if (!BDatagram_AddressFamilySupported(addr.type)) { - PeerLog(o, BLOG_ERROR, "unsupported receive address"); - return; - } - - // update addresses - BDatagram_SetSendAddrs(&o->dgram, addr, local_addr); -} - -int DatagramPeerIO_Init ( - DatagramPeerIO *o, - BReactor *reactor, - int payload_mtu, - int socket_mtu, - struct spproto_security_params sp_params, - btime_t latency, - int num_frames, - PacketPassInterface *recv_userif, - int otp_warning_count, - BThreadWorkDispatcher *twd, - void *user, - BLog_logfunc logfunc, - DatagramPeerIO_handler_error handler_error, - DatagramPeerIO_handler_otp_warning handler_otp_warning, - DatagramPeerIO_handler_otp_ready handler_otp_ready -) -{ - ASSERT(payload_mtu >= 0) - ASSERT(socket_mtu >= 0) - spproto_assert_security_params(sp_params); - ASSERT(num_frames > 0) - ASSERT(PacketPassInterface_GetMTU(recv_userif) >= payload_mtu) - if (SPPROTO_HAVE_OTP(sp_params)) { - ASSERT(otp_warning_count > 0) - ASSERT(otp_warning_count <= sp_params.otp_num) - } - - // set parameters - o->reactor = reactor; - o->payload_mtu = payload_mtu; - o->sp_params = sp_params; - o->user = user; - o->logfunc = logfunc; - o->handler_error = handler_error; - - // check num frames (for FragmentProtoAssembler) - if (num_frames >= FPA_MAX_TIME) { - PeerLog(o, BLOG_ERROR, "num_frames is too big"); - goto fail0; - } - - // check payload MTU (for FragmentProto) - if (o->payload_mtu > UINT16_MAX) { - PeerLog(o, BLOG_ERROR, "payload MTU is too big"); - goto fail0; - } - - // calculate SPProto payload MTU - if ((o->spproto_payload_mtu = spproto_payload_mtu_for_carrier_mtu(o->sp_params, socket_mtu)) <= (int)sizeof(struct fragmentproto_chunk_header)) { - PeerLog(o, BLOG_ERROR, "socket MTU is too small"); - goto fail0; - } - - // calculate effective socket MTU - if ((o->effective_socket_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->spproto_payload_mtu)) < 0) { - PeerLog(o, BLOG_ERROR, "spproto_carrier_mtu_for_payload_mtu failed !?"); - goto fail0; - } - - // init receiving - - // init assembler - if (!FragmentProtoAssembler_Init(&o->recv_assembler, o->spproto_payload_mtu, recv_userif, num_frames, fragmentproto_max_chunks_for_frame(o->spproto_payload_mtu, o->payload_mtu), - BReactor_PendingGroup(o->reactor), o->user, o->logfunc - )) { - PeerLog(o, BLOG_ERROR, "FragmentProtoAssembler_Init failed"); - goto fail0; - } - - // init notifier - PacketPassNotifier_Init(&o->recv_notifier, FragmentProtoAssembler_GetInput(&o->recv_assembler), BReactor_PendingGroup(o->reactor)); - - // init decoder - if (!SPProtoDecoder_Init(&o->recv_decoder, PacketPassNotifier_GetInput(&o->recv_notifier), o->sp_params, 2, BReactor_PendingGroup(o->reactor), twd, o->user, o->logfunc)) { - PeerLog(o, BLOG_ERROR, "SPProtoDecoder_Init failed"); - goto fail1; - } - SPProtoDecoder_SetHandlers(&o->recv_decoder, handler_otp_ready, user); - - // init connector - PacketRecvConnector_Init(&o->recv_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->recv_buffer, PacketRecvConnector_GetOutput(&o->recv_connector), SPProtoDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init sending base - - // init disassembler - FragmentProtoDisassembler_Init(&o->send_disassembler, o->reactor, o->payload_mtu, o->spproto_payload_mtu, -1, latency); - - // init encoder - if (!SPProtoEncoder_Init(&o->send_encoder, FragmentProtoDisassembler_GetOutput(&o->send_disassembler), o->sp_params, otp_warning_count, BReactor_PendingGroup(o->reactor), twd)) { - PeerLog(o, BLOG_ERROR, "SPProtoEncoder_Init failed"); - goto fail3; - } - SPProtoEncoder_SetHandlers(&o->send_encoder, handler_otp_warning, user); - - // init connector - PacketPassConnector_Init(&o->send_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->send_buffer, SPProtoEncoder_GetOutput(&o->send_encoder), PacketPassConnector_GetInput(&o->send_connector), BReactor_PendingGroup(o->reactor))) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail4; - } - - // set mode - o->mode = DATAGRAMPEERIO_MODE_NONE; - - DebugObject_Init(&o->d_obj); - return 1; - -fail4: - PacketPassConnector_Free(&o->send_connector); - SPProtoEncoder_Free(&o->send_encoder); -fail3: - FragmentProtoDisassembler_Free(&o->send_disassembler); - SinglePacketBuffer_Free(&o->recv_buffer); -fail2: - PacketRecvConnector_Free(&o->recv_connector); - SPProtoDecoder_Free(&o->recv_decoder); -fail1: - PacketPassNotifier_Free(&o->recv_notifier); - FragmentProtoAssembler_Free(&o->recv_assembler); -fail0: - return 0; -} - -void DatagramPeerIO_Free (DatagramPeerIO *o) -{ - DebugObject_Free(&o->d_obj); - - // reset mode - reset_mode(o); - - // free sending base - SinglePacketBuffer_Free(&o->send_buffer); - PacketPassConnector_Free(&o->send_connector); - SPProtoEncoder_Free(&o->send_encoder); - FragmentProtoDisassembler_Free(&o->send_disassembler); - - // free receiving - SinglePacketBuffer_Free(&o->recv_buffer); - PacketRecvConnector_Free(&o->recv_connector); - SPProtoDecoder_Free(&o->recv_decoder); - PacketPassNotifier_Free(&o->recv_notifier); - FragmentProtoAssembler_Free(&o->recv_assembler); -} - -PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o) -{ - DebugObject_Access(&o->d_obj); - - return FragmentProtoDisassembler_GetInput(&o->send_disassembler); -} - -int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - - // reset mode - reset_mode(o); - - // check address - if (!BDatagram_AddressFamilySupported(addr.type)) { - PeerLog(o, BLOG_ERROR, "BDatagram_AddressFamilySupported failed"); - goto fail0; - } - - // init dgram - if (!BDatagram_Init(&o->dgram, addr.type, o->reactor, o, (BDatagram_handler)dgram_handler)) { - PeerLog(o, BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // set send address - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, addr, local_addr); - - // init I/O - init_io(o); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_CONNECT; - - return 1; - -fail0: - return 0; -} - -int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - ASSERT(BDatagram_AddressFamilySupported(addr.type)) - - // reset mode - reset_mode(o); - - // init dgram - if (!BDatagram_Init(&o->dgram, addr.type, o->reactor, o, (BDatagram_handler)dgram_handler)) { - PeerLog(o, BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // bind dgram - if (!BDatagram_Bind(&o->dgram, addr)) { - PeerLog(o, BLOG_INFO, "BDatagram_Bind failed"); - goto fail1; - } - - // init I/O - init_io(o); - - // set recv notifier handler - PacketPassNotifier_SetHandler(&o->recv_notifier, (PacketPassNotifier_handler_notify)recv_decoder_notifier_handler, o); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_BIND; - - return 1; - -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // set sending key - SPProtoEncoder_SetEncryptionKey(&o->send_encoder, encryption_key); - - // set receiving key - SPProtoDecoder_SetEncryptionKey(&o->recv_decoder, encryption_key); -} - -void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove sending key - SPProtoEncoder_RemoveEncryptionKey(&o->send_encoder); - - // remove receiving key - SPProtoDecoder_RemoveEncryptionKey(&o->recv_decoder); -} - -void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // set sending seed - SPProtoEncoder_SetOTPSeed(&o->send_encoder, seed_id, key, iv); -} - -void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove sending seed - SPProtoEncoder_RemoveOTPSeed(&o->send_encoder); -} - -void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // add receiving seed - SPProtoDecoder_AddOTPSeed(&o->recv_decoder, seed_id, key, iv); -} - -void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove receiving seeds - SPProtoDecoder_RemoveOTPSeeds(&o->recv_decoder); -} diff --git a/external/badvpn_dns/client/DatagramPeerIO.h b/external/badvpn_dns/client/DatagramPeerIO.h deleted file mode 100644 index 5d19b5a..0000000 --- a/external/badvpn_dns/client/DatagramPeerIO.h +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file DatagramPeerIO.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object for comminicating with a peer using a datagram socket. - */ - -#ifndef BADVPN_CLIENT_DATAGRAMPEERIO_H -#define BADVPN_CLIENT_DATAGRAMPEERIO_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <protocol/spproto.h> -#include <protocol/fragmentproto.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BAddr.h> -#include <system/BDatagram.h> -#include <system/BTime.h> -#include <flow/PacketPassInterface.h> -#include <flow/PacketPassConnector.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketRecvConnector.h> -#include <flow/PacketPassNotifier.h> -#include <client/FragmentProtoDisassembler.h> -#include <client/FragmentProtoAssembler.h> -#include <client/SPProtoEncoder.h> -#include <client/SPProtoDecoder.h> - -/** - * Callback function invoked when an error occurs with the peer connection. - * The object has entered default state. - * May be called from within a sending Send call. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_error) (void *user); - -/** - * Handler function invoked when the number of used OTPs has reached - * the specified warning number in {@link DatagramPeerIO_SetOTPWarningHandler}. - * May be called from within a sending Send call. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_otp_warning) (void *user); - -/** - * Handler called when OTP generation for a new receive seed is finished. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_otp_ready) (void *user); - -/** - * Object for comminicating with a peer using a datagram socket. - * - * The user provides data for sending to the peer through {@link PacketPassInterface}. - * Received data is provided to the user through {@link PacketPassInterface}. - * - * The object has a logical state called a mode, which is one of the following: - * - default - nothing is send or received - * - connecting - an address was provided by the user for sending datagrams to. - * Datagrams are being sent to that address through a socket, - * and datagrams are being received on the same socket. - * - binding - an address was provided by the user to bind a socket to. - * Datagrams are being received on the socket. Datagrams are not being - * sent initially. When a datagram is received, its source address is - * used as a destination address for sending datagrams. - */ -typedef struct { - DebugObject d_obj; - BReactor *reactor; - int payload_mtu; - struct spproto_security_params sp_params; - void *user; - BLog_logfunc logfunc; - DatagramPeerIO_handler_error handler_error; - int spproto_payload_mtu; - int effective_socket_mtu; - - // sending base - FragmentProtoDisassembler send_disassembler; - SPProtoEncoder send_encoder; - SinglePacketBuffer send_buffer; - PacketPassConnector send_connector; - - // receiving - PacketRecvConnector recv_connector; - SinglePacketBuffer recv_buffer; - SPProtoDecoder recv_decoder; - PacketPassNotifier recv_notifier; - FragmentProtoAssembler recv_assembler; - - // mode - int mode; - - // datagram object - BDatagram dgram; -} DatagramPeerIO; - -/** - * Initializes the object. - * The interface is initialized in default mode. - * {@link BLog_Init} must have been done. - * {@link BNetwork_GlobalInit} must have been done. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param reactor {@link BReactor} we live in - * @param payload_mtu maximum payload size. Must be >=0. - * @param socket_mtu maximum datagram size for the socket. Must be >=0. Must be large enough so it is possible to - * send a FragmentProto chunk with one byte of data over SPProto, i.e. the following has to hold: - * spproto_payload_mtu_for_carrier_mtu(sp_params, socket_mtu) > sizeof(struct fragmentproto_chunk_header) - * @param sp_params SPProto security parameters - * @param latency latency parameter to {@link FragmentProtoDisassembler_Init}. - * @param num_frames num_frames parameter to {@link FragmentProtoAssembler_Init}. Must be >0. - * @param recv_userif interface to pass received packets to the user. Its MTU must be >=payload_mtu. - * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler. - * In this case, must be >0 and <=sp_params.otp_num. - * @param twd thread work dispatcher - * @param user value to pass to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @param handler_error error handler - * @param handler_otp_warning OTP warning handler - * @param handler_otp_ready handler called when OTP generation for a new receive seed is finished - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Init ( - DatagramPeerIO *o, - BReactor *reactor, - int payload_mtu, - int socket_mtu, - struct spproto_security_params sp_params, - btime_t latency, - int num_frames, - PacketPassInterface *recv_userif, - int otp_warning_count, - BThreadWorkDispatcher *twd, - void *user, - BLog_logfunc logfunc, - DatagramPeerIO_handler_error handler_error, - DatagramPeerIO_handler_otp_warning handler_otp_warning, - DatagramPeerIO_handler_otp_ready handler_otp_ready -) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void DatagramPeerIO_Free (DatagramPeerIO *o); - -/** - * Returns an interface the user should use to send packets. - * The OTP warning handler may be called from within Send calls - * to the interface. - * - * @param o the object - * @return sending interface - */ -PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o); - -/** - * Attempts to establish connection to the peer which has bound to an address. - * On success, the interface enters connecting mode. - * On failure, the interface enters default mode. - * - * @param o the object - * @param addr address to send packets to - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr) WARN_UNUSED; - -/** - * Attempts to establish connection to the peer by binding to an address. - * On success, the interface enters connecting mode. - * On failure, the interface enters default mode. - * - * @param o the object - * @param addr address to bind to. Must be supported according to - * {@link BDatagram_AddressFamilySupported}. - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr) WARN_UNUSED; - -/** - * Sets the encryption key to use for sending and receiving. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key); - -/** - * Removed the encryption key to use for sending and receiving. - * Encryption must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o); - -/** - * Sets the OTP seed for sending. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes the OTP seed for sending of one is configured. - * OTPs must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o); - -/** - * Adds an OTP seed for reciving. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes all OTP seeds for reciving. - * OTPs must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o); - -#endif diff --git a/external/badvpn_dns/client/FragmentProtoAssembler.c b/external/badvpn_dns/client/FragmentProtoAssembler.c deleted file mode 100644 index 8588c2e..0000000 --- a/external/badvpn_dns/client/FragmentProtoAssembler.c +++ /dev/null @@ -1,469 +0,0 @@ -/** - * @file FragmentProtoAssembler.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <misc/balloc.h> - -#include "FragmentProtoAssembler.h" - -#include <generated/blog_channel_FragmentProtoAssembler.h> - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#include "FragmentProtoAssembler_tree.h" -#include <structure/SAvl_impl.h> - -static void free_frame (FragmentProtoAssembler *o, struct FragmentProtoAssembler_frame *frame) -{ - // remove from used list - LinkedList1_Remove(&o->frames_used, &frame->list_node); - // remove from used tree - FPAFramesTree_Remove(&o->frames_used_tree, 0, frame); - - // append to free list - LinkedList1_Append(&o->frames_free, &frame->list_node); -} - -static void free_oldest_frame (FragmentProtoAssembler *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->frames_used)) - - // obtain oldest frame (first on the list) - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_used); - ASSERT(list_node) - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - - // free frame - free_frame(o, frame); -} - -static struct FragmentProtoAssembler_frame * allocate_new_frame (FragmentProtoAssembler *o, fragmentproto_frameid id) -{ - ASSERT(!FPAFramesTree_LookupExact(&o->frames_used_tree, 0, id)) - - // if there are no free entries, free the oldest used one - if (LinkedList1_IsEmpty(&o->frames_free)) { - PeerLog(o, BLOG_INFO, "freeing used frame"); - free_oldest_frame(o); - } - - // obtain frame entry - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_free); - ASSERT(list_node) - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - - // remove from free list - LinkedList1_Remove(&o->frames_free, &frame->list_node); - - // initialize values - frame->id = id; - frame->time = o->time; - frame->num_chunks = 0; - frame->sum = 0; - frame->length = -1; - frame->length_so_far = 0; - - // append to used list - LinkedList1_Append(&o->frames_used, &frame->list_node); - // insert to used tree - int res = FPAFramesTree_Insert(&o->frames_used_tree, 0, frame, NULL); - ASSERT_EXECUTE(res) - - return frame; -} - -static int chunks_overlap (int c1_start, int c1_len, int c2_start, int c2_len) -{ - return (c1_start + c1_len > c2_start && c2_start + c2_len > c1_start); -} - -static int frame_is_timed_out (FragmentProtoAssembler *o, struct FragmentProtoAssembler_frame *frame) -{ - ASSERT(frame->time <= o->time) - - return (o->time - frame->time > o->time_tolerance); -} - -static void reduce_times (FragmentProtoAssembler *o) -{ - // find the frame with minimal time, removing timed out frames - struct FragmentProtoAssembler_frame *minframe = NULL; - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_used); - while (list_node) { - LinkedList1Node *next = LinkedList1Node_Next(list_node); - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - if (frame_is_timed_out(o, frame)) { - PeerLog(o, BLOG_INFO, "freeing timed out frame (while reducing times)"); - free_frame(o, frame); - } else { - if (!minframe || frame->time < minframe->time) { - minframe = frame; - } - } - list_node = next; - } - - if (!minframe) { - // have no frames, set packet time to zero - o->time = 0; - return; - } - - uint32_t min_time = minframe->time; - - // subtract minimal time from all frames - for (list_node = LinkedList1_GetFirst(&o->frames_used); list_node; list_node = LinkedList1Node_Next(list_node)) { - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - frame->time -= min_time; - } - - // subtract minimal time from packet time - o->time -= min_time; -} - -static int process_chunk (FragmentProtoAssembler *o, fragmentproto_frameid frame_id, int chunk_start, int chunk_len, int is_last, uint8_t *payload) -{ - ASSERT(chunk_start >= 0) - ASSERT(chunk_len >= 0) - ASSERT(is_last == 0 || is_last == 1) - - // verify chunk - - // check start - if (chunk_start > o->output_mtu) { - PeerLog(o, BLOG_INFO, "chunk starts outside"); - return 0; - } - - // check frame size bound - if (chunk_len > o->output_mtu - chunk_start) { - PeerLog(o, BLOG_INFO, "chunk ends outside"); - return 0; - } - - // calculate end - int chunk_end = chunk_start + chunk_len; - ASSERT(chunk_end >= 0) - ASSERT(chunk_end <= o->output_mtu) - - // lookup frame - struct FragmentProtoAssembler_frame *frame = FPAFramesTree_LookupExact(&o->frames_used_tree, 0, frame_id); - if (!frame) { - // frame not found, add a new one - frame = allocate_new_frame(o, frame_id); - } else { - // have existing frame with that ID - // check frame time - if (frame_is_timed_out(o, frame)) { - // frame is timed out, remove it and use a new one - PeerLog(o, BLOG_INFO, "freeing timed out frame (while processing chunk)"); - free_frame(o, frame); - frame = allocate_new_frame(o, frame_id); - } - } - - ASSERT(frame->num_chunks < o->num_chunks) - - // check if the chunk overlaps with any existing chunks - for (int i = 0; i < frame->num_chunks; i++) { - struct FragmentProtoAssembler_chunk *chunk = &frame->chunks[i]; - if (chunks_overlap(chunk->start, chunk->len, chunk_start, chunk_len)) { - PeerLog(o, BLOG_INFO, "chunk overlaps with existing chunk"); - goto fail_frame; - } - } - - if (is_last) { - // this chunk is marked as last - if (frame->length >= 0) { - PeerLog(o, BLOG_INFO, "got last chunk, but already have one"); - goto fail_frame; - } - // check if frame size according to this packet is consistent - // with existing chunks - if (frame->length_so_far > chunk_end) { - PeerLog(o, BLOG_INFO, "got last chunk, but already have data over its bound"); - goto fail_frame; - } - } else { - // if we have length, chunk must be in its bound - if (frame->length >= 0) { - if (chunk_end > frame->length) { - PeerLog(o, BLOG_INFO, "chunk out of length bound"); - goto fail_frame; - } - } - } - - // chunk is good, add it - - // update frame time - frame->time = o->time; - - // add chunk entry - struct FragmentProtoAssembler_chunk *chunk = &frame->chunks[frame->num_chunks]; - chunk->start = chunk_start; - chunk->len = chunk_len; - frame->num_chunks++; - - // update sum - frame->sum += chunk_len; - - // update length - if (is_last) { - frame->length = chunk_end; - } else { - if (frame->length < 0) { - if (frame->length_so_far < chunk_end) { - frame->length_so_far = chunk_end; - } - } - } - - // copy chunk payload to buffer - memcpy(frame->buffer + chunk_start, payload, chunk_len); - - // is frame incomplete? - if (frame->length < 0 || frame->sum < frame->length) { - // if all chunks are used, fail it - if (frame->num_chunks == o->num_chunks) { - PeerLog(o, BLOG_INFO, "all chunks used, but frame not complete"); - goto fail_frame; - } - - // wait for more chunks - return 0; - } - - ASSERT(frame->sum == frame->length) - - PeerLog(o, BLOG_DEBUG, "frame complete"); - - // free frame entry - free_frame(o, frame); - - // send frame - PacketPassInterface_Sender_Send(o->output, frame->buffer, frame->length); - - return 1; - -fail_frame: - free_frame(o, frame); - return 0; -} - -static void process_input (FragmentProtoAssembler *o) -{ - ASSERT(o->in_len >= 0) - - // read chunks - while (o->in_pos < o->in_len) { - // obtain header - if (o->in_len - o->in_pos < sizeof(struct fragmentproto_chunk_header)) { - PeerLog(o, BLOG_INFO, "too little data for chunk header"); - break; - } - struct fragmentproto_chunk_header header; - memcpy(&header, o->in + o->in_pos, sizeof(header)); - o->in_pos += sizeof(struct fragmentproto_chunk_header); - fragmentproto_frameid frame_id = ltoh16(header.frame_id); - int chunk_start = ltoh16(header.chunk_start); - int chunk_len = ltoh16(header.chunk_len); - int is_last = ltoh8(header.is_last); - - // check is_last field - if (!(is_last == 0 || is_last == 1)) { - PeerLog(o, BLOG_INFO, "chunk is_last wrong"); - break; - } - - // obtain data - if (o->in_len - o->in_pos < chunk_len) { - PeerLog(o, BLOG_INFO, "too little data for chunk data"); - break; - } - - // process chunk - int res = process_chunk(o, frame_id, chunk_start, chunk_len, is_last, o->in + o->in_pos); - o->in_pos += chunk_len; - - if (res) { - // sending complete frame, stop processing input - return; - } - } - - // increment packet time - if (o->time == FPA_MAX_TIME) { - reduce_times(o); - if (!LinkedList1_IsEmpty(&o->frames_used)) { - ASSERT(o->time < FPA_MAX_TIME) // If there was a frame with zero time, it was removed because - // time_tolerance < FPA_MAX_TIME. So something >0 was subtracted. - o->time++; - } else { - // it was set to zero by reduce_times - ASSERT(o->time == 0) - } - } else { - o->time++; - } - - // set no input packet - o->in_len = -1; - - // finish input - PacketPassInterface_Done(&o->input); -} - -static void input_handler_send (FragmentProtoAssembler *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // save input packet - o->in_len = data_len; - o->in = data; - o->in_pos = 0; - - process_input(o); -} - -static void output_handler_done (FragmentProtoAssembler *o) -{ - ASSERT(o->in_len >= 0) - DebugObject_Access(&o->d_obj); - - process_input(o); -} - -int FragmentProtoAssembler_Init (FragmentProtoAssembler *o, int input_mtu, PacketPassInterface *output, int num_frames, int num_chunks, BPendingGroup *pg, void *user, BLog_logfunc logfunc) -{ - ASSERT(input_mtu >= 0) - ASSERT(num_frames > 0) - ASSERT(num_frames < FPA_MAX_TIME) // needed so we can always subtract times when packet time is maximum - ASSERT(num_chunks > 0) - - // init arguments - o->output = output; - o->num_chunks = num_chunks; - o->user = user; - o->logfunc = logfunc; - - // init input - PacketPassInterface_Init(&o->input, input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // remebmer output MTU - o->output_mtu = PacketPassInterface_GetMTU(o->output); - - // set packet time to zero - o->time = 0; - - // set time tolerance to num_frames - o->time_tolerance = num_frames; - - // allocate frames - if (!(o->frames_entries = (struct FragmentProtoAssembler_frame *)BAllocArray(num_frames, sizeof(o->frames_entries[0])))) { - goto fail1; - } - - // allocate chunks - if (!(o->frames_chunks = (struct FragmentProtoAssembler_chunk *)BAllocArray2(num_frames, o->num_chunks, sizeof(o->frames_chunks[0])))) { - goto fail2; - } - - // allocate buffers - if (!(o->frames_buffer = (uint8_t *)BAllocArray(num_frames, o->output_mtu))) { - goto fail3; - } - - // init frame lists - LinkedList1_Init(&o->frames_free); - LinkedList1_Init(&o->frames_used); - - // initialize frame entries - for (int i = 0; i < num_frames; i++) { - struct FragmentProtoAssembler_frame *frame = &o->frames_entries[i]; - // set chunks array pointer - frame->chunks = o->frames_chunks + (size_t)i * o->num_chunks; - // set buffer pointer - frame->buffer = o->frames_buffer + (size_t)i * o->output_mtu; - // add to free list - LinkedList1_Append(&o->frames_free, &frame->list_node); - } - - // init tree - FPAFramesTree_Init(&o->frames_used_tree); - - // have no input packet - o->in_len = -1; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail3: - BFree(o->frames_chunks); -fail2: - BFree(o->frames_entries); -fail1: - PacketPassInterface_Free(&o->input); - return 0; -} - -void FragmentProtoAssembler_Free (FragmentProtoAssembler *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffers - BFree(o->frames_buffer); - - // free chunks - BFree(o->frames_chunks); - - // free frames - BFree(o->frames_entries); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * FragmentProtoAssembler_GetInput (FragmentProtoAssembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/external/badvpn_dns/client/FragmentProtoAssembler.h b/external/badvpn_dns/client/FragmentProtoAssembler.h deleted file mode 100644 index bbc5483..0000000 --- a/external/badvpn_dns/client/FragmentProtoAssembler.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file FragmentProtoAssembler.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes packets according to FragmentProto. - */ - -#ifndef BADVPN_CLIENT_FRAGMENTPROTOASSEMBLER_H -#define BADVPN_CLIENT_FRAGMENTPROTOASSEMBLER_H - -#include <stdint.h> - -#include <protocol/fragmentproto.h> -#include <misc/debug.h> -#include <misc/compare.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <structure/LinkedList1.h> -#include <structure/SAvl.h> -#include <flow/PacketPassInterface.h> - -#define FPA_MAX_TIME UINT32_MAX - -struct FragmentProtoAssembler_frame; - -#include "FragmentProtoAssembler_tree.h" -#include <structure/SAvl_decl.h> - -struct FragmentProtoAssembler_chunk { - int start; - int len; -}; - -struct FragmentProtoAssembler_frame { - LinkedList1Node list_node; // node in free or used list - struct FragmentProtoAssembler_chunk *chunks; // array of chunks, up to num_chunks - uint8_t *buffer; // buffer with frame data, size output_mtu - // everything below only defined when frame entry is used - fragmentproto_frameid id; // frame identifier - uint32_t time; // packet time when the last chunk was received - FPAFramesTreeNode tree_node; // node fields in tree for searching frames by id - int num_chunks; // number of valid chunks - int sum; // sum of all chunks' lengths - int length; // length of the frame, or -1 if not yet known - int length_so_far; // if length=-1, current data set's upper bound -}; - -/** - * Object which decodes packets according to FragmentProto. - * - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - void *user; - BLog_logfunc logfunc; - PacketPassInterface input; - PacketPassInterface *output; - int output_mtu; - int num_chunks; - uint32_t time; - int time_tolerance; - struct FragmentProtoAssembler_frame *frames_entries; - struct FragmentProtoAssembler_chunk *frames_chunks; - uint8_t *frames_buffer; - LinkedList1 frames_free; - LinkedList1 frames_used; - FPAFramesTree frames_used_tree; - int in_len; - uint8_t *in; - int in_pos; - DebugObject d_obj; -} FragmentProtoAssembler; - -/** - * Initializes the object. - * {@link BLog_Init} must have been done. - * - * @param o the object - * @param input_mtu maximum input packet size. Must be >=0. - * @param output output interface - * @param num_frames number of frames we can hold. Must be >0 and < FPA_MAX_TIME. - * To make the assembler tolerate out-of-order input of degree D, set to D+2. - * Here, D is the minimum size of a hypothetical buffer needed to order the input. - * @param num_chunks maximum number of chunks a frame can come in. Must be >0. - * @param pg pending group - * @param user argument to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int FragmentProtoAssembler_Init (FragmentProtoAssembler *o, int input_mtu, PacketPassInterface *output, int num_frames, int num_chunks, BPendingGroup *pg, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void FragmentProtoAssembler_Free (FragmentProtoAssembler *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * FragmentProtoAssembler_GetInput (FragmentProtoAssembler *o); - -#endif diff --git a/external/badvpn_dns/client/FragmentProtoAssembler_tree.h b/external/badvpn_dns/client/FragmentProtoAssembler_tree.h deleted file mode 100644 index 744c633..0000000 --- a/external/badvpn_dns/client/FragmentProtoAssembler_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FPAFramesTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct FragmentProtoAssembler_frame -#define SAVL_PARAM_TYPE_KEY fragmentproto_frameid -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->id, (entry2)->id) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->id) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/external/badvpn_dns/client/FragmentProtoDisassembler.c b/external/badvpn_dns/client/FragmentProtoDisassembler.c deleted file mode 100644 index e67a1dc..0000000 --- a/external/badvpn_dns/client/FragmentProtoDisassembler.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - * @file FragmentProtoDisassembler.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/minmax.h> - -#include "client/FragmentProtoDisassembler.h" - -static void write_chunks (FragmentProtoDisassembler *o) -{ - #define IN_AVAIL (o->in_len - o->in_used) - #define OUT_AVAIL ((o->output_mtu - o->out_used) - (int)sizeof(struct fragmentproto_chunk_header)) - - ASSERT(o->in_len >= 0) - ASSERT(o->out) - ASSERT(OUT_AVAIL > 0) - - // write chunks to output packet - do { - // calculate chunk length - int chunk_len = bmin_int(IN_AVAIL, OUT_AVAIL); - if (o->chunk_mtu > 0) { - chunk_len = bmin_int(chunk_len, o->chunk_mtu); - } - - // write chunk header - struct fragmentproto_chunk_header header; - header.frame_id = htol16(o->frame_id); - header.chunk_start = htol16(o->in_used); - header.chunk_len = htol16(chunk_len); - header.is_last = (chunk_len == IN_AVAIL); - memcpy(o->out + o->out_used, &header, sizeof(header)); - - // write chunk data - memcpy(o->out + o->out_used + sizeof(struct fragmentproto_chunk_header), o->in + o->in_used, chunk_len); - - // increment pointers - o->in_used += chunk_len; - o->out_used += sizeof(struct fragmentproto_chunk_header) + chunk_len; - } while (IN_AVAIL > 0 && OUT_AVAIL > 0); - - // have we finished the input packet? - if (IN_AVAIL == 0) { - // set no input packet - o->in_len = -1; - - // increment frame ID - o->frame_id++; - - // finish input - PacketPassInterface_Done(&o->input); - } - - // should we finish the output packet? - if (OUT_AVAIL <= 0 || o->latency < 0) { - // set no output packet - o->out = NULL; - - // stop timer (if it's running) - if (o->latency >= 0) { - BReactor_RemoveTimer(o->reactor, &o->timer); - } - - // finish output - PacketRecvInterface_Done(&o->output, o->out_used); - } else { - // start timer if we have output and it's not running (output was empty before) - if (!BTimer_IsRunning(&o->timer)) { - BReactor_SetTimer(o->reactor, &o->timer); - } - } -} - -static void input_handler_send (FragmentProtoDisassembler *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(o->in_len == -1) - - // set input packet - o->in_len = data_len; - o->in = data; - o->in_used = 0; - - // if there is no output, wait for it - if (!o->out) { - return; - } - - write_chunks(o); -} - -static void input_handler_requestcancel (FragmentProtoDisassembler *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->out) - - // set no input packet - o->in_len = -1; - - // finish input - PacketPassInterface_Done(&o->input); -} - -static void output_handler_recv (FragmentProtoDisassembler *o, uint8_t *data) -{ - ASSERT(data) - ASSERT(!o->out) - - // set output packet - o->out = data; - o->out_used = 0; - - // if there is no input, wait for it - if (o->in_len < 0) { - return; - } - - write_chunks(o); -} - -static void timer_handler (FragmentProtoDisassembler *o) -{ - ASSERT(o->latency >= 0) - ASSERT(o->out) - ASSERT(o->in_len == -1) - - // set no output packet - o->out = NULL; - - // finish output - PacketRecvInterface_Done(&o->output, o->out_used); -} - -void FragmentProtoDisassembler_Init (FragmentProtoDisassembler *o, BReactor *reactor, int input_mtu, int output_mtu, int chunk_mtu, btime_t latency) -{ - ASSERT(input_mtu >= 0) - ASSERT(input_mtu <= UINT16_MAX) - ASSERT(output_mtu > sizeof(struct fragmentproto_chunk_header)) - ASSERT(chunk_mtu > 0 || chunk_mtu < 0) - - // init arguments - o->reactor = reactor; - o->output_mtu = output_mtu; - o->chunk_mtu = chunk_mtu; - o->latency = latency; - - // init input - PacketPassInterface_Init(&o->input, input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(reactor)); - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, BReactor_PendingGroup(reactor)); - - // init timer - if (o->latency >= 0) { - BTimer_Init(&o->timer, o->latency, (BTimer_handler)timer_handler, o); - } - - // have no input packet - o->in_len = -1; - - // have no output packet - o->out = NULL; - - // start with zero frame ID - o->frame_id = 0; - - DebugObject_Init(&o->d_obj); -} - -void FragmentProtoDisassembler_Free (FragmentProtoDisassembler *o) -{ - DebugObject_Free(&o->d_obj); - - // free timer - if (o->latency >= 0) { - BReactor_RemoveTimer(o->reactor, &o->timer); - } - - // free output - PacketRecvInterface_Free(&o->output); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * FragmentProtoDisassembler_GetInput (FragmentProtoDisassembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -PacketRecvInterface * FragmentProtoDisassembler_GetOutput (FragmentProtoDisassembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/client/FragmentProtoDisassembler.h b/external/badvpn_dns/client/FragmentProtoDisassembler.h deleted file mode 100644 index 49fe9c8..0000000 --- a/external/badvpn_dns/client/FragmentProtoDisassembler.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file FragmentProtoDisassembler.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets into packets composed of chunks - * according to FragmentProto. - */ - -#ifndef BADVPN_CLIENT_CCPROTODISASSEMBLER_H -#define BADVPN_CLIENT_CCPROTODISASSEMBLER_H - -#include <stdint.h> - -#include <protocol/fragmentproto.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <system/BTime.h> -#include <flow/PacketPassInterface.h> -#include <flow/PacketRecvInterface.h> - -/** - * Object which encodes packets into packets composed of chunks - * according to FragmentProto. - * - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - BReactor *reactor; - int output_mtu; - int chunk_mtu; - btime_t latency; - PacketPassInterface input; - PacketRecvInterface output; - BTimer timer; - int in_len; - uint8_t *in; - int in_used; - uint8_t *out; - int out_used; - fragmentproto_frameid frame_id; - DebugObject d_obj; -} FragmentProtoDisassembler; - -/** - * Initializes the object. - * - * @param o the object - * @param reactor reactor we live in - * @param input_mtu maximum input packet size. Must be >=0 and <=UINT16_MAX. - * @param output_mtu maximum output packet size. Must be >sizeof(struct fragmentproto_chunk_header). - * @param chunk_mtu maximum chunk size. Must be >0, or <0 for no explicit limit. - * @param latency maximum time a pending output packet with some data can wait for more data - * before being sent out. If nonnegative, a timer will be used. If negative, - * packets will always be sent out immediately. If low latency is desired, - * prefer setting this to zero rather than negative. - */ -void FragmentProtoDisassembler_Init (FragmentProtoDisassembler *o, BReactor *reactor, int input_mtu, int output_mtu, int chunk_mtu, btime_t latency); - -/** - * Frees the object. - * - * @param o the object - */ -void FragmentProtoDisassembler_Free (FragmentProtoDisassembler *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * FragmentProtoDisassembler_GetInput (FragmentProtoDisassembler *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * FragmentProtoDisassembler_GetOutput (FragmentProtoDisassembler *o); - -#endif diff --git a/external/badvpn_dns/client/FrameDecider.c b/external/badvpn_dns/client/FrameDecider.c deleted file mode 100644 index e7bb4de..0000000 --- a/external/badvpn_dns/client/FrameDecider.c +++ /dev/null @@ -1,795 +0,0 @@ -/** - * @file FrameDecider.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/balloc.h> -#include <misc/ethernet_proto.h> -#include <misc/ipv4_proto.h> -#include <misc/igmp_proto.h> -#include <misc/byteorder.h> -#include <misc/compare.h> -#include <misc/print_macros.h> - -#include <client/FrameDecider.h> - -#include <generated/blog_channel_FrameDecider.h> - -#define DECIDE_STATE_NONE 1 -#define DECIDE_STATE_UNICAST 2 -#define DECIDE_STATE_FLOOD 3 -#define DECIDE_STATE_MULTICAST 4 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static int compare_macs (const uint8_t *mac1, const uint8_t *mac2) -{ - int c = memcmp(mac1, mac2, 6); - return B_COMPARE(c, 0); -} - -#include "FrameDecider_macs_tree.h" -#include <structure/SAvl_impl.h> - -#include "FrameDecider_groups_tree.h" -#include <structure/SAvl_impl.h> - -#include "FrameDecider_multicast_tree.h" -#include <structure/SAvl_impl.h> - -static void add_mac_to_peer (FrameDeciderPeer *o, uint8_t *mac) -{ - FrameDecider *d = o->d; - - // locate entry in tree - struct _FrameDecider_mac_entry *e_entry = FDMacsTree_LookupExact(&d->macs_tree, 0, mac); - if (e_entry) { - if (e_entry->peer == o) { - // this is our MAC; only move it to the end of the used list - LinkedList1_Remove(&o->mac_entries_used, &e_entry->list_node); - LinkedList1_Append(&o->mac_entries_used, &e_entry->list_node); - return; - } - - // some other peer has that MAC; disassociate it - FDMacsTree_Remove(&d->macs_tree, 0, e_entry); - LinkedList1_Remove(&e_entry->peer->mac_entries_used, &e_entry->list_node); - LinkedList1_Append(&e_entry->peer->mac_entries_free, &e_entry->list_node); - } - - // aquire MAC address entry, if there are no free ones reuse the oldest used one - LinkedList1Node *list_node; - struct _FrameDecider_mac_entry *entry; - if (list_node = LinkedList1_GetFirst(&o->mac_entries_free)) { - entry = UPPER_OBJECT(list_node, struct _FrameDecider_mac_entry, list_node); - ASSERT(entry->peer == o) - - // remove from free - LinkedList1_Remove(&o->mac_entries_free, &entry->list_node); - } else { - list_node = LinkedList1_GetFirst(&o->mac_entries_used); - ASSERT(list_node) - entry = UPPER_OBJECT(list_node, struct _FrameDecider_mac_entry, list_node); - ASSERT(entry->peer == o) - - // remove from used - FDMacsTree_Remove(&d->macs_tree, 0, entry); - LinkedList1_Remove(&o->mac_entries_used, &entry->list_node); - } - - PeerLog(o, BLOG_INFO, "adding MAC %02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8"", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - // set MAC in entry - memcpy(entry->mac, mac, sizeof(entry->mac)); - - // add to used - LinkedList1_Append(&o->mac_entries_used, &entry->list_node); - int res = FDMacsTree_Insert(&d->macs_tree, 0, entry, NULL); - ASSERT_EXECUTE(res) -} - -static uint32_t compute_sig_for_group (uint32_t group) -{ - return hton32(ntoh32(group)&0x7FFFFF); -} - -static uint32_t compute_sig_for_mac (uint8_t *mac) -{ - uint32_t sig; - memcpy(&sig, mac + 2, 4); - sig = hton32(ntoh32(sig)&0x7FFFFF); - return sig; -} - -static void add_to_multicast (FrameDecider *d, struct _FrameDecider_group_entry *group_entry) -{ - // compute sig - uint32_t sig = compute_sig_for_group(group_entry->group); - - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&d->multicast_tree, 0, sig); - if (master) { - // use existing master - ASSERT(master->is_master) - - // set not master - group_entry->is_master = 0; - - // insert to list - LinkedList3Node_InitAfter(&group_entry->sig_list_node, &master->sig_list_node); - } else { - // make this entry master - - // set master - group_entry->is_master = 1; - - // set sig - group_entry->master.sig = sig; - - // insert to multicast tree - int res = FDMulticastTree_Insert(&d->multicast_tree, 0, group_entry, NULL); - ASSERT_EXECUTE(res) - - // init list node - LinkedList3Node_InitLonely(&group_entry->sig_list_node); - } -} - -static void remove_from_multicast (FrameDecider *d, struct _FrameDecider_group_entry *group_entry) -{ - // compute sig - uint32_t sig = compute_sig_for_group(group_entry->group); - - if (group_entry->is_master) { - // remove master from multicast tree - FDMulticastTree_Remove(&d->multicast_tree, 0, group_entry); - - if (!LinkedList3Node_IsLonely(&group_entry->sig_list_node)) { - // at least one more group entry for this sig; make another entry the master - - // get an entry - LinkedList3Node *list_node = LinkedList3Node_NextOrPrev(&group_entry->sig_list_node); - struct _FrameDecider_group_entry *newmaster = UPPER_OBJECT(list_node, struct _FrameDecider_group_entry, sig_list_node); - ASSERT(!newmaster->is_master) - - // set master - newmaster->is_master = 1; - - // set sig - newmaster->master.sig = sig; - - // insert to multicast tree - int res = FDMulticastTree_Insert(&d->multicast_tree, 0, newmaster, NULL); - ASSERT_EXECUTE(res) - } - } - - // free linked list node - LinkedList3Node_Free(&group_entry->sig_list_node); -} - -static void add_group_to_peer (FrameDeciderPeer *o, uint32_t group) -{ - FrameDecider *d = o->d; - - struct _FrameDecider_group_entry *group_entry = FDGroupsTree_LookupExact(&o->groups_tree, 0, group); - if (group_entry) { - // move to end of used list - LinkedList1_Remove(&o->group_entries_used, &group_entry->list_node); - LinkedList1_Append(&o->group_entries_used, &group_entry->list_node); - } else { - PeerLog(o, BLOG_INFO, "joined group %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", - ((uint8_t *)&group)[0], ((uint8_t *)&group)[1], ((uint8_t *)&group)[2], ((uint8_t *)&group)[3] - ); - - // aquire group entry, if there are no free ones reuse the earliest used one - LinkedList1Node *node; - if (node = LinkedList1_GetFirst(&o->group_entries_free)) { - group_entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from free list - LinkedList1_Remove(&o->group_entries_free, &group_entry->list_node); - } else { - node = LinkedList1_GetFirst(&o->group_entries_used); - ASSERT(node) - group_entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from multicast - remove_from_multicast(d, group_entry); - - // remove from peer's groups tree - FDGroupsTree_Remove(&o->groups_tree, 0, group_entry); - - // remove from used list - LinkedList1_Remove(&o->group_entries_used, &group_entry->list_node); - } - - // add entry to used list - LinkedList1_Append(&o->group_entries_used, &group_entry->list_node); - - // set group address - group_entry->group = group; - - // insert to peer's groups tree - int res = FDGroupsTree_Insert(&o->groups_tree, 0, group_entry, NULL); - ASSERT_EXECUTE(res) - - // add to multicast - add_to_multicast(d, group_entry); - } - - // set timer - group_entry->timer_endtime = btime_gettime() + d->igmp_group_membership_interval; - BReactor_SetTimerAbsolute(d->reactor, &group_entry->timer, group_entry->timer_endtime); -} - -static void remove_group_entry (struct _FrameDecider_group_entry *group_entry) -{ - FrameDeciderPeer *peer = group_entry->peer; - FrameDecider *d = peer->d; - - uint32_t group = group_entry->group; - - PeerLog(peer, BLOG_INFO, "left group %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", - ((uint8_t *)&group)[0], ((uint8_t *)&group)[1], ((uint8_t *)&group)[2], ((uint8_t *)&group)[3] - ); - - // remove from multicast - remove_from_multicast(d, group_entry); - - // remove from peer's groups tree - FDGroupsTree_Remove(&peer->groups_tree, 0, group_entry); - - // remove from used list - LinkedList1_Remove(&peer->group_entries_used, &group_entry->list_node); - - // add to free list - LinkedList1_Append(&peer->group_entries_free, &group_entry->list_node); - - // stop timer - BReactor_RemoveTimer(d->reactor, &group_entry->timer); -} - -static void lower_group_timers_to_lmqt (FrameDecider *d, uint32_t group) -{ - // have to lower all the group timers of this group down to LMQT - - // compute sig - uint32_t sig = compute_sig_for_group(group); - - // look up the sig in multicast tree - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&d->multicast_tree, 0, sig); - if (!master) { - return; - } - ASSERT(master->is_master) - - // iterate all group entries with this sig - LinkedList3Iterator it; - LinkedList3Iterator_Init(&it, LinkedList3Node_First(&master->sig_list_node), 1); - LinkedList3Node *sig_list_node; - while (sig_list_node = LinkedList3Iterator_Next(&it)) { - struct _FrameDecider_group_entry *group_entry = UPPER_OBJECT(sig_list_node, struct _FrameDecider_group_entry, sig_list_node); - - // skip wrong groups - if (group_entry->group != group) { - continue; - } - - // lower timer down to LMQT - btime_t now = btime_gettime(); - if (group_entry->timer_endtime > now + d->igmp_last_member_query_time) { - group_entry->timer_endtime = now + d->igmp_last_member_query_time; - BReactor_SetTimerAbsolute(d->reactor, &group_entry->timer, group_entry->timer_endtime); - } - } -} - -static void group_entry_timer_handler (struct _FrameDecider_group_entry *group_entry) -{ - DebugObject_Access(&group_entry->peer->d_obj); - - remove_group_entry(group_entry); -} - -void FrameDecider_Init (FrameDecider *o, int max_peer_macs, int max_peer_groups, btime_t igmp_group_membership_interval, btime_t igmp_last_member_query_time, BReactor *reactor) -{ - ASSERT(max_peer_macs > 0) - ASSERT(max_peer_groups > 0) - - // init arguments - o->max_peer_macs = max_peer_macs; - o->max_peer_groups = max_peer_groups; - o->igmp_group_membership_interval = igmp_group_membership_interval; - o->igmp_last_member_query_time = igmp_last_member_query_time; - o->reactor = reactor; - - // init peers list - LinkedList1_Init(&o->peers_list); - - // init MAC tree - FDMacsTree_Init(&o->macs_tree); - - // init multicast tree - FDMulticastTree_Init(&o->multicast_tree); - - // init decide state - o->decide_state = DECIDE_STATE_NONE; - - // set no current flood peer - o->decide_flood_current = NULL; - - DebugObject_Init(&o->d_obj); -} - -void FrameDecider_Free (FrameDecider *o) -{ - ASSERT(FDMulticastTree_IsEmpty(&o->multicast_tree)) - ASSERT(FDMacsTree_IsEmpty(&o->macs_tree)) - ASSERT(LinkedList1_IsEmpty(&o->peers_list)) - DebugObject_Free(&o->d_obj); -} - -void FrameDecider_AnalyzeAndDecide (FrameDecider *o, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - DebugObject_Access(&o->d_obj); - - // reset decide state - switch (o->decide_state) { - case DECIDE_STATE_NONE: - break; - case DECIDE_STATE_UNICAST: - break; - case DECIDE_STATE_FLOOD: - break; - case DECIDE_STATE_MULTICAST: - LinkedList3Iterator_Free(&o->decide_multicast_it); - return; - default: - ASSERT(0); - } - o->decide_state = DECIDE_STATE_NONE; - o->decide_flood_current = NULL; - - // analyze frame - - const uint8_t *pos = frame; - int len = frame_len; - - if (len < sizeof(struct ethernet_header)) { - return; - } - struct ethernet_header eh; - memcpy(&eh, pos, sizeof(eh)); - pos += sizeof(struct ethernet_header); - len -= sizeof(struct ethernet_header); - - int is_igmp = 0; - - switch (ntoh16(eh.type)) { - case ETHERTYPE_IPV4: { - // check IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check((uint8_t *)pos, len, &ipv4_header, (uint8_t **)&pos, &len)) { - BLog(BLOG_INFO, "decide: wrong IP packet"); - goto out; - } - - // check if it's IGMP - if (ntoh8(ipv4_header.protocol) != IPV4_PROTOCOL_IGMP) { - goto out; - } - - // remember that it's IGMP; we have to flood IGMP frames - is_igmp = 1; - - // check IGMP header - if (len < sizeof(struct igmp_base)) { - BLog(BLOG_INFO, "decide: IGMP: short packet"); - goto out; - } - struct igmp_base igmp_base; - memcpy(&igmp_base, pos, sizeof(igmp_base)); - pos += sizeof(struct igmp_base); - len -= sizeof(struct igmp_base); - - switch (ntoh8(igmp_base.type)) { - case IGMP_TYPE_MEMBERSHIP_QUERY: { - if (len == sizeof(struct igmp_v2_extra) && ntoh8(igmp_base.max_resp_code) != 0) { - // V2 query - struct igmp_v2_extra query; - memcpy(&query, pos, sizeof(query)); - pos += sizeof(struct igmp_v2_extra); - len -= sizeof(struct igmp_v2_extra); - - if (ntoh32(query.group) != 0) { - // got a Group-Specific Query, lower group timers to LMQT - lower_group_timers_to_lmqt(o, query.group); - } - } - else if (len >= sizeof(struct igmp_v3_query_extra)) { - // V3 query - struct igmp_v3_query_extra query; - memcpy(&query, pos, sizeof(query)); - pos += sizeof(struct igmp_v3_query_extra); - len -= sizeof(struct igmp_v3_query_extra); - - // iterate sources - uint16_t num_sources = ntoh16(query.number_of_sources); - int i; - for (i = 0; i < num_sources; i++) { - // check source - if (len < sizeof(struct igmp_source)) { - BLog(BLOG_NOTICE, "decide: IGMP: short source"); - goto out; - } - pos += sizeof(struct igmp_source); - len -= sizeof(struct igmp_source); - } - - if (ntoh32(query.group) != 0 && num_sources == 0) { - // got a Group-Specific Query, lower group timers to LMQT - lower_group_timers_to_lmqt(o, query.group); - } - } - } break; - } - } break; - } - -out:; - - const uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const uint8_t multicast_mac_header[] = {0x01, 0x00, 0x5e}; - - // if it's broadcast or IGMP, flood it - if (is_igmp || !memcmp(eh.dest, broadcast_mac, sizeof(broadcast_mac))) { - o->decide_state = DECIDE_STATE_FLOOD; - o->decide_flood_current = LinkedList1_GetFirst(&o->peers_list); - return; - } - - // if it's multicast, forward to all peers with the given sig - if (!memcmp(eh.dest, multicast_mac_header, sizeof(multicast_mac_header))) { - // extract group's sig from destination MAC - uint32_t sig = compute_sig_for_mac(eh.dest); - - // look up the sig in multicast tree - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&o->multicast_tree, 0, sig); - if (master) { - ASSERT(master->is_master) - - o->decide_state = DECIDE_STATE_MULTICAST; - LinkedList3Iterator_Init(&o->decide_multicast_it, LinkedList3Node_First(&master->sig_list_node), 1); - } - - return; - } - - // look for MAC entry - struct _FrameDecider_mac_entry *entry = FDMacsTree_LookupExact(&o->macs_tree, 0, eh.dest); - if (entry) { - o->decide_state = DECIDE_STATE_UNICAST; - o->decide_unicast_peer = entry->peer; - return; - } - - // unknown destination MAC, flood - o->decide_state = DECIDE_STATE_FLOOD; - o->decide_flood_current = LinkedList1_GetFirst(&o->peers_list); - return; -} - -FrameDeciderPeer * FrameDecider_NextDestination (FrameDecider *o) -{ - DebugObject_Access(&o->d_obj); - - switch (o->decide_state) { - case DECIDE_STATE_NONE: { - return NULL; - } break; - - case DECIDE_STATE_UNICAST: { - o->decide_state = DECIDE_STATE_NONE; - - return o->decide_unicast_peer; - } break; - - case DECIDE_STATE_FLOOD: { - if (!o->decide_flood_current) { - o->decide_state = DECIDE_STATE_NONE; - return NULL; - } - - LinkedList1Node *list_node = o->decide_flood_current; - o->decide_flood_current = LinkedList1Node_Next(o->decide_flood_current); - - FrameDeciderPeer *peer = UPPER_OBJECT(list_node, FrameDeciderPeer, list_node); - - return peer; - } break; - - case DECIDE_STATE_MULTICAST: { - LinkedList3Node *list_node = LinkedList3Iterator_Next(&o->decide_multicast_it); - if (!list_node) { - o->decide_state = DECIDE_STATE_NONE; - return NULL; - } - struct _FrameDecider_group_entry *group_entry = UPPER_OBJECT(list_node, struct _FrameDecider_group_entry, sig_list_node); - - return group_entry->peer; - } break; - - default: - ASSERT(0); - return NULL; - } -} - -int FrameDeciderPeer_Init (FrameDeciderPeer *o, FrameDecider *d, void *user, BLog_logfunc logfunc) -{ - // init arguments - o->d = d; - o->user = user; - o->logfunc = logfunc; - - // allocate MAC entries - if (!(o->mac_entries = (struct _FrameDecider_mac_entry *)BAllocArray(d->max_peer_macs, sizeof(struct _FrameDecider_mac_entry)))) { - PeerLog(o, BLOG_ERROR, "failed to allocate MAC entries"); - goto fail0; - } - - // allocate group entries - if (!(o->group_entries = (struct _FrameDecider_group_entry *)BAllocArray(d->max_peer_groups, sizeof(struct _FrameDecider_group_entry)))) { - PeerLog(o, BLOG_ERROR, "failed to allocate group entries"); - goto fail1; - } - - // insert to peers list - LinkedList1_Append(&d->peers_list, &o->list_node); - - // init MAC entry lists - LinkedList1_Init(&o->mac_entries_free); - LinkedList1_Init(&o->mac_entries_used); - - // initialize MAC entries - for (int i = 0; i < d->max_peer_macs; i++) { - struct _FrameDecider_mac_entry *entry = &o->mac_entries[i]; - - // set peer - entry->peer = o; - - // insert to free list - LinkedList1_Append(&o->mac_entries_free, &entry->list_node); - } - - // init group entry lists - LinkedList1_Init(&o->group_entries_free); - LinkedList1_Init(&o->group_entries_used); - - // initialize group entries - for (int i = 0; i < d->max_peer_groups; i++) { - struct _FrameDecider_group_entry *entry = &o->group_entries[i]; - - // set peer - entry->peer = o; - - // insert to free list - LinkedList1_Append(&o->group_entries_free, &entry->list_node); - - // init timer - BTimer_Init(&entry->timer, 0, (BTimer_handler)group_entry_timer_handler, entry); - } - - // initialize groups tree - FDGroupsTree_Init(&o->groups_tree); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - BFree(o->mac_entries); -fail0: - return 0; -} - -void FrameDeciderPeer_Free (FrameDeciderPeer *o) -{ - DebugObject_Free(&o->d_obj); - - FrameDecider *d = o->d; - - // remove decide unicast reference - if (d->decide_state == DECIDE_STATE_UNICAST && d->decide_unicast_peer == o) { - d->decide_state = DECIDE_STATE_NONE; - } - - LinkedList1Node *node; - - // free group entries - for (node = LinkedList1_GetFirst(&o->group_entries_used); node; node = LinkedList1Node_Next(node)) { - struct _FrameDecider_group_entry *entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from multicast - remove_from_multicast(d, entry); - - // stop timer - BReactor_RemoveTimer(d->reactor, &entry->timer); - } - - // remove used MAC entries from tree - for (node = LinkedList1_GetFirst(&o->mac_entries_used); node; node = LinkedList1Node_Next(node)) { - struct _FrameDecider_mac_entry *entry = UPPER_OBJECT(node, struct _FrameDecider_mac_entry, list_node); - - // remove from tree - FDMacsTree_Remove(&d->macs_tree, 0, entry); - } - - // remove from peers list - if (d->decide_flood_current == &o->list_node) { - d->decide_flood_current = LinkedList1Node_Next(d->decide_flood_current); - } - LinkedList1_Remove(&d->peers_list, &o->list_node); - - // free group entries - BFree(o->group_entries); - - // free MAC entries - BFree(o->mac_entries); -} - -void FrameDeciderPeer_Analyze (FrameDeciderPeer *o, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - DebugObject_Access(&o->d_obj); - - const uint8_t *pos = frame; - int len = frame_len; - - if (len < sizeof(struct ethernet_header)) { - goto out; - } - struct ethernet_header eh; - memcpy(&eh, pos, sizeof(eh)); - pos += sizeof(struct ethernet_header); - len -= sizeof(struct ethernet_header); - - // register source MAC address with this peer - add_mac_to_peer(o, eh.source); - - switch (ntoh16(eh.type)) { - case ETHERTYPE_IPV4: { - // check IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check((uint8_t *)pos, len, &ipv4_header, (uint8_t **)&pos, &len)) { - PeerLog(o, BLOG_INFO, "analyze: wrong IP packet"); - goto out; - } - - // check if it's IGMP - if (ntoh8(ipv4_header.protocol) != IPV4_PROTOCOL_IGMP) { - goto out; - } - - // check IGMP header - if (len < sizeof(struct igmp_base)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short packet"); - goto out; - } - struct igmp_base igmp_base; - memcpy(&igmp_base, pos, sizeof(igmp_base)); - pos += sizeof(struct igmp_base); - len -= sizeof(struct igmp_base); - - switch (ntoh8(igmp_base.type)) { - case IGMP_TYPE_V2_MEMBERSHIP_REPORT: { - // check extra - if (len < sizeof(struct igmp_v2_extra)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short v2 report"); - goto out; - } - struct igmp_v2_extra report; - memcpy(&report, pos, sizeof(report)); - pos += sizeof(struct igmp_v2_extra); - len -= sizeof(struct igmp_v2_extra); - - // add to group - add_group_to_peer(o, report.group); - } break; - - case IGMP_TYPE_V3_MEMBERSHIP_REPORT: { - // check extra - if (len < sizeof(struct igmp_v3_report_extra)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short v3 report"); - goto out; - } - struct igmp_v3_report_extra report; - memcpy(&report, pos, sizeof(report)); - pos += sizeof(struct igmp_v3_report_extra); - len -= sizeof(struct igmp_v3_report_extra); - - // iterate records - uint16_t num_records = ntoh16(report.number_of_group_records); - for (int i = 0; i < num_records; i++) { - // check record - if (len < sizeof(struct igmp_v3_report_record)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short record header"); - goto out; - } - struct igmp_v3_report_record record; - memcpy(&record, pos, sizeof(record)); - pos += sizeof(struct igmp_v3_report_record); - len -= sizeof(struct igmp_v3_report_record); - - // iterate sources - uint16_t num_sources = ntoh16(record.number_of_sources); - int j; - for (j = 0; j < num_sources; j++) { - // check source - if (len < sizeof(struct igmp_source)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short source"); - goto out; - } - pos += sizeof(struct igmp_source); - len -= sizeof(struct igmp_source); - } - - // check aux data - uint16_t aux_len = ntoh16(record.aux_data_len); - if (len < aux_len) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short record aux data"); - goto out; - } - pos += aux_len; - len -= aux_len; - - switch (record.type) { - case IGMP_RECORD_TYPE_MODE_IS_INCLUDE: - case IGMP_RECORD_TYPE_CHANGE_TO_INCLUDE_MODE: - if (num_sources != 0) { - add_group_to_peer(o, record.group); - } - break; - case IGMP_RECORD_TYPE_MODE_IS_EXCLUDE: - case IGMP_RECORD_TYPE_CHANGE_TO_EXCLUDE_MODE: - add_group_to_peer(o, record.group); - break; - } - } - } break; - } - } break; - } - -out:; -} diff --git a/external/badvpn_dns/client/FrameDecider.h b/external/badvpn_dns/client/FrameDecider.h deleted file mode 100644 index f2a2937..0000000 --- a/external/badvpn_dns/client/FrameDecider.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @file FrameDecider.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Mudule which decides to which peers frames from the device are to be - * forwarded. - */ - -#ifndef BADVPN_CLIENT_FRAMEDECIDER_H -#define BADVPN_CLIENT_FRAMEDECIDER_H - -#include <stdint.h> - -#include <structure/LinkedList1.h> -#include <structure/LinkedList3.h> -#include <structure/SAvl.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> - -struct _FrameDeciderPeer; -struct _FrameDecider_mac_entry; -struct _FrameDecider_group_entry; - -typedef const uint8_t *FDMacsTree_key; - -#include "FrameDecider_macs_tree.h" -#include <structure/SAvl_decl.h> - -#include "FrameDecider_groups_tree.h" -#include <structure/SAvl_decl.h> - -#include "FrameDecider_multicast_tree.h" -#include <structure/SAvl_decl.h> - -struct _FrameDecider_mac_entry { - struct _FrameDeciderPeer *peer; - LinkedList1Node list_node; // node in FrameDeciderPeer.mac_entries_free or FrameDeciderPeer.mac_entries_used - // defined when used: - uint8_t mac[6]; - FDMacsTreeNode tree_node; // node in FrameDecider.macs_tree, indexed by mac -}; - -struct _FrameDecider_group_entry { - struct _FrameDeciderPeer *peer; - LinkedList1Node list_node; // node in FrameDeciderPeer.group_entries_free or FrameDeciderPeer.group_entries_used - BTimer timer; // timer for removing the group entry, running when used - // defined when used: - // basic group data - uint32_t group; // group address - FDGroupsTreeNode tree_node; // node in FrameDeciderPeer.groups_tree, indexed by group - // all that folows is managed by add_to_multicast() and remove_from_multicast() - LinkedList3Node sig_list_node; // node in list of group entries with the same sig - btime_t timer_endtime; - int is_master; - // defined when used and we are master: - struct { - uint32_t sig; // last 23 bits of group address - FDMulticastTreeNode tree_node; // node in FrameDecider.multicast_tree, indexed by sig - } master; -}; - -/** - * Object that represents a local device. - */ -typedef struct { - int max_peer_macs; - int max_peer_groups; - btime_t igmp_group_membership_interval; - btime_t igmp_last_member_query_time; - BReactor *reactor; - LinkedList1 peers_list; - FDMacsTree macs_tree; - FDMulticastTree multicast_tree; - int decide_state; - LinkedList1Node *decide_flood_current; - struct _FrameDeciderPeer *decide_unicast_peer; - LinkedList3Iterator decide_multicast_it; - DebugObject d_obj; -} FrameDecider; - -/** - * Object that represents a peer that a local device can send frames to. - */ -typedef struct _FrameDeciderPeer { - FrameDecider *d; - void *user; - BLog_logfunc logfunc; - struct _FrameDecider_mac_entry *mac_entries; - struct _FrameDecider_group_entry *group_entries; - LinkedList1Node list_node; // node in FrameDecider.peers_list - LinkedList1 mac_entries_free; - LinkedList1 mac_entries_used; - LinkedList1 group_entries_free; - LinkedList1 group_entries_used; - FDGroupsTree groups_tree; - DebugObject d_obj; -} FrameDeciderPeer; - -/** - * Initializes the object. - * - * @param o the object - * @param max_peer_macs maximum number of MAC addresses a peer may posess. Must be >0. - * @param max_peer_groups maximum number of multicast groups a peer may belong to. Must be >0. - * @param igmp_group_membership_interval IGMP Group Membership Interval value. When a join - * is detected for a peer in {@link FrameDeciderPeer_Analyze}, this is how long we wait - * for another join before we remove the group from the peer. Note that the group may - * be removed sooner if the peer fails to respond to a Group-Specific Query (see below). - * @param igmp_last_member_query_time IGMP Last Member Query Time value. When a Group-Specific - * Query is detected in {@link FrameDecider_AnalyzeAndDecide}, this is how long we wait for a peer - * belonging to the group to send a join before we remove the group from it. - */ -void FrameDecider_Init (FrameDecider *o, int max_peer_macs, int max_peer_groups, btime_t igmp_group_membership_interval, btime_t igmp_last_member_query_time, BReactor *reactor); - -/** - * Frees the object. - * There must be no {@link FrameDeciderPeer} objects using this decider. - * - * @param o the object - */ -void FrameDecider_Free (FrameDecider *o); - -/** - * Analyzes a frame read from the local device and starts deciding which peers - * the frame should be forwarded to. - * - * @param o the object - * @param frame frame data - * @param frame_len frame length. Must be >=0. - */ -void FrameDecider_AnalyzeAndDecide (FrameDecider *o, const uint8_t *frame, int frame_len); - -/** - * Returns the next peer that the frame submitted to {@link FrameDecider_AnalyzeAndDecide} should be - * forwarded to. - * - * @param o the object - * @return peer to forward the frame to, or NULL if no more - */ -FrameDeciderPeer * FrameDecider_NextDestination (FrameDecider *o); - -/** - * Initializes the object. - * - * @param o the object - * @param d decider this peer will belong to - * @param user argument to log function - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int FrameDeciderPeer_Init (FrameDeciderPeer *o, FrameDecider *d, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void FrameDeciderPeer_Free (FrameDeciderPeer *o); - -/** - * Analyzes a frame received from the peer. - * - * @param o the object - * @param frame frame data - * @param frame_len frame length. Must be >=0. - */ -void FrameDeciderPeer_Analyze (FrameDeciderPeer *o, const uint8_t *frame, int frame_len); - -#endif diff --git a/external/badvpn_dns/client/FrameDecider_groups_tree.h b/external/badvpn_dns/client/FrameDecider_groups_tree.h deleted file mode 100644 index b52a947..0000000 --- a/external/badvpn_dns/client/FrameDecider_groups_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDGroupsTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_group_entry -#define SAVL_PARAM_TYPE_KEY uint32_t -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->group, (entry2)->group) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->group) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/external/badvpn_dns/client/FrameDecider_macs_tree.h b/external/badvpn_dns/client/FrameDecider_macs_tree.h deleted file mode 100644 index 2145918..0000000 --- a/external/badvpn_dns/client/FrameDecider_macs_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDMacsTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_mac_entry -#define SAVL_PARAM_TYPE_KEY FDMacsTree_key -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_macs((entry1)->mac, (entry2)->mac) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) compare_macs((key1), (entry2)->mac) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/external/badvpn_dns/client/FrameDecider_multicast_tree.h b/external/badvpn_dns/client/FrameDecider_multicast_tree.h deleted file mode 100644 index 2731684..0000000 --- a/external/badvpn_dns/client/FrameDecider_multicast_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDMulticastTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_group_entry -#define SAVL_PARAM_TYPE_KEY uint32_t -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->master.sig, (entry2)->master.sig) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->master.sig) -#define SAVL_PARAM_MEMBER_NODE master.tree_node diff --git a/external/badvpn_dns/client/PasswordListener.c b/external/badvpn_dns/client/PasswordListener.c deleted file mode 100644 index 5ec573b..0000000 --- a/external/badvpn_dns/client/PasswordListener.c +++ /dev/null @@ -1,374 +0,0 @@ -/** - * @file PasswordListener.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <prerror.h> - -#include <ssl.h> - -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <base/BLog.h> -#include <security/BRandom.h> -#include <nspr_support/DummyPRFileDesc.h> - -#include <client/PasswordListener.h> - -#include <generated/blog_channel_PasswordListener.h> - -static int password_comparator (void *user, uint64_t *p1, uint64_t *p2); -static void remove_client (struct PasswordListenerClient *client); -static void listener_handler (PasswordListener *l); -static void client_connection_handler (struct PasswordListenerClient *client, int event); -static void client_sslcon_handler (struct PasswordListenerClient *client, int event); -static void client_receiver_handler (struct PasswordListenerClient *client); - -int password_comparator (void *user, uint64_t *p1, uint64_t *p2) -{ - return B_COMPARE(*p1, *p2); -} - -void remove_client (struct PasswordListenerClient *client) -{ - PasswordListener *l = client->l; - - // stop using any buffers before they get freed - if (l->ssl) { - BSSLConnection_ReleaseBuffers(&client->sslcon); - } - - // free receiver - SingleStreamReceiver_Free(&client->receiver); - - // free SSL - if (l->ssl) { - BSSLConnection_Free(&client->sslcon); - ASSERT_FORCE(PR_Close(client->sock->ssl_prfd) == PR_SUCCESS) - } - - // free connection interfaces - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - - // free connection - BConnection_Free(&client->sock->con); - - // free sslsocket structure - free(client->sock); - - // move to free list - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); -} - -void listener_handler (PasswordListener *l) -{ - DebugObject_Access(&l->d_obj); - - // obtain client entry - if (LinkedList1_IsEmpty(&l->clients_free)) { - struct PasswordListenerClient *client = UPPER_OBJECT(LinkedList1_GetFirst(&l->clients_used), struct PasswordListenerClient, list_node); - remove_client(client); - } - struct PasswordListenerClient *client = UPPER_OBJECT(LinkedList1_GetLast(&l->clients_free), struct PasswordListenerClient, list_node); - LinkedList1_Remove(&l->clients_free, &client->list_node); - LinkedList1_Append(&l->clients_used, &client->list_node); - - // allocate sslsocket structure - if (!(client->sock = (sslsocket *)malloc(sizeof(*client->sock)))) { - BLog(BLOG_ERROR, "malloc failedt"); - goto fail0; - } - - // accept connection - if (!BConnection_Init(&client->sock->con, BConnection_source_listener(&l->listener, NULL), l->bsys, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - BLog(BLOG_INFO, "Connection accepted"); - - // init connection interfaces - BConnection_SendAsync_Init(&client->sock->con); - BConnection_RecvAsync_Init(&client->sock->con); - - StreamPassInterface *send_if = BConnection_SendAsync_GetIf(&client->sock->con); - StreamRecvInterface *recv_if = BConnection_RecvAsync_GetIf(&client->sock->con); - - if (l->ssl) { - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&client->sock->bottom_prfd, send_if, recv_if, l->twd, l->ssl_flags)) { - BLog(BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail2; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(client->sock->ssl_prfd = SSL_ImportFD(l->model_prfd, &client->sock->bottom_prfd))) { - ASSERT_FORCE(PR_Close(&client->sock->bottom_prfd) == PR_SUCCESS) - goto fail2; - } - - // set server mode - if (SSL_ResetHandshake(client->sock->ssl_prfd, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail3; - } - - // set require client certificate - if (SSL_OptionSet(client->sock->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed"); - goto fail3; - } - if (SSL_OptionSet(client->sock->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed"); - goto fail3; - } - - // initialize SSLConnection - BSSLConnection_Init(&client->sslcon, client->sock->ssl_prfd, 0, BReactor_PendingGroup(l->bsys), client, (BSSLConnection_handler)client_sslcon_handler); - - send_if = BSSLConnection_GetSendIf(&client->sslcon); - recv_if = BSSLConnection_GetRecvIf(&client->sslcon); - } - - // init receiver - SingleStreamReceiver_Init(&client->receiver, (uint8_t *)&client->recv_buffer, sizeof(client->recv_buffer), recv_if, BReactor_PendingGroup(l->bsys), client, (SingleStreamReceiver_handler)client_receiver_handler); - - return; - - // cleanup on error -fail3: - if (l->ssl) { - ASSERT_FORCE(PR_Close(client->sock->ssl_prfd) == PR_SUCCESS) - } -fail2: - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - BConnection_Free(&client->sock->con); -fail1: - free(client->sock); -fail0: - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); -} - -void client_connection_handler (struct PasswordListenerClient *client, int event) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - BLog(BLOG_INFO, "connection closed"); - } else { - BLog(BLOG_INFO, "connection error"); - } - - remove_client(client); -} - -void client_sslcon_handler (struct PasswordListenerClient *client, int event) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - ASSERT(l->ssl) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - BLog(BLOG_INFO, "SSL error"); - - remove_client(client); -} - -void client_receiver_handler (struct PasswordListenerClient *client) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - - // check password - uint64_t received_pass = ltoh64(client->recv_buffer); - BAVLNode *pw_tree_node = BAVL_LookupExact(&l->passwords, &received_pass); - if (!pw_tree_node) { - BLog(BLOG_WARNING, "unknown password"); - remove_client(client); - return; - } - PasswordListener_pwentry *pw_entry = UPPER_OBJECT(pw_tree_node, PasswordListener_pwentry, tree_node); - - BLog(BLOG_INFO, "Password recognized"); - - // remove password entry - BAVL_Remove(&l->passwords, &pw_entry->tree_node); - - // stop using any buffers before they get freed - if (l->ssl) { - BSSLConnection_ReleaseBuffers(&client->sslcon); - } - - // free receiver - SingleStreamReceiver_Free(&client->receiver); - - if (l->ssl) { - // free SSL connection - BSSLConnection_Free(&client->sslcon); - } else { - // free connection interfaces - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - } - - // remove connection handler - BConnection_SetHandlers(&client->sock->con, NULL, NULL); - - // move client entry to free list - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); - - // give the socket to the handler - pw_entry->handler_client(pw_entry->user, client->sock); - return; -} - -int PasswordListener_Init (PasswordListener *l, BReactor *bsys, BThreadWorkDispatcher *twd, BAddr listen_addr, int max_clients, int ssl, int ssl_flags, CERTCertificate *cert, SECKEYPrivateKey *key) -{ - ASSERT(BConnection_AddressSupported(listen_addr)) - ASSERT(max_clients > 0) - ASSERT(ssl == 0 || ssl == 1) - - // init arguments - l->bsys = bsys; - l->twd = twd; - l->ssl = ssl; - l->ssl_flags = ssl_flags; - - // allocate client entries - if (!(l->clients_data = (struct PasswordListenerClient *)BAllocArray(max_clients, sizeof(struct PasswordListenerClient)))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - if (l->ssl) { - // initialize model SSL fd - DummyPRFileDesc_Create(&l->model_dprfd); - if (!(l->model_prfd = SSL_ImportFD(NULL, &l->model_dprfd))) { - BLog(BLOG_ERROR, "SSL_ImportFD failed"); - ASSERT_FORCE(PR_Close(&l->model_dprfd) == PR_SUCCESS) - goto fail1; - } - - // set server certificate - if (SSL_ConfigSecureServer(l->model_prfd, cert, key, NSS_FindCertKEAType(cert)) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigSecureServer failed"); - goto fail2; - } - } - - // initialize client entries - LinkedList1_Init(&l->clients_free); - LinkedList1_Init(&l->clients_used); - for (int i = 0; i < max_clients; i++) { - struct PasswordListenerClient *conn = &l->clients_data[i]; - conn->l = l; - LinkedList1_Append(&l->clients_free, &conn->list_node); - } - - // initialize passwords tree - BAVL_Init(&l->passwords, OFFSET_DIFF(PasswordListener_pwentry, password, tree_node), (BAVL_comparator)password_comparator, NULL); - - // initialize listener - if (!BListener_Init(&l->listener, listen_addr, l->bsys, l, (BListener_handler)listener_handler)) { - BLog(BLOG_ERROR, "Listener_Init failed"); - goto fail2; - } - - DebugObject_Init(&l->d_obj); - return 1; - - // cleanup -fail2: - if (l->ssl) { - ASSERT_FORCE(PR_Close(l->model_prfd) == PR_SUCCESS) - } -fail1: - BFree(l->clients_data); -fail0: - return 0; -} - -void PasswordListener_Free (PasswordListener *l) -{ - DebugObject_Free(&l->d_obj); - - // free clients - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&l->clients_used)) { - struct PasswordListenerClient *client = UPPER_OBJECT(node, struct PasswordListenerClient, list_node); - remove_client(client); - } - - // free listener - BListener_Free(&l->listener); - - // free model SSL file descriptor - if (l->ssl) { - ASSERT_FORCE(PR_Close(l->model_prfd) == PR_SUCCESS) - } - - // free client entries - BFree(l->clients_data); -} - -uint64_t PasswordListener_AddEntry (PasswordListener *l, PasswordListener_pwentry *entry, PasswordListener_handler_client handler_client, void *user) -{ - DebugObject_Access(&l->d_obj); - - while (1) { - // generate password - BRandom_randomize((uint8_t *)&entry->password, sizeof(entry->password)); - - // try inserting - if (BAVL_Insert(&l->passwords, &entry->tree_node, NULL)) { - break; - } - } - - entry->handler_client = handler_client; - entry->user = user; - - return entry->password; -} - -void PasswordListener_RemoveEntry (PasswordListener *l, PasswordListener_pwentry *entry) -{ - DebugObject_Access(&l->d_obj); - - // remove - BAVL_Remove(&l->passwords, &entry->tree_node); -} diff --git a/external/badvpn_dns/client/PasswordListener.h b/external/badvpn_dns/client/PasswordListener.h deleted file mode 100644 index bbc0bd1..0000000 --- a/external/badvpn_dns/client/PasswordListener.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file PasswordListener.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used to listen on a socket, accept clients and identify them - * based on a number they send. - */ - -#ifndef BADVPN_CLIENT_PASSWORDLISTENER_H -#define BADVPN_CLIENT_PASSWORDLISTENER_H - -#include <stdint.h> - -#include <prio.h> - -#include <cert.h> -#include <keyhi.h> - -#include <misc/debug.h> -#include <misc/sslsocket.h> -#include <structure/LinkedList1.h> -#include <structure/BAVL.h> -#include <base/DebugObject.h> -#include <flow/SingleStreamReceiver.h> -#include <system/BConnection.h> -#include <nspr_support/BSSLConnection.h> - -/** - * Handler function called when a client identifies itself with a password - * belonging to one of the password entries. - * The password entry is unregistered before the handler is called - * and must not be unregistered again. - * - * @param user as in {@link PasswordListener_AddEntry} - * @param sock structure containing a {@link BConnection} and, if TLS is enabled, - * the SSL socket with the bottom layer connected to the async interfaces - * of the {@link BConnection} object. The structure was allocated with - * malloc() and the user is responsible for freeing it. - */ -typedef void (*PasswordListener_handler_client) (void *user, sslsocket *sock); - -struct PasswordListenerClient; - -/** - * Object used to listen on a socket, accept clients and identify them - * based on a number they send. - */ -typedef struct { - BReactor *bsys; - BThreadWorkDispatcher *twd; - int ssl; - int ssl_flags; - PRFileDesc model_dprfd; - PRFileDesc *model_prfd; - struct PasswordListenerClient *clients_data; - LinkedList1 clients_free; - LinkedList1 clients_used; - BAVL passwords; - BListener listener; - DebugObject d_obj; -} PasswordListener; - -typedef struct { - uint64_t password; - BAVLNode tree_node; - PasswordListener_handler_client handler_client; - void *user; -} PasswordListener_pwentry; - -struct PasswordListenerClient { - PasswordListener *l; - LinkedList1Node list_node; - sslsocket *sock; - BSSLConnection sslcon; - SingleStreamReceiver receiver; - uint64_t recv_buffer; -}; - -/** - * Initializes the object. - * - * @param l the object - * @param bsys reactor we live in - * @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL - * operations in threads. - * @param listen_addr address to listen on. Must be supported according to {@link BConnection_AddressSupported}. - * @param max_clients maximum number of client to hold until they are identified. - * Must be >0. - * @param ssl whether to use TLS. Must be 1 or 0. - * @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to - * request performing SSL operations in threads. - * @param cert if using TLS, the server certificate - * @param key if using TLS, the private key - * @return 1 on success, 0 on failure - */ -int PasswordListener_Init (PasswordListener *l, BReactor *bsys, BThreadWorkDispatcher *twd, BAddr listen_addr, int max_clients, int ssl, int ssl_flags, CERTCertificate *cert, SECKEYPrivateKey *key) WARN_UNUSED; - -/** - * Frees the object. - * - * @param l the object - */ -void PasswordListener_Free (PasswordListener *l); - -/** - * Registers a password entry. - * - * @param l the object - * @param entry uninitialized entry structure - * @param handler_client handler function to call when a client identifies - * with the password which this function returns - * @param user value to pass to handler function - * @return password which a client should send to be recognized and - * dispatched to the handler function. Should be treated as a numeric - * value, which a client should as a little-endian 64-bit unsigned integer - * when it connects. - */ -uint64_t PasswordListener_AddEntry (PasswordListener *l, PasswordListener_pwentry *entry, PasswordListener_handler_client handler_client, void *user); - -/** - * Unregisters a password entry. - * Note that when a client is dispatched, its entry is unregistered - * automatically and must not be unregistered again here. - * - * @param l the object - * @param entry entry to unregister - */ -void PasswordListener_RemoveEntry (PasswordListener *l, PasswordListener_pwentry *entry); - -#endif diff --git a/external/badvpn_dns/client/PeerChat.c b/external/badvpn_dns/client/PeerChat.c deleted file mode 100644 index d9dd966..0000000 --- a/external/badvpn_dns/client/PeerChat.c +++ /dev/null @@ -1,433 +0,0 @@ -/** - * @file PeerChat.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <ssl.h> -#include <sslerr.h> - -#include <misc/byteorder.h> -#include <security/BRandom.h> - -#include "PeerChat.h" - -#include <generated/blog_channel_PeerChat.h> - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void report_error (PeerChat *o) -{ - DebugError_AssertNoError(&o->d_err); - - DEBUGERROR(&o->d_err, o->handler_error(o->user)) - return; -} - -static void recv_job_handler (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv_data_len >= 0) - ASSERT(o->recv_data_len <= SC_MAX_MSGLEN) - - int data_len = o->recv_data_len; - - // set no received data - o->recv_data_len = -1; - -#ifdef PEERCHAT_SIMULATE_ERROR - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < PEERCHAT_SIMULATE_ERROR) { - PeerLog(o, BLOG_ERROR, "simulate error"); - report_error(o); - return; - } -#endif - - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - // buffer data - if (!SimpleStreamBuffer_Write(&o->ssl_recv_buf, o->recv_data, data_len)) { - PeerLog(o, BLOG_ERROR, "out of recv buffer"); - report_error(o); - return; - } - } else { - // call message handler - o->handler_message(o->user, o->recv_data, data_len); - return; - } -} - -static void ssl_con_handler (PeerChat *o, int event) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - PeerLog(o, BLOG_ERROR, "SSL error"); - - report_error(o); - return; -} - -static SECStatus client_auth_data_callback (PeerChat *o, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT) - - CERTCertificate *cert = CERT_DupCertificate(o->ssl_cert); - if (!cert) { - PeerLog(o, BLOG_ERROR, "CERT_DupCertificate failed"); - goto fail0; - } - - SECKEYPrivateKey *key = SECKEY_CopyPrivateKey(o->ssl_key); - if (!key) { - PeerLog(o, BLOG_ERROR, "SECKEY_CopyPrivateKey failed"); - goto fail1; - } - - *pRetCert = cert; - *pRetKey = key; - return SECSuccess; - -fail1: - CERT_DestroyCertificate(cert); -fail0: - return SECFailure; -} - -static SECStatus auth_certificate_callback (PeerChat *o, PRFileDesc *fd, PRBool checkSig, PRBool isServer) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - - // This callback is used to bypass checking the server's domain name, as peers - // don't have domain names. We byte-compare the certificate to the one reported - // by the server anyway. - - SECStatus ret = SECFailure; - - CERTCertificate *cert = SSL_PeerCertificate(o->ssl_prfd); - if (!cert) { - PeerLog(o, BLOG_ERROR, "SSL_PeerCertificate failed"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail1; - } - - SECCertUsage cert_usage = (o->ssl_mode == PEERCHAT_SSL_CLIENT ? certUsageSSLServer : certUsageSSLClient); - - if (CERT_VerifyCertNow(CERT_GetDefaultCertDB(), cert, PR_TRUE, cert_usage, SSL_RevealPinArg(o->ssl_prfd)) != SECSuccess) { - goto fail2; - } - - // compare to certificate provided by the server - SECItem der = cert->derCert; - if (der.len != o->ssl_peer_cert_len || memcmp(der.data, o->ssl_peer_cert, der.len)) { - PeerLog(o, BLOG_ERROR, "peer certificate doesn't match"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail2; - } - - ret = SECSuccess; - -fail2: - CERT_DestroyCertificate(cert); -fail1: - return ret; -} - -static void ssl_recv_if_handler_send (PeerChat *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // accept packet - PacketPassInterface_Done(&o->ssl_recv_if); - - // call message handler - o->handler_message(o->user, data, data_len); - return; -} - -static void ssl_recv_decoder_handler_error (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - - PeerLog(o, BLOG_ERROR, "decoder error"); - - report_error(o); - return; -} - -int PeerChat_Init (PeerChat *o, peerid_t peer_id, int ssl_mode, int ssl_flags, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key, - uint8_t *ssl_peer_cert, int ssl_peer_cert_len, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, - BLog_logfunc logfunc, - PeerChat_handler_error handler_error, - PeerChat_handler_message handler_message) -{ - ASSERT(ssl_mode == PEERCHAT_SSL_NONE || ssl_mode == PEERCHAT_SSL_CLIENT || ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(ssl_mode == PEERCHAT_SSL_NONE || ssl_peer_cert_len >= 0) - ASSERT(logfunc) - ASSERT(handler_error) - ASSERT(handler_message) - - // init arguments - o->ssl_mode = ssl_mode; - o->ssl_cert = ssl_cert; - o->ssl_key = ssl_key; - o->ssl_peer_cert = ssl_peer_cert; - o->ssl_peer_cert_len = ssl_peer_cert_len; - o->user = user; - o->logfunc = logfunc; - o->handler_error = handler_error; - o->handler_message = handler_message; - - // init copier - PacketCopier_Init(&o->copier, SC_MAX_MSGLEN, pg); - - // init SC encoder - SCOutmsgEncoder_Init(&o->sc_encoder, peer_id, PacketCopier_GetOutput(&o->copier), pg); - - // init PacketProto encoder - PacketProtoEncoder_Init(&o->pp_encoder, SCOutmsgEncoder_GetOutput(&o->sc_encoder), pg); - - // init recv job - BPending_Init(&o->recv_job, pg, (BPending_handler)recv_job_handler, o); - - // set no received data - o->recv_data_len = -1; - - PacketPassInterface *send_buf_output = PacketCopier_GetInput(&o->copier); - - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - // init receive buffer - if (!SimpleStreamBuffer_Init(&o->ssl_recv_buf, PEERCHAT_SSL_RECV_BUF_SIZE, pg)) { - PeerLog(o, BLOG_ERROR, "SimpleStreamBuffer_Init failed"); - goto fail1; - } - - // init SSL StreamPacketSender - StreamPacketSender_Init(&o->ssl_sp_sender, send_buf_output, pg); - - // init SSL bottom prfd - if (!BSSLConnection_MakeBackend(&o->ssl_bottom_prfd, StreamPacketSender_GetInput(&o->ssl_sp_sender), SimpleStreamBuffer_GetOutput(&o->ssl_recv_buf), twd, ssl_flags)) { - PeerLog(o, BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail2; - } - - // init SSL prfd - if (!(o->ssl_prfd = SSL_ImportFD(NULL, &o->ssl_bottom_prfd))) { - ASSERT_FORCE(PR_Close(&o->ssl_bottom_prfd) == PR_SUCCESS) - PeerLog(o, BLOG_ERROR, "SSL_ImportFD failed"); - goto fail2; - } - - // set client or server mode - if (SSL_ResetHandshake(o->ssl_prfd, (o->ssl_mode == PEERCHAT_SSL_SERVER ? PR_TRUE : PR_FALSE)) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail3; - } - - if (o->ssl_mode == PEERCHAT_SSL_SERVER) { - // set server certificate - if (SSL_ConfigSecureServer(o->ssl_prfd, o->ssl_cert, o->ssl_key, NSS_FindCertKEAType(o->ssl_cert)) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_ConfigSecureServer failed"); - goto fail3; - } - - // set require client certificate - if (SSL_OptionSet(o->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed"); - goto fail3; - } - if (SSL_OptionSet(o->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed"); - goto fail3; - } - } else { - // set client certificate callback - if (SSL_GetClientAuthDataHook(o->ssl_prfd, (SSLGetClientAuthData)client_auth_data_callback, o) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail3; - } - } - - // set verify peer certificate hook - if (SSL_AuthCertificateHook(o->ssl_prfd, (SSLAuthCertificate)auth_certificate_callback, o) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail3; - } - - // init SSL connection - BSSLConnection_Init(&o->ssl_con, o->ssl_prfd, 0, pg, o, (BSSLConnection_handler)ssl_con_handler); - - // init SSL PacketStreamSender - PacketStreamSender_Init(&o->ssl_ps_sender, BSSLConnection_GetSendIf(&o->ssl_con), sizeof(struct packetproto_header) + SC_MAX_MSGLEN, pg); - - // init SSL copier - PacketCopier_Init(&o->ssl_copier, SC_MAX_MSGLEN, pg); - - // init SSL encoder - PacketProtoEncoder_Init(&o->ssl_encoder, PacketCopier_GetOutput(&o->ssl_copier), pg); - - // init SSL buffer - if (!SinglePacketBuffer_Init(&o->ssl_buffer, PacketProtoEncoder_GetOutput(&o->ssl_encoder), PacketStreamSender_GetInput(&o->ssl_ps_sender), pg)) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail4; - } - - // init receive interface - PacketPassInterface_Init(&o->ssl_recv_if, SC_MAX_MSGLEN, (PacketPassInterface_handler_send)ssl_recv_if_handler_send, o, pg); - - // init receive decoder - if (!PacketProtoDecoder_Init(&o->ssl_recv_decoder, BSSLConnection_GetRecvIf(&o->ssl_con), &o->ssl_recv_if, pg, o, (PacketProtoDecoder_handler_error)ssl_recv_decoder_handler_error)) { - PeerLog(o, BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail5; - } - - send_buf_output = PacketCopier_GetInput(&o->ssl_copier); - } - - // init send writer - BufferWriter_Init(&o->send_writer, SC_MAX_MSGLEN, pg); - - // init send buffer - if (!PacketBuffer_Init(&o->send_buf, BufferWriter_GetOutput(&o->send_writer), send_buf_output, PEERCHAT_SEND_BUF_SIZE, pg)) { - PeerLog(o, BLOG_ERROR, "PacketBuffer_Init failed"); - goto fail6; - } - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); - return 1; - -fail6: - BufferWriter_Free(&o->send_writer); - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - PacketProtoDecoder_Free(&o->ssl_recv_decoder); -fail5: - PacketPassInterface_Free(&o->ssl_recv_if); - SinglePacketBuffer_Free(&o->ssl_buffer); -fail4: - PacketProtoEncoder_Free(&o->ssl_encoder); - PacketCopier_Free(&o->ssl_copier); - PacketStreamSender_Free(&o->ssl_ps_sender); - BSSLConnection_Free(&o->ssl_con); -fail3: - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) -fail2: - StreamPacketSender_Free(&o->ssl_sp_sender); - SimpleStreamBuffer_Free(&o->ssl_recv_buf); - } -fail1: - BPending_Free(&o->recv_job); - PacketProtoEncoder_Free(&o->pp_encoder); - SCOutmsgEncoder_Free(&o->sc_encoder); - PacketCopier_Free(&o->copier); - return 0; -} - -void PeerChat_Free (PeerChat *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // stop using any buffers before they get freed - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - BSSLConnection_ReleaseBuffers(&o->ssl_con); - } - - PacketBuffer_Free(&o->send_buf); - BufferWriter_Free(&o->send_writer); - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - PacketProtoDecoder_Free(&o->ssl_recv_decoder); - PacketPassInterface_Free(&o->ssl_recv_if); - SinglePacketBuffer_Free(&o->ssl_buffer); - PacketProtoEncoder_Free(&o->ssl_encoder); - PacketCopier_Free(&o->ssl_copier); - PacketStreamSender_Free(&o->ssl_ps_sender); - BSSLConnection_Free(&o->ssl_con); - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) - StreamPacketSender_Free(&o->ssl_sp_sender); - SimpleStreamBuffer_Free(&o->ssl_recv_buf); - } - BPending_Free(&o->recv_job); - PacketProtoEncoder_Free(&o->pp_encoder); - SCOutmsgEncoder_Free(&o->sc_encoder); - PacketCopier_Free(&o->copier); -} - -PacketRecvInterface * PeerChat_GetSendOutput (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - - return PacketProtoEncoder_GetOutput(&o->pp_encoder); -} - -void PeerChat_InputReceived (PeerChat *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv_data_len == -1) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // remember data - o->recv_data = data; - o->recv_data_len = data_len; - - // set received job - BPending_Set(&o->recv_job); -} - -int PeerChat_StartMessage (PeerChat *o, uint8_t **data) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - return BufferWriter_StartPacket(&o->send_writer, data); -} - -void PeerChat_EndMessage (PeerChat *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - BufferWriter_EndPacket(&o->send_writer, data_len); -} diff --git a/external/badvpn_dns/client/PeerChat.h b/external/badvpn_dns/client/PeerChat.h deleted file mode 100644 index 674e374..0000000 --- a/external/badvpn_dns/client/PeerChat.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file PeerChat.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_PEERCHAT_H -#define BADVPN_PEERCHAT_H - -#include <cert.h> -#include <keyhi.h> - -#include <protocol/packetproto.h> -#include <protocol/scproto.h> -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <base/BLog.h> -#include <flow/SinglePacketSender.h> -#include <flow/PacketProtoEncoder.h> -#include <flow/PacketCopier.h> -#include <flow/StreamPacketSender.h> -#include <flow/PacketStreamSender.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketBuffer.h> -#include <flow/BufferWriter.h> -#include <nspr_support/BSSLConnection.h> -#include <client/SCOutmsgEncoder.h> -#include <client/SimpleStreamBuffer.h> - -#define PEERCHAT_SSL_NONE 0 -#define PEERCHAT_SSL_CLIENT 1 -#define PEERCHAT_SSL_SERVER 2 - -#define PEERCHAT_SSL_RECV_BUF_SIZE 4096 -#define PEERCHAT_SEND_BUF_SIZE 200 - -//#define PEERCHAT_SIMULATE_ERROR 40 - -typedef void (*PeerChat_handler_error) (void *user); -typedef void (*PeerChat_handler_message) (void *user, uint8_t *data, int data_len); - -typedef struct { - int ssl_mode; - CERTCertificate *ssl_cert; - SECKEYPrivateKey *ssl_key; - uint8_t *ssl_peer_cert; - int ssl_peer_cert_len; - void *user; - BLog_logfunc logfunc; - PeerChat_handler_error handler_error; - PeerChat_handler_message handler_message; - - // transport - PacketProtoEncoder pp_encoder; - SCOutmsgEncoder sc_encoder; - PacketCopier copier; - BPending recv_job; - uint8_t *recv_data; - int recv_data_len; - - // SSL transport - StreamPacketSender ssl_sp_sender; - SimpleStreamBuffer ssl_recv_buf; - - // SSL connection - PRFileDesc ssl_bottom_prfd; - PRFileDesc *ssl_prfd; - BSSLConnection ssl_con; - - // SSL higher layer - PacketStreamSender ssl_ps_sender; - SinglePacketBuffer ssl_buffer; - PacketProtoEncoder ssl_encoder; - PacketCopier ssl_copier; - PacketProtoDecoder ssl_recv_decoder; - PacketPassInterface ssl_recv_if; - - // higher layer send buffer - PacketBuffer send_buf; - BufferWriter send_writer; - - DebugError d_err; - DebugObject d_obj; -} PeerChat; - -int PeerChat_Init (PeerChat *o, peerid_t peer_id, int ssl_mode, int ssl_flags, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key, - uint8_t *ssl_peer_cert, int ssl_peer_cert_len, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, - BLog_logfunc logfunc, - PeerChat_handler_error handler_error, - PeerChat_handler_message handler_message) WARN_UNUSED; -void PeerChat_Free (PeerChat *o); -PacketRecvInterface * PeerChat_GetSendOutput (PeerChat *o); -void PeerChat_InputReceived (PeerChat *o, uint8_t *data, int data_len); -int PeerChat_StartMessage (PeerChat *o, uint8_t **data) WARN_UNUSED; -void PeerChat_EndMessage (PeerChat *o, int data_len); - -#endif diff --git a/external/badvpn_dns/client/SCOutmsgEncoder.c b/external/badvpn_dns/client/SCOutmsgEncoder.c deleted file mode 100644 index 83e8b27..0000000 --- a/external/badvpn_dns/client/SCOutmsgEncoder.c +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file SCOutmsgEncoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <limits.h> -#include <string.h> - -#include <misc/balign.h> -#include <misc/debug.h> -#include <misc/byteorder.h> - -#include "SCOutmsgEncoder.h" - -static void output_handler_recv (SCOutmsgEncoder *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->output_packet) - ASSERT(data) - - // schedule receive - o->output_packet = data; - PacketRecvInterface_Receiver_Recv(o->input, o->output_packet + SCOUTMSG_OVERHEAD); -} - -static void input_handler_done (SCOutmsgEncoder *o, int in_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->output_packet) - - // write SC header - struct sc_header header; - header.type = htol8(SCID_OUTMSG); - memcpy(o->output_packet, &header, sizeof(header)); - - // write outmsg - struct sc_client_outmsg outmsg; - outmsg.clientid = htol16(o->peer_id); - memcpy(o->output_packet + sizeof(header), &outmsg, sizeof(outmsg)); - - // finish output packet - o->output_packet = NULL; - PacketRecvInterface_Done(&o->output, SCOUTMSG_OVERHEAD + in_len); -} - -void SCOutmsgEncoder_Init (SCOutmsgEncoder *o, peerid_t peer_id, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - SCOUTMSG_OVERHEAD) - - // init arguments - o->peer_id = peer_id; - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketRecvInterface_Init(&o->output, SCOUTMSG_OVERHEAD + PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no output packet - o->output_packet = NULL; - - DebugObject_Init(&o->d_obj); -} - -void SCOutmsgEncoder_Free (SCOutmsgEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * SCOutmsgEncoder_GetOutput (SCOutmsgEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/client/SCOutmsgEncoder.h b/external/badvpn_dns/client/SCOutmsgEncoder.h deleted file mode 100644 index 05d4cb2..0000000 --- a/external/badvpn_dns/client/SCOutmsgEncoder.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file SCOutmsgEncoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SCOUTMSGENCODER_H -#define BADVPN_SCOUTMSGENCODER_H - -#include <protocol/scproto.h> -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -#define SCOUTMSG_OVERHEAD (sizeof(struct sc_header) + sizeof(struct sc_client_outmsg)) - -/** - * A {@link PacketRecvInterface} layer which encodes SCProto outgoing messages. - */ -typedef struct { - peerid_t peer_id; - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *output_packet; - DebugObject d_obj; -} SCOutmsgEncoder; - -/** - * Initializes the object. - * - * @param o the object - * @param peer_id destination peer for messages - * @param input input interface. Its MTU muse be <= (INT_MAX - SCOUTMSG_OVERHEAD). - * @param pg pending group we live in - */ -void SCOutmsgEncoder_Init (SCOutmsgEncoder *o, peerid_t peer_id, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SCOutmsgEncoder_Free (SCOutmsgEncoder *o); - -/** - * Returns the output interface. - * The MTU of the interface will be (SCOUTMSG_OVERHEAD + input MTU). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SCOutmsgEncoder_GetOutput (SCOutmsgEncoder *o); - -#endif diff --git a/external/badvpn_dns/client/SPProtoDecoder.c b/external/badvpn_dns/client/SPProtoDecoder.c deleted file mode 100644 index 0855162..0000000 --- a/external/badvpn_dns/client/SPProtoDecoder.c +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @file SPProtoDecoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/balign.h> -#include <misc/byteorder.h> -#include <security/BHash.h> - -#include "SPProtoDecoder.h" - -#include <generated/blog_channel_SPProtoDecoder.h> - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void decode_work_func (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->in_len <= o->input_mtu) - - uint8_t *in = o->in; - int in_len = o->in_len; - - o->tw_out_len = -1; - - uint8_t *plaintext; - int plaintext_len; - - // decrypt if needed - if (!SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - plaintext = in; - plaintext_len = in_len; - } else { - // input must be a multiple of blocks size - if (in_len % o->enc_block_size != 0) { - PeerLog(o, BLOG_WARNING, "packet size not a multiple of block size"); - return; - } - - // input must have an IV block - if (in_len < o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet does not have an IV"); - return; - } - - // check if we have encryption key - if (!o->have_encryption_key) { - PeerLog(o, BLOG_WARNING, "have no encryption key"); - return; - } - - // copy IV as BEncryption_Decrypt changes the IV - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - memcpy(iv, in, o->enc_block_size); - - // decrypt - uint8_t *ciphertext = in + o->enc_block_size; - int ciphertext_len = in_len - o->enc_block_size; - plaintext = o->buf; - BEncryption_Decrypt(&o->encryptor, ciphertext, plaintext, ciphertext_len, iv); - - // read padding - if (ciphertext_len < o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet does not have a padding block"); - return; - } - int i; - for (i = ciphertext_len - 1; i >= ciphertext_len - o->enc_block_size; i--) { - if (plaintext[i] == 1) { - break; - } - if (plaintext[i] != 0) { - PeerLog(o, BLOG_WARNING, "packet padding wrong (nonzero byte)"); - return; - } - } - if (i < ciphertext_len - o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet padding wrong (all zeroes)"); - return; - } - plaintext_len = i; - } - - // check for header - if (plaintext_len < SPPROTO_HEADER_LEN(o->sp_params)) { - PeerLog(o, BLOG_WARNING, "packet has no header"); - return; - } - uint8_t *header = plaintext; - - // check data length - if (plaintext_len - SPPROTO_HEADER_LEN(o->sp_params) > o->output_mtu) { - PeerLog(o, BLOG_WARNING, "packet too long"); - return; - } - - // check OTP - if (SPPROTO_HAVE_OTP(o->sp_params)) { - // remember seed and OTP (can't check from here) - struct spproto_otpdata header_otpd; - memcpy(&header_otpd, header + SPPROTO_HEADER_OTPDATA_OFF(o->sp_params), sizeof(header_otpd)); - o->tw_out_seed_id = ltoh16(header_otpd.seed_id); - o->tw_out_otp = header_otpd.otp; - } - - // check hash - if (SPPROTO_HAVE_HASH(o->sp_params)) { - uint8_t *header_hash = header + SPPROTO_HEADER_HASH_OFF(o->sp_params); - // read hash - uint8_t hash[BHASH_MAX_SIZE]; - memcpy(hash, header_hash, o->hash_size); - // zero hash in packet - memset(header_hash, 0, o->hash_size); - // calculate hash - uint8_t hash_calc[BHASH_MAX_SIZE]; - BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash_calc); - // set hash field to its original value - memcpy(header_hash, hash, o->hash_size); - // compare hashes - if (memcmp(hash, hash_calc, o->hash_size)) { - PeerLog(o, BLOG_WARNING, "packet has wrong hash"); - return; - } - } - - // return packet - o->tw_out = plaintext + SPPROTO_HEADER_LEN(o->sp_params); - o->tw_out_len = plaintext_len - SPPROTO_HEADER_LEN(o->sp_params); -} - -static void decode_work_handler (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->tw_have) - DebugObject_Access(&o->d_obj); - - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // check OTP - if (SPPROTO_HAVE_OTP(o->sp_params) && o->tw_out_len >= 0) { - if (!OTPChecker_CheckOTP(&o->otpchecker, o->tw_out_seed_id, o->tw_out_otp)) { - PeerLog(o, BLOG_WARNING, "packet has wrong OTP"); - o->tw_out_len = -1; - } - } - - if (o->tw_out_len < 0) { - // cannot decode, finish input packet - PacketPassInterface_Done(&o->input); - o->in_len = -1; - } else { - // submit decoded packet to output - PacketPassInterface_Sender_Send(o->output, o->tw_out, o->tw_out_len); - } -} - -static void input_handler_send (SPProtoDecoder *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember input - o->in = data; - o->in_len = data_len; - - // start decoding - BThreadWork_Init(&o->tw, o->twd, (BThreadWork_handler_done)decode_work_handler, o, (BThreadWork_work_func)decode_work_func, o); - o->tw_have = 1; -} - -static void output_handler_done (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // finish input packet - PacketPassInterface_Done(&o->input); - o->in_len = -1; -} - -static void maybe_stop_work_and_ignore (SPProtoDecoder *o) -{ - ASSERT(!(o->tw_have) || o->in_len >= 0) - - if (o->tw_have) { - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // ignore packet, receive next one - PacketPassInterface_Done(&o->input); - o->in_len = -1; - } -} - -int SPProtoDecoder_Init (SPProtoDecoder *o, PacketPassInterface *output, struct spproto_security_params sp_params, int num_otp_seeds, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, BLog_logfunc logfunc) -{ - spproto_assert_security_params(sp_params); - ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketPassInterface_GetMTU(output)) >= 0) - ASSERT(!SPPROTO_HAVE_OTP(sp_params) || num_otp_seeds >= 2) - - // init arguments - o->output = output; - o->sp_params = sp_params; - o->twd = twd; - o->user = user; - o->logfunc = logfunc; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // remember output MTU - o->output_mtu = PacketPassInterface_GetMTU(o->output); - - // calculate hash size - if (SPPROTO_HAVE_HASH(o->sp_params)) { - o->hash_size = BHash_size(o->sp_params.hash_mode); - } - - // calculate encryption block and key sizes - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->enc_block_size = BEncryption_cipher_block_size(o->sp_params.encryption_mode); - o->enc_key_size = BEncryption_cipher_key_size(o->sp_params.encryption_mode); - } - - // calculate input MTU - o->input_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->output_mtu); - - // allocate plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - int buf_size = balign_up((SPPROTO_HEADER_LEN(o->sp_params) + o->output_mtu + 1), o->enc_block_size); - if (!(o->buf = (uint8_t *)malloc(buf_size))) { - goto fail0; - } - } - - // init input - PacketPassInterface_Init(&o->input, o->input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // init OTP checker - if (SPPROTO_HAVE_OTP(o->sp_params)) { - if (!OTPChecker_Init(&o->otpchecker, o->sp_params.otp_num, o->sp_params.otp_mode, num_otp_seeds, o->twd)) { - goto fail1; - } - } - - // have no encryption key - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->have_encryption_key = 0; - } - - // have no input packet - o->in_len = -1; - - // have no work - o->tw_have = 0; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketPassInterface_Free(&o->input); - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } -fail0: - return 0; -} - -void SPProtoDecoder_Free (SPProtoDecoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - } - - // free encryptor - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params) && o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // free OTP checker - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPChecker_Free(&o->otpchecker); - } - - // free input - PacketPassInterface_Free(&o->input); - - // free plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } -} - -PacketPassInterface * SPProtoDecoder_GetInput (SPProtoDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void SPProtoDecoder_SetEncryptionKey (SPProtoDecoder *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work_and_ignore(o); - - // free encryptor - if (o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // init encryptor - BEncryption_Init(&o->encryptor, BENCRYPTION_MODE_DECRYPT, o->sp_params.encryption_mode, encryption_key); - - // have encryption key - o->have_encryption_key = 1; -} - -void SPProtoDecoder_RemoveEncryptionKey (SPProtoDecoder *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work_and_ignore(o); - - if (o->have_encryption_key) { - // free encryptor - BEncryption_Free(&o->encryptor); - - // have no encryption key - o->have_encryption_key = 0; - } -} - -void SPProtoDecoder_AddOTPSeed (SPProtoDecoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - OTPChecker_AddSeed(&o->otpchecker, seed_id, key, iv); -} - -void SPProtoDecoder_RemoveOTPSeeds (SPProtoDecoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - OTPChecker_RemoveSeeds(&o->otpchecker); -} - -void SPProtoDecoder_SetHandlers (SPProtoDecoder *o, SPProtoDecoder_otp_handler otp_handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPChecker_SetHandlers(&o->otpchecker, otp_handler, user); - } -} diff --git a/external/badvpn_dns/client/SPProtoDecoder.h b/external/badvpn_dns/client/SPProtoDecoder.h deleted file mode 100644 index 3b5de71..0000000 --- a/external/badvpn_dns/client/SPProtoDecoder.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file SPProtoDecoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes packets according to SPProto. - */ - -#ifndef BADVPN_CLIENT_SPPROTODECODER_H -#define BADVPN_CLIENT_SPPROTODECODER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <protocol/spproto.h> -#include <security/BEncryption.h> -#include <security/OTPChecker.h> -#include <flow/PacketPassInterface.h> - -/** - * Handler called when OTP generation for a new seed is finished. - * - * @param user as in {@link SPProtoDecoder_Init} - */ -typedef void (*SPProtoDecoder_otp_handler) (void *user); - -/** - * Object which decodes packets according to SPProto. - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - PacketPassInterface *output; - struct spproto_security_params sp_params; - BThreadWorkDispatcher *twd; - void *user; - BLog_logfunc logfunc; - int output_mtu; - int hash_size; - int enc_block_size; - int enc_key_size; - int input_mtu; - uint8_t *buf; - PacketPassInterface input; - OTPChecker otpchecker; - int have_encryption_key; - BEncryption encryptor; - uint8_t *in; - int in_len; - int tw_have; - BThreadWork tw; - uint16_t tw_out_seed_id; - otp_t tw_out_otp; - uint8_t *tw_out; - int tw_out_len; - DebugObject d_obj; -} SPProtoDecoder; - -/** - * Initializes the object. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param output output interface. Its MTU must not be too large, i.e. this must hold: - * spproto_carrier_mtu_for_payload_mtu(sp_params, output MTU) >= 0 - * @param sp_params SPProto parameters - * @param encryption_key if using encryption, the encryption key - * @param num_otp_seeds if using OTPs, how many OTP seeds to keep for checking - * receiving packets. Must be >=2 if using OTPs. - * @param pg pending group - * @param twd thread work dispatcher - * @param user argument to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int SPProtoDecoder_Init (SPProtoDecoder *o, PacketPassInterface *output, struct spproto_security_params sp_params, int num_otp_seeds, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void SPProtoDecoder_Free (SPProtoDecoder *o); - -/** - * Returns the input interface. - * The MTU of the input interface will depend on the output MTU and security parameters, - * that is spproto_carrier_mtu_for_payload_mtu(sp_params, output MTU). - * - * @param o the object - * @return input interface - */ -PacketPassInterface * SPProtoDecoder_GetInput (SPProtoDecoder *o); - -/** - * Sets an encryption key for decrypting packets. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void SPProtoDecoder_SetEncryptionKey (SPProtoDecoder *o, uint8_t *encryption_key); - -/** - * Removes an encryption key if one is configured. - * Encryption must be enabled. - * - * @param o the object - */ -void SPProtoDecoder_RemoveEncryptionKey (SPProtoDecoder *o); - -/** - * Starts generating OTPs for a seed to check received packets against. - * OTPs for this seed will not be recognized until the {@link SPProtoDecoder_otp_handler} handler - * is called. - * If OTPs are still being generated for the previous seed, it will be forgotten. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void SPProtoDecoder_AddOTPSeed (SPProtoDecoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes all OTP seeds for checking received packets against. - * OTPs must be enabled. - * - * @param o the object - */ -void SPProtoDecoder_RemoveOTPSeeds (SPProtoDecoder *o); - -/** - * Sets handlers. - * - * @param o the object - * @param otp_handler handler called when OTP generation is finished - * @param user argument to handler - */ -void SPProtoDecoder_SetHandlers (SPProtoDecoder *o, SPProtoDecoder_otp_handler otp_handler, void *user); - -#endif diff --git a/external/badvpn_dns/client/SPProtoEncoder.c b/external/badvpn_dns/client/SPProtoEncoder.c deleted file mode 100644 index fbbab50..0000000 --- a/external/badvpn_dns/client/SPProtoEncoder.c +++ /dev/null @@ -1,436 +0,0 @@ -/** - * @file SPProtoEncoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdlib.h> - -#include <misc/balign.h> -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <security/BRandom.h> -#include <security/BHash.h> - -#include "SPProtoEncoder.h" - -static int can_encode (SPProtoEncoder *o); -static void encode_packet (SPProtoEncoder *o); -static void encode_work_func (SPProtoEncoder *o); -static void encode_work_handler (SPProtoEncoder *o); -static void maybe_encode (SPProtoEncoder *o); -static void output_handler_recv (SPProtoEncoder *o, uint8_t *data); -static void input_handler_done (SPProtoEncoder *o, int data_len); -static void handler_job_hander (SPProtoEncoder *o); -static void otpgenerator_handler (SPProtoEncoder *o); -static void maybe_stop_work (SPProtoEncoder *o); - -static int can_encode (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - - return ( - (!SPPROTO_HAVE_OTP(o->sp_params) || OTPGenerator_GetPosition(&o->otpgen) < o->sp_params.otp_num) && - (!SPPROTO_HAVE_ENCRYPTION(o->sp_params) || o->have_encryption_key) - ); -} - -static void encode_packet (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - ASSERT(can_encode(o)) - - // generate OTP, remember seed ID - if (SPPROTO_HAVE_OTP(o->sp_params)) { - o->tw_seed_id = o->otpgen_seed_id; - o->tw_otp = OTPGenerator_GetOTP(&o->otpgen); - } - - // start work - BThreadWork_Init(&o->tw, o->twd, (BThreadWork_handler_done)encode_work_handler, o, (BThreadWork_work_func)encode_work_func, o); - o->tw_have = 1; - - // schedule OTP warning handler - if (SPPROTO_HAVE_OTP(o->sp_params) && OTPGenerator_GetPosition(&o->otpgen) == o->otp_warning_count) { - BPending_Set(&o->handler_job); - } -} - -static void encode_work_func (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!SPPROTO_HAVE_ENCRYPTION(o->sp_params) || o->have_encryption_key) - - ASSERT(o->in_len <= o->input_mtu) - - // determine plaintext location - uint8_t *plaintext = (SPPROTO_HAVE_ENCRYPTION(o->sp_params) ? o->buf : o->out); - - // plaintext begins with header - uint8_t *header = plaintext; - - // plaintext is header + payload - int plaintext_len = SPPROTO_HEADER_LEN(o->sp_params) + o->in_len; - - // write OTP - if (SPPROTO_HAVE_OTP(o->sp_params)) { - struct spproto_otpdata header_otpd; - header_otpd.seed_id = htol16(o->tw_seed_id); - header_otpd.otp = o->tw_otp; - memcpy(header + SPPROTO_HEADER_OTPDATA_OFF(o->sp_params), &header_otpd, sizeof(header_otpd)); - } - - // write hash - if (SPPROTO_HAVE_HASH(o->sp_params)) { - uint8_t *header_hash = header + SPPROTO_HEADER_HASH_OFF(o->sp_params); - // zero hash field - memset(header_hash, 0, o->hash_size); - // calculate hash - uint8_t hash[BHASH_MAX_SIZE]; - BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash); - // set hash field - memcpy(header_hash, hash, o->hash_size); - } - - int out_len; - - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - // encrypting pad(header + payload) - int cyphertext_len = balign_up((plaintext_len + 1), o->enc_block_size); - - // write padding - plaintext[plaintext_len] = 1; - for (int i = plaintext_len + 1; i < cyphertext_len; i++) { - plaintext[i] = 0; - } - - // generate IV - BRandom_randomize(o->out, o->enc_block_size); - - // copy IV because BEncryption_Encrypt changes the IV - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - memcpy(iv, o->out, o->enc_block_size); - - // encrypt - BEncryption_Encrypt(&o->encryptor, plaintext, o->out + o->enc_block_size, cyphertext_len, iv); - out_len = o->enc_block_size + cyphertext_len; - } else { - out_len = plaintext_len; - } - - // remember length - o->tw_out_len = out_len; -} - -static void encode_work_handler (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(o->tw_have) - - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // finish packet - o->in_len = -1; - o->out_have = 0; - PacketRecvInterface_Done(&o->output, o->tw_out_len); -} - -static void maybe_encode (SPProtoEncoder *o) -{ - if (o->in_len >= 0 && o->out_have && !o->tw_have && can_encode(o)) { - encode_packet(o); - } -} - -static void output_handler_recv (SPProtoEncoder *o, uint8_t *data) -{ - ASSERT(o->in_len == -1) - ASSERT(!o->out_have) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_have = 1; - o->out = data; - - // determine plaintext location - uint8_t *plaintext = (SPPROTO_HAVE_ENCRYPTION(o->sp_params) ? o->buf : o->out); - - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, plaintext + SPPROTO_HEADER_LEN(o->sp_params)); -} - -static void input_handler_done (SPProtoEncoder *o, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - - // encode if possible - if (can_encode(o)) { - encode_packet(o); - } -} - -static void handler_job_hander (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - if (o->handler) { - o->handler(o->user); - return; - } -} - -static void otpgenerator_handler (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remember seed ID - o->otpgen_seed_id = o->otpgen_pending_seed_id; - - // possibly continue I/O - maybe_encode(o); -} - -static void maybe_stop_work (SPProtoEncoder *o) -{ - // stop existing work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - o->tw_have = 0; - } -} - -int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, BPendingGroup *pg, BThreadWorkDispatcher *twd) -{ - spproto_assert_security_params(sp_params); - ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketRecvInterface_GetMTU(input)) >= 0) - if (SPPROTO_HAVE_OTP(sp_params)) { - ASSERT(otp_warning_count > 0) - ASSERT(otp_warning_count <= sp_params.otp_num) - } - - // init arguments - o->input = input; - o->sp_params = sp_params; - o->otp_warning_count = otp_warning_count; - o->twd = twd; - - // set no handlers - o->handler = NULL; - - // calculate hash size - if (SPPROTO_HAVE_HASH(o->sp_params)) { - o->hash_size = BHash_size(o->sp_params.hash_mode); - } - - // calculate encryption block and key sizes - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->enc_block_size = BEncryption_cipher_block_size(o->sp_params.encryption_mode); - o->enc_key_size = BEncryption_cipher_key_size(o->sp_params.encryption_mode); - } - - // init otp generator - if (SPPROTO_HAVE_OTP(o->sp_params)) { - if (!OTPGenerator_Init(&o->otpgen, o->sp_params.otp_num, o->sp_params.otp_mode, o->twd, (OTPGenerator_handler)otpgenerator_handler, o)) { - goto fail0; - } - } - - // have no encryption key - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->have_encryption_key = 0; - } - - // remember input MTU - o->input_mtu = PacketRecvInterface_GetMTU(o->input); - - // calculate output MTU - o->output_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->input_mtu); - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // have no input in buffer - o->in_len = -1; - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output available - o->out_have = 0; - - // allocate plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - int buf_size = balign_up((SPPROTO_HEADER_LEN(o->sp_params) + o->input_mtu + 1), o->enc_block_size); - if (!(o->buf = (uint8_t *)malloc(buf_size))) { - goto fail1; - } - } - - // init handler job - BPending_Init(&o->handler_job, pg, (BPending_handler)handler_job_hander, o); - - // have no work - o->tw_have = 0; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketRecvInterface_Free(&o->output); - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPGenerator_Free(&o->otpgen); - } -fail0: - return 0; -} - -void SPProtoEncoder_Free (SPProtoEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - } - - // free handler job - BPending_Free(&o->handler_job); - - // free plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } - - // free output - PacketRecvInterface_Free(&o->output); - - // free encryptor - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params) && o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // free otp generator - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPGenerator_Free(&o->otpgen); - } -} - -PacketRecvInterface * SPProtoEncoder_GetOutput (SPProtoEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void SPProtoEncoder_SetEncryptionKey (SPProtoEncoder *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work(o); - - // free encryptor - if (o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // init encryptor - BEncryption_Init(&o->encryptor, BENCRYPTION_MODE_ENCRYPT, o->sp_params.encryption_mode, encryption_key); - - // have encryption key - o->have_encryption_key = 1; - - // possibly continue I/O - maybe_encode(o); -} - -void SPProtoEncoder_RemoveEncryptionKey (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work(o); - - if (o->have_encryption_key) { - // free encryptor - BEncryption_Free(&o->encryptor); - - // have no encryption key - o->have_encryption_key = 0; - } -} - -void SPProtoEncoder_SetOTPSeed (SPProtoEncoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // give seed to OTP generator - OTPGenerator_SetSeed(&o->otpgen, key, iv); - - // remember seed ID - o->otpgen_pending_seed_id = seed_id; -} - -void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // reset OTP generator - OTPGenerator_Reset(&o->otpgen); -} - -void SPProtoEncoder_SetHandlers (SPProtoEncoder *o, SPProtoEncoder_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->user = user; -} diff --git a/external/badvpn_dns/client/SPProtoEncoder.h b/external/badvpn_dns/client/SPProtoEncoder.h deleted file mode 100644 index 874f391..0000000 --- a/external/badvpn_dns/client/SPProtoEncoder.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file SPProtoEncoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets according to SPProto. - */ - -#ifndef BADVPN_CLIENT_SPPROTOENCODER_H -#define BADVPN_CLIENT_SPPROTOENCODER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <protocol/spproto.h> -#include <base/DebugObject.h> -#include <security/BEncryption.h> -#include <security/OTPGenerator.h> -#include <flow/PacketRecvInterface.h> -#include <threadwork/BThreadWork.h> - -/** - * Event context handler called when the remaining number of - * OTPs equals the warning number after having encoded a packet. - * - * @param user as in {@link SPProtoEncoder_Init} - */ -typedef void (*SPProtoEncoder_handler) (void *user); - -/** - * Object which encodes packets according to SPProto. - * - * Input is with {@link PacketRecvInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - PacketRecvInterface *input; - struct spproto_security_params sp_params; - int otp_warning_count; - SPProtoEncoder_handler handler; - BThreadWorkDispatcher *twd; - void *user; - int hash_size; - int enc_block_size; - int enc_key_size; - OTPGenerator otpgen; - uint16_t otpgen_seed_id; - uint16_t otpgen_pending_seed_id; - int have_encryption_key; - BEncryption encryptor; - int input_mtu; - int output_mtu; - int in_len; - PacketRecvInterface output; - int out_have; - uint8_t *out; - uint8_t *buf; - BPending handler_job; - int tw_have; - BThreadWork tw; - uint16_t tw_seed_id; - otp_t tw_otp; - int tw_out_len; - DebugObject d_obj; -} SPProtoEncoder; - -/** - * Initializes the object. - * The object is initialized in blocked state. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param input input interface. Its MTU must not be too large, i.e. this must hold: - * spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU) >= 0 - * @param sp_params SPProto security parameters - * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler. - * In this case, must be >0 and <=sp_params.otp_num. - * @param pg pending group - * @param twd thread work dispatcher - * @return 1 on success, 0 on failure - */ -int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, BPendingGroup *pg, BThreadWorkDispatcher *twd) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void SPProtoEncoder_Free (SPProtoEncoder *o); - -/** - * Returns the output interface. - * The MTU of the output interface will depend on the input MTU and security parameters, - * that is spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SPProtoEncoder_GetOutput (SPProtoEncoder *o); - -/** - * Sets an encryption key to use. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void SPProtoEncoder_SetEncryptionKey (SPProtoEncoder *o, uint8_t *encryption_key); - -/** - * Removes an encryption key if one is configured. - * Encryption must be enabled. - * - * @param o the object - */ -void SPProtoEncoder_RemoveEncryptionKey (SPProtoEncoder *o); - -/** - * Sets an OTP seed to use. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void SPProtoEncoder_SetOTPSeed (SPProtoEncoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes the OTP seed if one is configured. - * OTPs must be enabled. - * - * @param o the object - */ -void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o); - -/** - * Sets handlers. - * - * @param o the object - * @param handler OTP warning handler - * @param user value to pass to handler - */ -void SPProtoEncoder_SetHandlers (SPProtoEncoder *o, SPProtoEncoder_handler handler, void *user); - -#endif diff --git a/external/badvpn_dns/client/SimpleStreamBuffer.c b/external/badvpn_dns/client/SimpleStreamBuffer.c deleted file mode 100644 index 74448cb..0000000 --- a/external/badvpn_dns/client/SimpleStreamBuffer.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file SimpleStreamBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stddef.h> - -#include <misc/balloc.h> -#include <misc/minmax.h> - -#include "SimpleStreamBuffer.h" - -static void try_output (SimpleStreamBuffer *o) -{ - ASSERT(o->output_data_len > 0) - - // calculate number of bytes to output - int bytes = bmin_int(o->output_data_len, o->buf_used); - if (bytes == 0) { - return; - } - - // copy bytes to output - memcpy(o->output_data, o->buf, bytes); - - // shift buffer - memmove(o->buf, o->buf + bytes, o->buf_used - bytes); - o->buf_used -= bytes; - - // forget data - o->output_data_len = -1; - - // done - StreamRecvInterface_Done(&o->output, bytes); -} - -static void output_handler_recv (SimpleStreamBuffer *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->output_data_len == -1) - ASSERT(data) - ASSERT(data_len > 0) - - // remember data - o->output_data = data; - o->output_data_len = data_len; - - try_output(o); -} - -int SimpleStreamBuffer_Init (SimpleStreamBuffer *o, int buf_size, BPendingGroup *pg) -{ - ASSERT(buf_size > 0) - - // init arguments - o->buf_size = buf_size; - - // init output - StreamRecvInterface_Init(&o->output, (StreamRecvInterface_handler_recv)output_handler_recv, o, pg); - - // allocate buffer - if (!(o->buf = (uint8_t *)BAlloc(buf_size))) { - goto fail1; - } - - // init buffer state - o->buf_used = 0; - - // set no output data - o->output_data_len = -1; - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - StreamRecvInterface_Free(&o->output); - return 0; -} - -void SimpleStreamBuffer_Free (SimpleStreamBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - BFree(o->buf); - - // free output - StreamRecvInterface_Free(&o->output); -} - -StreamRecvInterface * SimpleStreamBuffer_GetOutput (SimpleStreamBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -int SimpleStreamBuffer_Write (SimpleStreamBuffer *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= 0) - - if (data_len > o->buf_size - o->buf_used) { - return 0; - } - - // copy to buffer - memcpy(o->buf + o->buf_used, data, data_len); - - // update buffer state - o->buf_used += data_len; - - // continue outputting - if (o->output_data_len > 0) { - try_output(o); - } - - return 1; -} diff --git a/external/badvpn_dns/client/SimpleStreamBuffer.h b/external/badvpn_dns/client/SimpleStreamBuffer.h deleted file mode 100644 index 31a55f7..0000000 --- a/external/badvpn_dns/client/SimpleStreamBuffer.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file SimpleStreamBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SIMPLESTREAMBUFFER_H -#define BADVPN_SIMPLESTREAMBUFFER_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> - -typedef struct { - int buf_size; - StreamRecvInterface output; - uint8_t *buf; - int buf_used; - uint8_t *output_data; - int output_data_len; - DebugObject d_obj; -} SimpleStreamBuffer; - -int SimpleStreamBuffer_Init (SimpleStreamBuffer *o, int buf_size, BPendingGroup *pg) WARN_UNUSED; -void SimpleStreamBuffer_Free (SimpleStreamBuffer *o); -StreamRecvInterface * SimpleStreamBuffer_GetOutput (SimpleStreamBuffer *o); -int SimpleStreamBuffer_Write (SimpleStreamBuffer *o, uint8_t *data, int data_len) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/client/SinglePacketSource.c b/external/badvpn_dns/client/SinglePacketSource.c deleted file mode 100644 index 1c6a573..0000000 --- a/external/badvpn_dns/client/SinglePacketSource.c +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file SinglePacketSource.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/debug.h> - -#include "SinglePacketSource.h" - -static void output_handler_recv (SinglePacketSource *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - // if we already sent one packet, stop - if (o->sent) { - return; - } - - // set sent - o->sent = 1; - - // write packet - memcpy(data, o->packet, o->packet_len); - - // done - PacketRecvInterface_Done(&o->output, o->packet_len); -} - -void SinglePacketSource_Init (SinglePacketSource *o, uint8_t *packet, int packet_len, BPendingGroup *pg) -{ - ASSERT(packet_len >= 0) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - - // set not sent - o->sent = 0; - - // init output - PacketRecvInterface_Init(&o->output, o->packet_len, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void SinglePacketSource_Free (SinglePacketSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * SinglePacketSource_GetOutput (SinglePacketSource *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/client/SinglePacketSource.h b/external/badvpn_dns/client/SinglePacketSource.h deleted file mode 100644 index 85ca426..0000000 --- a/external/badvpn_dns/client/SinglePacketSource.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file SinglePacketSource.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLEPACKETSOURCE_H -#define BADVPN_SINGLEPACKETSOURCE_H - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * An object which provides a single packet through {@link PacketRecvInterface}. - */ -typedef struct { - uint8_t *packet; - int packet_len; - int sent; - PacketRecvInterface output; - DebugObject d_obj; -} SinglePacketSource; - -/** - * Initializes the object. - * - * @param o the object - * @param packet packet to provide to the output. Must stay available until the packet is provided. - * @param packet_len length of packet. Must be >=0. - * @param pg pending group we live in - */ -void SinglePacketSource_Init (SinglePacketSource *o, uint8_t *packet, int packet_len, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SinglePacketSource_Free (SinglePacketSource *o); - -/** - * Returns the output interface. - * The MTU of the interface will be packet_len. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SinglePacketSource_GetOutput (SinglePacketSource *o); - -#endif diff --git a/external/badvpn_dns/client/StreamPeerIO.c b/external/badvpn_dns/client/StreamPeerIO.c deleted file mode 100644 index 3113c3b..0000000 --- a/external/badvpn_dns/client/StreamPeerIO.c +++ /dev/null @@ -1,712 +0,0 @@ -/** - * @file StreamPeerIO.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <ssl.h> -#include <sslerr.h> - -#include <misc/offset.h> -#include <misc/byteorder.h> - -#include <client/StreamPeerIO.h> - -#include <generated/blog_channel_StreamPeerIO.h> - -#define MODE_NONE 0 -#define MODE_CONNECT 1 -#define MODE_LISTEN 2 - -#define CONNECT_STATE_CONNECTING 0 -#define CONNECT_STATE_HANDSHAKE 1 -#define CONNECT_STATE_SENDING 2 -#define CONNECT_STATE_SENT 3 -#define CONNECT_STATE_FINISHED 4 - -#define LISTEN_STATE_LISTENER 0 -#define LISTEN_STATE_GOTCLIENT 1 -#define LISTEN_STATE_FINISHED 2 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void decoder_handler_error (StreamPeerIO *pio); -static void connector_handler (StreamPeerIO *pio, int is_error); -static void connection_handler (StreamPeerIO *pio, int event); -static void connect_sslcon_handler (StreamPeerIO *pio, int event); -static void pwsender_handler (StreamPeerIO *pio); -static void listener_handler_client (StreamPeerIO *pio, sslsocket *sock); -static int init_io (StreamPeerIO *pio, sslsocket *sock); -static void free_io (StreamPeerIO *pio); -static void sslcon_handler (StreamPeerIO *pio, int event); -static SECStatus client_auth_certificate_callback (StreamPeerIO *pio, PRFileDesc *fd, PRBool checkSig, PRBool isServer); -static SECStatus client_client_auth_data_callback (StreamPeerIO *pio, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey); -static int compare_certificate (StreamPeerIO *pio, CERTCertificate *cert); -static void reset_state (StreamPeerIO *pio); -static void reset_and_report_error (StreamPeerIO *pio); - -void decoder_handler_error (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - - PeerLog(pio, BLOG_ERROR, "decoder error"); - - reset_and_report_error(pio); - return; -} - -void connector_handler (StreamPeerIO *pio, int is_error) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_CONNECTING) - - // check connection result - if (is_error) { - PeerLog(pio, BLOG_NOTICE, "connection failed"); - goto fail0; - } - - // init connection - if (!BConnection_Init(&pio->connect.sock.con, BConnection_source_connector(&pio->connect.connector), pio->reactor, pio, (BConnection_handler)connection_handler)) { - PeerLog(pio, BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - if (pio->ssl) { - // init connection interfaces - BConnection_SendAsync_Init(&pio->connect.sock.con); - BConnection_RecvAsync_Init(&pio->connect.sock.con); - - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&pio->connect.sock.bottom_prfd, BConnection_SendAsync_GetIf(&pio->connect.sock.con), BConnection_RecvAsync_GetIf(&pio->connect.sock.con), pio->twd, pio->ssl_flags)) { - PeerLog(pio, BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail1; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(pio->connect.sock.ssl_prfd = SSL_ImportFD(NULL, &pio->connect.sock.bottom_prfd))) { - ASSERT_FORCE(PR_Close(&pio->connect.sock.bottom_prfd) == PR_SUCCESS) - goto fail1; - } - - // set client mode - if (SSL_ResetHandshake(pio->connect.sock.ssl_prfd, PR_FALSE) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail2; - } - - // set verify peer certificate hook - if (SSL_AuthCertificateHook(pio->connect.sock.ssl_prfd, (SSLAuthCertificate)client_auth_certificate_callback, pio) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail2; - } - - // set client certificate callback - if (SSL_GetClientAuthDataHook(pio->connect.sock.ssl_prfd, (SSLGetClientAuthData)client_client_auth_data_callback, pio) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail2; - } - - // init BSSLConnection - BSSLConnection_Init(&pio->connect.sslcon, pio->connect.sock.ssl_prfd, 1, BReactor_PendingGroup(pio->reactor), pio, (BSSLConnection_handler)connect_sslcon_handler); - - // change state - pio->connect.state = CONNECT_STATE_HANDSHAKE; - } else { - // init connection send interface - BConnection_SendAsync_Init(&pio->connect.sock.con); - - // init password sender - SingleStreamSender_Init(&pio->connect.pwsender, (uint8_t *)&pio->connect.password, sizeof(pio->connect.password), BConnection_SendAsync_GetIf(&pio->connect.sock.con), BReactor_PendingGroup(pio->reactor), pio, (SingleStreamSender_handler)pwsender_handler); - - // change state - pio->connect.state = CONNECT_STATE_SENDING; - } - - return; - - if (pio->ssl) { -fail2: - ASSERT_FORCE(PR_Close(pio->connect.sock.ssl_prfd) == PR_SUCCESS) -fail1: - BConnection_RecvAsync_Free(&pio->connect.sock.con); - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - BConnection_Free(&pio->connect.sock.con); -fail0: - reset_and_report_error(pio); - return; -} - -void connection_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT || pio->mode == MODE_LISTEN) - ASSERT(!(pio->mode == MODE_CONNECT) || pio->connect.state >= CONNECT_STATE_HANDSHAKE) - ASSERT(!(pio->mode == MODE_LISTEN) || pio->listen.state >= LISTEN_STATE_FINISHED) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - PeerLog(pio, BLOG_NOTICE, "connection closed"); - } else { - PeerLog(pio, BLOG_NOTICE, "connection error"); - } - - reset_and_report_error(pio); - return; -} - -void connect_sslcon_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE || pio->connect.state == CONNECT_STATE_SENDING) - ASSERT(event == BSSLCONNECTION_EVENT_UP || event == BSSLCONNECTION_EVENT_ERROR) - - if (event == BSSLCONNECTION_EVENT_ERROR) { - PeerLog(pio, BLOG_NOTICE, "SSL error"); - - reset_and_report_error(pio); - return; - } - - // handshake complete - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - - // remove client certificate callback - if (SSL_GetClientAuthDataHook(pio->connect.sock.ssl_prfd, NULL, NULL) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail0; - } - - // remove verify peer certificate callback - if (SSL_AuthCertificateHook(pio->connect.sock.ssl_prfd, NULL, NULL) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail0; - } - - // init password sender - SingleStreamSender_Init(&pio->connect.pwsender, (uint8_t *)&pio->connect.password, sizeof(pio->connect.password), BSSLConnection_GetSendIf(&pio->connect.sslcon), BReactor_PendingGroup(pio->reactor), pio, (SingleStreamSender_handler)pwsender_handler); - - // change state - pio->connect.state = CONNECT_STATE_SENDING; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -void pwsender_handler (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_SENDING) - - // stop using any buffers before they get freed - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->connect.sslcon); - } - - // free password sender - SingleStreamSender_Free(&pio->connect.pwsender); - - if (pio->ssl) { - // free BSSLConnection (we used the send interface) - BSSLConnection_Free(&pio->connect.sslcon); - } else { - // init connection send interface - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - - // change state - pio->connect.state = CONNECT_STATE_SENT; - - // setup i/o - if (!init_io(pio, &pio->connect.sock)) { - goto fail0; - } - - // change state - pio->connect.state = CONNECT_STATE_FINISHED; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -void listener_handler_client (StreamPeerIO *pio, sslsocket *sock) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_LISTEN) - ASSERT(pio->listen.state == LISTEN_STATE_LISTENER) - - // remember socket - pio->listen.sock = sock; - - // set connection handler - BConnection_SetHandlers(&pio->listen.sock->con, pio, (BConnection_handler)connection_handler); - - // change state - pio->listen.state = LISTEN_STATE_GOTCLIENT; - - // check ceritficate - if (pio->ssl) { - CERTCertificate *peer_cert = SSL_PeerCertificate(pio->listen.sock->ssl_prfd); - if (!peer_cert) { - PeerLog(pio, BLOG_ERROR, "SSL_PeerCertificate failed"); - goto fail0; - } - - // compare certificate to the one provided by the server - if (!compare_certificate(pio, peer_cert)) { - CERT_DestroyCertificate(peer_cert); - goto fail0; - } - - CERT_DestroyCertificate(peer_cert); - } - - // setup i/o - if (!init_io(pio, pio->listen.sock)) { - goto fail0; - } - - // change state - pio->listen.state = LISTEN_STATE_FINISHED; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -int init_io (StreamPeerIO *pio, sslsocket *sock) -{ - ASSERT(!pio->sock) - - // limit socket send buffer, else our scheduling is pointless - if (pio->sock_sndbuf > 0) { - if (!BConnection_SetSendBuffer(&sock->con, pio->sock_sndbuf)) { - PeerLog(pio, BLOG_WARNING, "BConnection_SetSendBuffer failed"); - } - } - - if (pio->ssl) { - // init BSSLConnection - BSSLConnection_Init(&pio->sslcon, sock->ssl_prfd, 0, BReactor_PendingGroup(pio->reactor), pio, (BSSLConnection_handler)sslcon_handler); - } else { - // init connection interfaces - BConnection_SendAsync_Init(&sock->con); - BConnection_RecvAsync_Init(&sock->con); - } - - StreamPassInterface *send_if = (pio->ssl ? BSSLConnection_GetSendIf(&pio->sslcon) : BConnection_SendAsync_GetIf(&sock->con)); - StreamRecvInterface *recv_if = (pio->ssl ? BSSLConnection_GetRecvIf(&pio->sslcon) : BConnection_RecvAsync_GetIf(&sock->con)); - - // init receiving - StreamRecvConnector_ConnectInput(&pio->input_connector, recv_if); - - // init sending - PacketStreamSender_Init(&pio->output_pss, send_if, PACKETPROTO_ENCLEN(pio->payload_mtu), BReactor_PendingGroup(pio->reactor)); - PacketPassConnector_ConnectOutput(&pio->output_connector, PacketStreamSender_GetInput(&pio->output_pss)); - - pio->sock = sock; - - return 1; -} - -void free_io (StreamPeerIO *pio) -{ - ASSERT(pio->sock) - - // stop using any buffers before they get freed - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->sslcon); - } - - // reset decoder - PacketProtoDecoder_Reset(&pio->input_decoder); - - // free sending - PacketPassConnector_DisconnectOutput(&pio->output_connector); - PacketStreamSender_Free(&pio->output_pss); - - // free receiving - StreamRecvConnector_DisconnectInput(&pio->input_connector); - - if (pio->ssl) { - // free BSSLConnection - BSSLConnection_Free(&pio->sslcon); - } else { - // free connection interfaces - BConnection_RecvAsync_Free(&pio->sock->con); - BConnection_SendAsync_Free(&pio->sock->con); - } - - pio->sock = NULL; -} - -void sslcon_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT || pio->mode == MODE_LISTEN) - ASSERT(!(pio->mode == MODE_CONNECT) || pio->connect.state == CONNECT_STATE_FINISHED) - ASSERT(!(pio->mode == MODE_LISTEN) || pio->listen.state == LISTEN_STATE_FINISHED) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - PeerLog(pio, BLOG_NOTICE, "SSL error"); - - reset_and_report_error(pio); - return; -} - -SECStatus client_auth_certificate_callback (StreamPeerIO *pio, PRFileDesc *fd, PRBool checkSig, PRBool isServer) -{ - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - DebugObject_Access(&pio->d_obj); - - // This callback is used to bypass checking the server's domain name, as peers - // don't have domain names. We byte-compare the certificate to the one reported - // by the server anyway. - - SECStatus ret = SECFailure; - - CERTCertificate *server_cert = SSL_PeerCertificate(pio->connect.sock.ssl_prfd); - if (!server_cert) { - PeerLog(pio, BLOG_ERROR, "SSL_PeerCertificate failed"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail1; - } - - if (CERT_VerifyCertNow(CERT_GetDefaultCertDB(), server_cert, PR_TRUE, certUsageSSLServer, SSL_RevealPinArg(pio->connect.sock.ssl_prfd)) != SECSuccess) { - goto fail2; - } - - // compare to certificate provided by the server - if (!compare_certificate(pio, server_cert)) { - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail2; - } - - ret = SECSuccess; - -fail2: - CERT_DestroyCertificate(server_cert); -fail1: - return ret; -} - -SECStatus client_client_auth_data_callback (StreamPeerIO *pio, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) -{ - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - DebugObject_Access(&pio->d_obj); - - CERTCertificate *cert = CERT_DupCertificate(pio->connect.ssl_cert); - if (!cert) { - PeerLog(pio, BLOG_ERROR, "CERT_DupCertificate failed"); - goto fail0; - } - - SECKEYPrivateKey *key = SECKEY_CopyPrivateKey(pio->connect.ssl_key); - if (!key) { - PeerLog(pio, BLOG_ERROR, "SECKEY_CopyPrivateKey failed"); - goto fail1; - } - - *pRetCert = cert; - *pRetKey = key; - return SECSuccess; - -fail1: - CERT_DestroyCertificate(cert); -fail0: - return SECFailure; -} - -int compare_certificate (StreamPeerIO *pio, CERTCertificate *cert) -{ - ASSERT(pio->ssl) - - SECItem der = cert->derCert; - if (der.len != pio->ssl_peer_cert_len || memcmp(der.data, pio->ssl_peer_cert, der.len)) { - PeerLog(pio, BLOG_NOTICE, "Client certificate doesn't match"); - return 0; - } - - return 1; -} - -void reset_state (StreamPeerIO *pio) -{ - // free resources - switch (pio->mode) { - case MODE_NONE: - break; - case MODE_LISTEN: - switch (pio->listen.state) { - case LISTEN_STATE_FINISHED: - free_io(pio); - case LISTEN_STATE_GOTCLIENT: - if (pio->ssl) { - ASSERT_FORCE(PR_Close(pio->listen.sock->ssl_prfd) == PR_SUCCESS) - BConnection_RecvAsync_Free(&pio->listen.sock->con); - BConnection_SendAsync_Free(&pio->listen.sock->con); - } - BConnection_Free(&pio->listen.sock->con); - free(pio->listen.sock); - case LISTEN_STATE_LISTENER: - if (pio->listen.state == LISTEN_STATE_LISTENER) { - PasswordListener_RemoveEntry(pio->listen.listener, &pio->listen.pwentry); - } - break; - default: - ASSERT(0); - } - break; - case MODE_CONNECT: - switch (pio->connect.state) { - case CONNECT_STATE_FINISHED: - free_io(pio); - case CONNECT_STATE_SENT: - case CONNECT_STATE_SENDING: - if (pio->connect.state == CONNECT_STATE_SENDING) { - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->connect.sslcon); - } - SingleStreamSender_Free(&pio->connect.pwsender); - if (!pio->ssl) { - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - } - case CONNECT_STATE_HANDSHAKE: - if (pio->ssl) { - if (pio->connect.state == CONNECT_STATE_HANDSHAKE || pio->connect.state == CONNECT_STATE_SENDING) { - BSSLConnection_Free(&pio->connect.sslcon); - } - ASSERT_FORCE(PR_Close(pio->connect.sock.ssl_prfd) == PR_SUCCESS) - BConnection_RecvAsync_Free(&pio->connect.sock.con); - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - BConnection_Free(&pio->connect.sock.con); - case CONNECT_STATE_CONNECTING: - BConnector_Free(&pio->connect.connector); - break; - default: - ASSERT(0); - } - break; - default: - ASSERT(0); - } - - // set mode none - pio->mode = MODE_NONE; - - ASSERT(!pio->sock) -} - -void reset_and_report_error (StreamPeerIO *pio) -{ - reset_state(pio); - - pio->handler_error(pio->user); - return; -} - -int StreamPeerIO_Init ( - StreamPeerIO *pio, - BReactor *reactor, - BThreadWorkDispatcher *twd, - int ssl, - int ssl_flags, - uint8_t *ssl_peer_cert, - int ssl_peer_cert_len, - int payload_mtu, - int sock_sndbuf, - PacketPassInterface *user_recv_if, - BLog_logfunc logfunc, - StreamPeerIO_handler_error handler_error, - void *user -) -{ - ASSERT(ssl == 0 || ssl == 1) - ASSERT(payload_mtu >= 0) - ASSERT(PacketPassInterface_GetMTU(user_recv_if) >= payload_mtu) - ASSERT(handler_error) - - // init arguments - pio->reactor = reactor; - pio->twd = twd; - pio->ssl = ssl; - if (pio->ssl) { - pio->ssl_flags = ssl_flags; - pio->ssl_peer_cert = ssl_peer_cert; - pio->ssl_peer_cert_len = ssl_peer_cert_len; - } - pio->payload_mtu = payload_mtu; - pio->sock_sndbuf = sock_sndbuf; - pio->logfunc = logfunc; - pio->handler_error = handler_error; - pio->user = user; - - // check payload MTU - if (pio->payload_mtu > PACKETPROTO_MAXPAYLOAD) { - PeerLog(pio, BLOG_ERROR, "payload MTU is too large"); - goto fail0; - } - - // init receiveing objects - StreamRecvConnector_Init(&pio->input_connector, BReactor_PendingGroup(pio->reactor)); - if (!PacketProtoDecoder_Init(&pio->input_decoder, StreamRecvConnector_GetOutput(&pio->input_connector), user_recv_if, BReactor_PendingGroup(pio->reactor), pio, - (PacketProtoDecoder_handler_error)decoder_handler_error - )) { - PeerLog(pio, BLOG_ERROR, "FlowErrorDomain_Init failed"); - goto fail1; - } - - // init sending objects - PacketCopier_Init(&pio->output_user_copier, pio->payload_mtu, BReactor_PendingGroup(pio->reactor)); - PacketProtoEncoder_Init(&pio->output_user_ppe, PacketCopier_GetOutput(&pio->output_user_copier), BReactor_PendingGroup(pio->reactor)); - PacketPassConnector_Init(&pio->output_connector, PACKETPROTO_ENCLEN(pio->payload_mtu), BReactor_PendingGroup(pio->reactor)); - if (!SinglePacketBuffer_Init(&pio->output_user_spb, PacketProtoEncoder_GetOutput(&pio->output_user_ppe), PacketPassConnector_GetInput(&pio->output_connector), BReactor_PendingGroup(pio->reactor))) { - PeerLog(pio, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // set mode none - pio->mode = MODE_NONE; - - // set no socket - pio->sock = NULL; - - DebugObject_Init(&pio->d_obj); - return 1; - -fail2: - PacketPassConnector_Free(&pio->output_connector); - PacketProtoEncoder_Free(&pio->output_user_ppe); - PacketCopier_Free(&pio->output_user_copier); - PacketProtoDecoder_Free(&pio->input_decoder); -fail1: - StreamRecvConnector_Free(&pio->input_connector); -fail0: - return 0; -} - -void StreamPeerIO_Free (StreamPeerIO *pio) -{ - DebugObject_Free(&pio->d_obj); - - // reset state - reset_state(pio); - - // free sending objects - SinglePacketBuffer_Free(&pio->output_user_spb); - PacketPassConnector_Free(&pio->output_connector); - PacketProtoEncoder_Free(&pio->output_user_ppe); - PacketCopier_Free(&pio->output_user_copier); - - // free receiveing objects - PacketProtoDecoder_Free(&pio->input_decoder); - StreamRecvConnector_Free(&pio->input_connector); -} - -PacketPassInterface * StreamPeerIO_GetSendInput (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - - return PacketCopier_GetInput(&pio->output_user_copier); -} - -int StreamPeerIO_Connect (StreamPeerIO *pio, BAddr addr, uint64_t password, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key) -{ - DebugObject_Access(&pio->d_obj); - - // reset state - reset_state(pio); - - // check address - if (!BConnection_AddressSupported(addr)) { - PeerLog(pio, BLOG_ERROR, "BConnection_AddressSupported failed"); - goto fail0; - } - - // init connector - if (!BConnector_Init(&pio->connect.connector, addr, pio->reactor, pio, (BConnector_handler)connector_handler)) { - PeerLog(pio, BLOG_ERROR, "BConnector_Init failed"); - goto fail0; - } - - // remember data - if (pio->ssl) { - pio->connect.ssl_cert = ssl_cert; - pio->connect.ssl_key = ssl_key; - } - pio->connect.password = htol64(password); - - // set state - pio->mode = MODE_CONNECT; - pio->connect.state = CONNECT_STATE_CONNECTING; - - return 1; - -fail0: - return 0; -} - -void StreamPeerIO_Listen (StreamPeerIO *pio, PasswordListener *listener, uint64_t *password) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(listener->ssl == pio->ssl) - - // reset state - reset_state(pio); - - // add PasswordListener entry - uint64_t newpass = PasswordListener_AddEntry(listener, &pio->listen.pwentry, (PasswordListener_handler_client)listener_handler_client, pio); - - // remember data - pio->listen.listener = listener; - - // set state - pio->mode = MODE_LISTEN; - pio->listen.state = LISTEN_STATE_LISTENER; - - *password = newpass; -} diff --git a/external/badvpn_dns/client/StreamPeerIO.h b/external/badvpn_dns/client/StreamPeerIO.h deleted file mode 100644 index 0b6b260..0000000 --- a/external/badvpn_dns/client/StreamPeerIO.h +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @file StreamPeerIO.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used for communicating with a peer over TCP. - */ - -#ifndef BADVPN_CLIENT_STREAMPEERIO_H -#define BADVPN_CLIENT_STREAMPEERIO_H - -#include <stdint.h> - -#include <cert.h> -#include <keyhi.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BConnection.h> -#include <structure/LinkedList1.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketStreamSender.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketProtoEncoder.h> -#include <flow/PacketCopier.h> -#include <flow/PacketPassConnector.h> -#include <flow/StreamRecvConnector.h> -#include <flow/SingleStreamSender.h> -#include <client/PasswordListener.h> - -/** - * Callback function invoked when an error occurs with the peer connection. - * The object has entered default state. - * May be called from within a sending Send call. - * - * @param user value given to {@link StreamPeerIO_Init}. - */ -typedef void (*StreamPeerIO_handler_error) (void *user); - -/** - * Object used for communicating with a peer over TCP. - * The object has a logical state which can be one of the following: - * - default state - * - listening state - * - connecting state - */ -typedef struct { - // common arguments - BReactor *reactor; - BThreadWorkDispatcher *twd; - int ssl; - int ssl_flags; - uint8_t *ssl_peer_cert; - int ssl_peer_cert_len; - int payload_mtu; - int sock_sndbuf; - BLog_logfunc logfunc; - StreamPeerIO_handler_error handler_error; - void *user; - - // persistent I/O modules - - // base sending objects - PacketCopier output_user_copier; - PacketProtoEncoder output_user_ppe; - SinglePacketBuffer output_user_spb; - PacketPassConnector output_connector; - - // receiving objects - StreamRecvConnector input_connector; - PacketProtoDecoder input_decoder; - - // connection side - int mode; - - union { - // listening data - struct { - int state; - PasswordListener *listener; - PasswordListener_pwentry pwentry; - sslsocket *sock; - } listen; - // connecting data - struct { - int state; - CERTCertificate *ssl_cert; - SECKEYPrivateKey *ssl_key; - BConnector connector; - sslsocket sock; - BSSLConnection sslcon; - uint64_t password; - SingleStreamSender pwsender; - } connect; - }; - - // socket data - sslsocket *sock; - BSSLConnection sslcon; - - // sending objects - PacketStreamSender output_pss; - - DebugObject d_obj; -} StreamPeerIO; - -/** - * Initializes the object. - * The object is initialized in default state. - * {@link BLog_Init} must have been done. - * {@link BNetwork_GlobalInit} must have been done. - * {@link BSSLConnection_GlobalInit} must have been done if using SSL. - * - * @param pio the object - * @param reactor reactor we live in - * @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL - * operations in threads. - * @param ssl if nonzero, SSL will be used for peer connection - * @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to - * request performing SSL operations in threads. - * @param ssl_peer_cert if using SSL, the certificate we expect the peer to have - * @param ssl_peer_cert_len if using SSL, the length of the certificate - * @param payload_mtu maximum packet size as seen from the user. Must be >=0. - * @param sock_sndbuf socket SO_SNDBUF option. Specify <=0 to not set it. - * @param user_recv_if interface to use for submitting received packets. Its MTU - * must be >=payload_mtu. - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @param handler_error handler function invoked when a connection error occurs - * @param user value to pass to handler functions - * @return 1 on success, 0 on failure - */ -int StreamPeerIO_Init ( - StreamPeerIO *pio, - BReactor *reactor, - BThreadWorkDispatcher *twd, - int ssl, - int ssl_flags, - uint8_t *ssl_peer_cert, - int ssl_peer_cert_len, - int payload_mtu, - int sock_sndbuf, - PacketPassInterface *user_recv_if, - BLog_logfunc logfunc, - StreamPeerIO_handler_error handler_error, - void *user -) WARN_UNUSED; - -/** - * Frees the object. - * - * @param pio the object - */ -void StreamPeerIO_Free (StreamPeerIO *pio); - -/** - * Returns the interface for sending packets to the peer. - * The OTP warning handler may be called from within Send calls - * to the interface. - * - * @param pio the object - * @return interface for sending packets to the peer - */ -PacketPassInterface * StreamPeerIO_GetSendInput (StreamPeerIO *pio); - -/** - * Starts an attempt to connect to the peer. - * On success, the object enters connecting state. - * On failure, the object enters default state. - * - * @param pio the object - * @param addr address to connect to - * @param password identification code to send to the peer - * @param ssl_cert if using SSL, the client certificate to use. This object does not - * take ownership of the certificate; it must remain valid until - * the object is reset. - * @param ssl_key if using SSL, the private key to use. This object does not take - * ownership of the key; it must remain valid until the object is reset. - * @return 1 on success, 0 on failure - */ -int StreamPeerIO_Connect (StreamPeerIO *pio, BAddr addr, uint64_t password, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key) WARN_UNUSED; - -/** - * Starts an attempt to accept a connection from the peer. - * The object enters listening state. - * - * @param pio the object - * @param listener {@link PasswordListener} object to use for accepting a connection. - * The listener must have SSL enabled if and only if this object has - * SSL enabled. The listener must be available until the object is - * reset or {@link StreamPeerIO_handler_up} is called. - * @param password will return the identification code the peer should send when connecting - */ -void StreamPeerIO_Listen (StreamPeerIO *pio, PasswordListener *listener, uint64_t *password); - -#endif diff --git a/external/badvpn_dns/client/badvpn-client.8 b/external/badvpn_dns/client/badvpn-client.8 deleted file mode 100644 index 4f41203..0000000 --- a/external/badvpn_dns/client/badvpn-client.8 +++ /dev/null @@ -1,316 +0,0 @@ -.TH badvpn-client 8 "14 July 2011" -.SH NAME -badvpn-client \- VPN node daemon for the BadVPN peer-to-peer VPN system -.SH SYNOPSIS -.B badvpn-client -.RS -.RB "[" --help "]" -.br -.RB "[" --version "]" -.br -.RB "[" --logger " <stdout/syslog>]" -.br -(logger=syslog? -.br -.RS -.br -.RB "[" --syslog-facility " <string>]" -.br -.RB "[" --syslog-ident " <string>]" -.br -.RE -) -.br -.RB "[" --loglevel " <0-5/none/error/warning/notice/info/debug>]" -.br -.RB "[" --channel-loglevel " <channel-name> <0-5/none/error/warning/notice/info/debug>] ..." -.br -.RB "[" --threads " <integer>]" -.br -.RB "[" --ssl " " --nssdb " <string> " --client-cert-name " <string>]" -.br -.RB "[" --server-name " <string>]" -.br -.BR --server-addr " <addr>" -.br -.RB "[" --tapdev " <name>]" -.br -.RB "[" --scope " <scope_name>] ..." -.br -[ -.br -.RS -.BR --bind-addr " <addr>" -.br -.RB "(transport-mode=udp? " --num-ports " <num>)" -.br -.RB "[" --ext-addr " <addr / {server_reported}:port> <scope_name>] ..." -.br -.RE -] ... -.br -.BR --transport-mode " <udp/tcp>" -.br -(transport-mode=udp? -.br -.RS -.BR --encryption-mode " <blowfish/aes/none>" -.br -.BR --hash-mode " <md5/sha1/none>" -.br -.RB "[" --otp " <blowfish/aes> <num> <num-warn>]" -.br -.RB "[" --fragmentation-latency " <milliseconds>]" -.br -.RE -) -.br -(transport-mode=tcp? -.br -.RS -.RB "(ssl? [" --peer-ssl "])" -.br -.RB "[" --peer-tcp-socket-sndbuf " <bytes / 0>]" -.br -.RE -) -.br -.RB "[" --send-buffer-size " <num-packets>]" -.br -.RB "[" --send-buffer-relay-size " <num-packets>]" -.br -.RB "[" --max-macs " <num>]" -.br -.RB "[" --max-groups " <num>]" -.br -.RB "[" --igmp-group-membership-interval " <ms>]" -.br -.RB "[" --igmp-last-member-query-time " <ms>]" -.br -.RB "[" --allow-peer-talk-without-ssl "]" -.br -.RE -.SH INTRODUCTION -.P -This page documents the BadVPN client, a daemon for a node in a BadVPN VPN network. -For a general description of BadVPN, see -.BR badvpn (7). -.SH DESCRIPTION -.P -The BadVPN client is a daemon that runs on a VPN node. It opens the TAP device, connects to -the server, then keeps running while attempting to establish data connection to peers and -tranferring data between the TAP device and the peers. Once it initializes, the program only -terminates if it loses connection to the server, or if a signal is received. -.SH OPTIONS -.P -The BadVPN client is configured entirely from command line. -.TP -.BR --help -Print version and command line syntax and exit. -.TP -.BR --version -Print version and exit. -.TP -.BR --logger " <stdout/syslog>" -Select where to log messages. Default is stdout. Syslog is not available on Windows. -.TP -.BR --syslog-facility " <string>" -When logging to syslog, set the logging facility. The facility name must be in lower case. -.TP -.BR --syslog-ident " <string>" -When logging to syslog, set the ident. -.TP -.BR --loglevel " <0-5/none/error/warning/notice/info/debug>" -Set the default logging level. -.TP -.BR --channel-loglevel " <channel-name> <0-5/none/error/warning/notice/info/debug>" -Set the logging level for a specific logging channel. -.TP -.BR --threads " <integer>" -Hint for the number of additional threads to use for potentionally long computations (such as -encryption and OTP generation). If zero (0) (default), additional threads will be disabled and all -computations will be done in the event loop. If negative (<0), a guess will be made, possibly -based on the number of CPUs. If positive (>0), the given number of threads will be used. -.TP -.BR --ssl -Use TLS. Requires --nssdb and --server-cert-name. -.TP -.BR --nssdb " <string>" -When using TLS, the NSS database to use. Probably something like sql:/some/folder. -.TP -.BR --client-cert-name " <string>" -When using TLS, the name of the certificate to use. The certificate must be readily accessible. -.TP -.BR --server-name " <string>" -Set the name of the server used for validating the server's certificate. The server name defaults -to the the name in the server address (or a numeric address). -.TP -.BR --server-addr " <addr>" -Set the address for the server to listen on. See below for address format. -.TP -.BR --tapdev " <name>" -Set the TAP device to use. See below on how to configure the device. A TAP device is a virtual card -in the operating system, but rather than receiving from and sending frames to a piece of hardware, -a program (this one) opens it to read from and write frames into. If the VPN network is set up correctly, -the TAP devices on the VPN nodes will act as if they were all connected into a network switch. -.TP -.BR --scope " <scope_name>" -Add an address scope allowed for connecting to peers. May be specified multiple times to add multiple -scopes. The order of the scopes is irrelevant. Note that it must actually be possible to connect -to addresses in the given scope; when another peer binds for us to connect to, we choose the first -external address whose scope we recognize, and do not attempt further external addresses, even if -establishing the connection fails. -.TP -.BR --bind-addr " <addr>" -Add an address to allow binding on. See below for address format. When attempting to bind in order -for some peer to connect to us, the addresses will be tried in the order they are specified. If UDP -data transport is being used, a --num-ports option must follow to specify how many continuous ports -to allow binding to. For the address to be useful, one or more --ext-addr options must follow. -Note that when two peers need to establish a data connection, it is arbitrary which one will attempt -to bind first. -.TP -.BR --num-ports " <num>" -When using UDP transport, set the number of continuous ports for a previously specified bind address. -Must follow a previous --bind-addr option. -.TP -.BR --ext-addr " <addr / {server_reported}:port> <scope_name>" -Add an external address for a previously specified bind address. Must follow a previous --bind-addr -option. May be specified multiple times to add multiple external addresses. See below for address -format. Additionally, the IP address part can be {server_reported} to use the IPv4 address as the -server sees us. The external addresses are tried by the connecting peer in the order they are specified. -Note that the connecting peer only attempts to connect to the first address whose scope it recognizes -and does not try other addresses. This means that all addresses must work for be able to communicate. -.TP -.BR --transport-mode " <udp/tcp>" -Sets the transport protocol for data connections. UDP is recommended and works best for most networks. -TCP can be used instead if the underlying network has high packet loss which your virtual network -cannot tolerate. Must match on all peers. -.TP -.BR --encryption-mode " <blowfish/aes/none>" -When using UDP transport, sets the encryption mode. None means no encryption, other options mean -a specific cipher. Note that encryption is only useful if clients use TLS to connect to the server. -The encryption mode must match on all peers. -.TP -.BR --hash-mode " <md5/sha1/none>" -When using UDP transport, sets the hashing mode. None means no hashes, other options mean a specific -type of hash. Note that hashing is only useful if encryption is used as well. The hash mode must -match on all peers. -.TP -.BR --otp " <blowfish/aes> <num> <num-warn>" -When using UDP transport, enables one-time passwords. The first argument specifies a block cipher -used to generate passwords from a seed. The second argument specifies how many passwords are -generated from a single seed. The third argument specifies after how many passwords used up for -sending packets an attempt is made to negotiate a new seed with the other peer. num must be >0, -and num-warn must be >0 and <=num. The difference (num - num-warn) should be large enough to allow -a new seed to be negotiated before the sender runs out of passwords. Negotiating a seed involves -the sending peer sending it to the receiving peer via the server and the receiving peer confirming -it via the server. Note that one-time passwords are only useful if clients use TLS to connect to the -server. The OTP option must match on all peers, except for num-warn. -.TP -.BR --fragmentation-latency " <milliseconds>" -When using UDP transport, sets the maximum latency to sacrifice in order to pack frames into data -packets more efficiently. If it is >=0, a timer of that many milliseconds is used to wait for further -frames to put into an incomplete packet since the first chunk of the packet was written. If it is -<0, packets are sent out immediately. Defaults to 0, which is the recommended setting. -.TP -.BR --peer-ssl -When using TCP transport, enables TLS for data connections. Requires using TLS for server connection. -For this to work, the peers must trust each others' cerificates, and the cerificates must grant the -TLS server usage context. This option must match on all peers. -.TP -.BR --peer-tcp-socket-sndbuf " <bytes / 0>" -Sets the value of the SO_SNDBUF socket option for peer TCP sockets (zero to not set). Lower values -will improve fairness when data from multiple sources (local and relaying) is being sent to a -given peer, but may result in lower bandwidth if the network's bandwidth-delay product is too big. -.TP -.BR --send-buffer-size " <num-packets>" -Sets the minimum size of the peers' send buffers for sending frames originating from this system, in -number of packets. -.TP -.BR --send-buffer-relay-size " <num-packets>" -Sets the minimum size of the peers' send buffers for relaying frames from other peers, in number of -packets. -.TP -.BR --max-macs " <num>" -Sets the maximum number of MAC addresses to remember for a peer. When the number is exceeded, the least -recently used slot will be reused. -.TP -.BR --max-groups " <num>" -Sets the maximum number of IGMP group memberships to remember for a peer. When the number is exceeded, -the least recently used slot will be reused. -.TP -.BR --igmp-group-membership-interval " <ms>" -Sets the Group Membership Interval parameter for IGMP snooping, in milliseconds. -.TP -.BR --igmp-last-member-query-time " <ms>" -Sets the Last Member Query Time parameter for IGMP snooping, in milliseconds. -.TP -.BR --allow-peer-talk-without-ssl -When SSL is enabled, the clients not only connect to the server using SSL, but also exchange messages through -the server through another layer of SSL. This protects the messages from attacks on the server. Older versions -of BadVPN (<1.999.109), however, do not support this. This option allows older and newer clients to -interoperate by not using SSL if the other peer does not support it. It does however negate the security -benefits of using SSL, since the (potentionally compromised) server can then order peers not to use SSL. -.SH "EXIT CODE" -.P -If initialization fails, exits with code 1. Otherwise runs until termination is requested or server connection -is broken and exits with code 1. -.SH "ADDRESS FORMAT" -.P -Addresses have the form ipaddr:port, where ipaddr is either an IPv4 address (name or numeric), or an -IPv6 address enclosed in brackets [] (name or numeric again). -.SH "TAP DEVICE CONFIGURATION" -.P -To use this program, you first have to configure a TAP network device that will act as an endpoint for -the virtual network. The configuration depends on your operating system. -.P -Note that the client program does not configure the TAP device in any way; it only reads and writes -frames from/to it. You are responsible for configuring it (e.g. putting it up and setting its IP address). -.P -.B Linux -.P -You need to enable the kernel configuration option CONFIG_TUN. If you enabled it as a module, you may -have to load it (`modprobe tun`) before you can create the device. -.P -Then you should create a persistent TAP device for the VPN client program to open. This can be done with -either the -.B tunctl -or the -.B openvpn -program. The device will be associated with a user account that will have permission to use it, which should -be the same user as the client program will run as (not root!). To create the device with tunctl, use `tunctl -u <user> -t tapN`, -and to create it with openvpn, use `openvpn --mktun --user <user> --dev tapN`, where N is a number that identifies the -TAP device. -.P -Once the TAP device is created, pass `--tapdev tapN` to the client program to make it use this device. Note that the -device will not be preserved across a shutdown of the system; consult your OS documentaton if you want to automate -the creation or configuration of the device. -.P -.B Windows -.P -Windows does not come with a TAP driver. The client program uses the TAP-Win32 driver, which is part of OpenVPN. -You need to install the OpenVPN open source (!) version, and in the installer enable at least the -`TAP Virtual Ethernet Adapter` and `Add Shortcuts to Start Menu` options. -You can get the installer at -.br -<http://openvpn.net/index.php/open-source/downloads.html>. -.P -The OpenVPN installer automatically creates one TAP device on your system when it's run for the first time. -To create another device, use `Programs -> OpenVPN -> Utilities -> Add a new TAP virtual ethernet adapter`. -You may have to install OpenVPN once again to make this shortcut appear. -.P -Once you have a TAP device, you can configure it like a physical network card. You can recognize TAP devices -by their `Device Name` field. -.P -To use the device, pass `--tapdev "<driver_name>:<interface_name>"` to the client program, where <driver_name> is the name of -the TAP driver (tap0901 for OpenVPN 2.1 and 2.2) (case sensitive), and <interface_name> is the (human) name of the TAP -network interface (e.g. `Local Area Connection 2`). -.SH "EXAMPLES" -.P -For examples of using BadVPN, see -.BR badvpn (7). -.SH "SEE ALSO" -.BR badvpn-server (8), -.BR badvpn (7) -.SH AUTHORS -Ambroz Bizjak <ambrop7@gmail.com> diff --git a/external/badvpn_dns/client/client.c b/external/badvpn_dns/client/client.c deleted file mode 100644 index 2729d6b..0000000 --- a/external/badvpn_dns/client/client.c +++ /dev/null @@ -1,2997 +0,0 @@ -/** - * @file client.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <protocol/msgproto.h> -#include <protocol/addr.h> -#include <protocol/dataproto.h> -#include <misc/version.h> -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <misc/nsskey.h> -#include <misc/loglevel.h> -#include <misc/loggers_string.h> -#include <misc/string_begins_with.h> -#include <misc/open_standard_streams.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <security/BSecurity.h> -#include <security/BRandom.h> -#include <system/BSignal.h> -#include <system/BTime.h> -#include <system/BNetwork.h> -#include <nspr_support/DummyPRFileDesc.h> -#include <nspr_support/BSSLConnection.h> -#include <server_connection/ServerConnection.h> -#include <tuntap/BTap.h> -#include <threadwork/BThreadWork.h> - -#ifndef BADVPN_USE_WINAPI -#include <base/BLog_syslog.h> -#endif - -#include <client/client.h> - -#include <generated/blog_channel_client.h> - -#define TRANSPORT_MODE_UDP 0 -#define TRANSPORT_MODE_TCP 1 - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -// command-line options -struct ext_addr_option { - char *addr; - char *scope; -}; -struct bind_addr_option { - char *addr; - int num_ports; - int num_ext_addrs; - struct ext_addr_option ext_addrs[MAX_EXT_ADDRS]; -}; -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - int threads; - int use_threads_for_ssl_handshake; - int use_threads_for_ssl_data; - int ssl; - char *nssdb; - char *client_cert_name; - char *server_name; - char *server_addr; - char *tapdev; - int num_scopes; - char *scopes[MAX_SCOPES]; - int num_bind_addrs; - struct bind_addr_option bind_addrs[MAX_BIND_ADDRS]; - int transport_mode; - int encryption_mode; - int hash_mode; - int otp_mode; - int otp_num; - int otp_num_warn; - int fragmentation_latency; - int peer_ssl; - int peer_tcp_socket_sndbuf; - int send_buffer_size; - int send_buffer_relay_size; - int max_macs; - int max_groups; - int igmp_group_membership_interval; - int igmp_last_member_query_time; - int allow_peer_talk_without_ssl; - int max_peers; -} options; - -// bind addresses -struct ext_addr { - int server_reported_port; - BAddr addr; // if server_reported_port>=0, defined only after hello received - char scope[64]; -}; -struct bind_addr { - BAddr addr; - int num_ports; - int num_ext_addrs; - struct ext_addr ext_addrs[MAX_EXT_ADDRS]; -}; -int num_bind_addrs; -struct bind_addr bind_addrs[MAX_BIND_ADDRS]; - -// TCP listeners -PasswordListener listeners[MAX_BIND_ADDRS]; - -// SPProto parameters (UDP only) -struct spproto_security_params sp_params; - -// server address we connect to -BAddr server_addr; - -// server name to use for SSL -char server_name[256]; - -// reactor -BReactor ss; - -// thread work dispatcher -BThreadWorkDispatcher twd; - -// client certificate if using SSL -CERTCertificate *client_cert; - -// client private key if using SSL -SECKEYPrivateKey *client_key; - -// device -BTap device; -int device_mtu; - -// DataProtoSource for device input (reading) -DataProtoSource device_dpsource; - -// DPReceiveDevice for device output (writing) -DPReceiveDevice device_output_dprd; - -// data communication MTU -int data_mtu; - -// peers list -LinkedList1 peers; -int num_peers; - -// frame decider -FrameDecider frame_decider; - -// peers that can be user as relays -LinkedList1 relays; - -// peers than need a relay -LinkedList1 waiting_relay_peers; - -// server connection -ServerConnection server; - -// my ID, defined only after server_ready -peerid_t my_id; - -// fair queue for sending peer messages to the server -PacketPassFairQueue server_queue; - -// whether server is ready -int server_ready; - -// dying server flow -struct server_flow *dying_server_flow; - -// stops event processing, causing the program to exit -static void terminate (void); - -// prints program name and version to standard output -static void print_help (const char *name); - -// prints program name and version to standard output -static void print_version (void); - -// parses the command line -static int parse_arguments (int argc, char *argv[]); - -// processes certain command line options -static int process_arguments (void); - -static int ssl_flags (void); - -// handler for program termination request -static void signal_handler (void *unused); - -// adds a new peer -static void peer_add (peerid_t id, int flags, const uint8_t *cert, int cert_len); - -// removes a peer -static void peer_remove (struct peer_data *peer, int exiting); - -// appends the peer log prefix to the logger -static void peer_logfunc (struct peer_data *peer); - -// passes a message to the logger, prepending it info about the peer -static void peer_log (struct peer_data *peer, int level, const char *fmt, ...); - -// see if we are the master relative to this peer -static int peer_am_master (struct peer_data *peer); - -// frees PeerChat, disconnecting it from the server flow -static void peer_free_chat (struct peer_data *peer); - -// initializes the link -static int peer_init_link (struct peer_data *peer); - -// frees link resources -static void peer_free_link (struct peer_data *peer); - -// frees link, relaying, waiting relaying -static void peer_cleanup_connections (struct peer_data *peer); - -// registers the peer as a relay provider -static void peer_enable_relay_provider (struct peer_data *peer); - -// unregisters the peer as a relay provider -static void peer_disable_relay_provider (struct peer_data *peer); - -// install relaying for a peer -static void peer_install_relaying (struct peer_data *peer, struct peer_data *relay); - -// uninstall relaying for a peer -static void peer_free_relaying (struct peer_data *peer); - -// handle a peer that needs a relay -static void peer_need_relay (struct peer_data *peer); - -// inserts the peer into the need relay list -static void peer_register_need_relay (struct peer_data *peer); - -// removes the peer from the need relay list -static void peer_unregister_need_relay (struct peer_data *peer); - -// handle a link setup failure -static void peer_reset (struct peer_data *peer); - -// fees chat and sends resetpeer -static void peer_resetpeer (struct peer_data *peer); - -// chat handlers -static void peer_chat_handler_error (struct peer_data *peer); -static void peer_chat_handler_message (struct peer_data *peer, uint8_t *data, int data_len); - -// handlers for different message types -static void peer_msg_youconnect (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_cannotconnect (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_cannotbind (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_seed (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_confirmseed (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_youretry (struct peer_data *peer, uint8_t *data, int data_len); - -// handler from DatagramPeerIO when we should generate a new OTP send seed -static void peer_udp_pio_handler_seed_warning (struct peer_data *peer); - -// handler from DatagramPeerIO when a new OTP seed can be recognized once it was provided to it -static void peer_udp_pio_handler_seed_ready (struct peer_data *peer); - -// handler from DatagramPeerIO when an error occurs on the connection -static void peer_udp_pio_handler_error (struct peer_data *peer); - -// handler from StreamPeerIO when an error occurs on the connection -static void peer_tcp_pio_handler_error (struct peer_data *peer); - -// peer retry timer handler. The timer is used only on the master side, -// wither when we detect an error, or the peer reports an error. -static void peer_reset_timer_handler (struct peer_data *peer); - -// start binding, according to the protocol -static void peer_start_binding (struct peer_data *peer); - -// tries binding on one address, according to the protocol -static void peer_bind (struct peer_data *peer); - -static void peer_bind_one_address (struct peer_data *peer, int addr_index, int *cont); - -static void peer_connect (struct peer_data *peer, BAddr addr, uint8_t *encryption_key, uint64_t password); - -static int peer_start_msg (struct peer_data *peer, void **data, int type, int len); - -static void peer_end_msg (struct peer_data *peer); - -// sends a message with no payload to the peer -static void peer_send_simple (struct peer_data *peer, int msgid); - -static void peer_send_conectinfo (struct peer_data *peer, int addr_index, int port_adjust, uint8_t *enckey, uint64_t pass); - -static void peer_send_confirmseed (struct peer_data *peer, uint16_t seed_id); - -// handler for peer DataProto up state changes -static void peer_dataproto_handler (struct peer_data *peer, int up); - -// looks for a peer with the given ID -static struct peer_data * find_peer_by_id (peerid_t id); - -// device error handler -static void device_error_handler (void *unused); - -// DataProtoSource handler for packets from the device -static void device_dpsource_handler (void *unused, const uint8_t *frame, int frame_len); - -// assign relays to clients waiting for them -static void assign_relays (void); - -// checks if the given address scope is known (i.e. we can connect to an address in it) -static char * address_scope_known (uint8_t *name, int name_len); - -// handlers for server messages -static void server_handler_error (void *user); -static void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip); -static void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len); -static void server_handler_endclient (void *user, peerid_t peer_id); -static void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len); - -// jobs -static void peer_job_send_seed (struct peer_data *peer); -static void peer_job_init (struct peer_data *peer); - -// server flows -static struct server_flow * server_flow_init (void); -static void server_flow_free (struct server_flow *flow); -static void server_flow_die (struct server_flow *flow); -static void server_flow_qflow_handler_busy (struct server_flow *flow); -static void server_flow_connect (struct server_flow *flow, PacketRecvInterface *input); -static void server_flow_disconnect (struct server_flow *flow); - -int main (int argc, char *argv[]) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - if (options.ssl) { - // init NSPR - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - // register local NSPR file types - if (!DummyPRFileDesc_GlobalInit()) { - BLog(BLOG_ERROR, "DummyPRFileDesc_GlobalInit failed"); - goto fail01; - } - if (!BSSLConnection_GlobalInit()) { - BLog(BLOG_ERROR, "BSSLConnection_GlobalInit failed"); - goto fail01; - } - - // init NSS - if (NSS_Init(options.nssdb) != SECSuccess) { - BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError()); - goto fail01; - } - - // set cipher policy - if (NSS_SetDomesticPolicy() != SECSuccess) { - BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // init server cache - if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // open server certificate and private key - if (!open_nss_cert_and_key(options.client_cert_name, &client_cert, &client_key)) { - BLog(BLOG_ERROR, "Cannot open certificate and key"); - goto fail03; - } - } - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // init time - BTime_Init(); - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // init thread work dispatcher - if (!BThreadWorkDispatcher_Init(&twd, &ss, options.threads)) { - BLog(BLOG_ERROR, "BThreadWorkDispatcher_Init failed"); - goto fail3; - } - - // init BSecurity - if (BThreadWorkDispatcher_UsingThreads(&twd)) { - if (!BSecurity_GlobalInitThreadSafe()) { - BLog(BLOG_ERROR, "BSecurity_GlobalInitThreadSafe failed"); - goto fail4; - } - } - - // init listeners - int num_listeners = 0; - if (options.transport_mode == TRANSPORT_MODE_TCP) { - while (num_listeners < num_bind_addrs) { - struct bind_addr *addr = &bind_addrs[num_listeners]; - if (!PasswordListener_Init(&listeners[num_listeners], &ss, &twd, addr->addr, TCP_MAX_PASSWORD_LISTENER_CLIENTS, options.peer_ssl, ssl_flags(), client_cert, client_key)) { - BLog(BLOG_ERROR, "PasswordListener_Init failed"); - goto fail8; - } - num_listeners++; - } - } - - // init device - if (!BTap_Init(&device, &ss, options.tapdev, device_error_handler, NULL, 0)) { - BLog(BLOG_ERROR, "BTap_Init failed"); - goto fail8; - } - - // remember device MTU - device_mtu = BTap_GetMTU(&device); - - BLog(BLOG_INFO, "device MTU is %d", device_mtu); - - // calculate data MTU - if (device_mtu > INT_MAX - DATAPROTO_MAX_OVERHEAD) { - BLog(BLOG_ERROR, "Device MTU is too large"); - goto fail9; - } - data_mtu = DATAPROTO_MAX_OVERHEAD + device_mtu; - - // init device input - if (!DataProtoSource_Init(&device_dpsource, BTap_GetOutput(&device), device_dpsource_handler, NULL, &ss)) { - BLog(BLOG_ERROR, "DataProtoSource_Init failed"); - goto fail9; - } - - // init device output - if (!DPReceiveDevice_Init(&device_output_dprd, device_mtu, (DPReceiveDevice_output_func)BTap_Send, &device, &ss, options.send_buffer_relay_size, PEER_RELAY_FLOW_INACTIVITY_TIME)) { - BLog(BLOG_ERROR, "DPReceiveDevice_Init failed"); - goto fail10; - } - - // init peers list - LinkedList1_Init(&peers); - num_peers = 0; - - // init frame decider - FrameDecider_Init(&frame_decider, options.max_macs, options.max_groups, options.igmp_group_membership_interval, options.igmp_last_member_query_time, &ss); - - // init relays list - LinkedList1_Init(&relays); - - // init need relay list - LinkedList1_Init(&waiting_relay_peers); - - // start connecting to server - if (!ServerConnection_Init(&server, &ss, &twd, server_addr, SC_KEEPALIVE_INTERVAL, SERVER_BUFFER_MIN_PACKETS, options.ssl, ssl_flags(), client_cert, client_key, server_name, NULL, - server_handler_error, server_handler_ready, server_handler_newclient, server_handler_endclient, server_handler_message - )) { - BLog(BLOG_ERROR, "ServerConnection_Init failed"); - goto fail11; - } - - // set server not ready - server_ready = 0; - - // set no dying flow - dying_server_flow = NULL; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - if (server_ready) { - // allow freeing server queue flows - PacketPassFairQueue_PrepareFree(&server_queue); - - // make ServerConnection stop using buffers from peers before they are freed - ServerConnection_ReleaseBuffers(&server); - } - - // free peers - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&peers)) { - struct peer_data *peer = UPPER_OBJECT(node, struct peer_data, list_node); - peer_remove(peer, 1); - } - - // free dying server flow - if (dying_server_flow) { - server_flow_free(dying_server_flow); - } - - if (server_ready) { - PacketPassFairQueue_Free(&server_queue); - } - ServerConnection_Free(&server); -fail11: - FrameDecider_Free(&frame_decider); - DPReceiveDevice_Free(&device_output_dprd); -fail10: - DataProtoSource_Free(&device_dpsource); -fail9: - BTap_Free(&device); -fail8: - if (options.transport_mode == TRANSPORT_MODE_TCP) { - while (num_listeners-- > 0) { - PasswordListener_Free(&listeners[num_listeners]); - } - } - if (BThreadWorkDispatcher_UsingThreads(&twd)) { - BSecurity_GlobalFreeThreadSafe(); - } -fail4: - // NOTE: BThreadWorkDispatcher must be freed before NSPR and stuff - BThreadWorkDispatcher_Free(&twd); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&ss); -fail1: - if (options.ssl) { - CERT_DestroyCertificate(client_cert); - SECKEY_DestroyPrivateKey(client_key); -fail03: - ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess) -fail02: - SSL_ClearSessionCache(); - ASSERT_FORCE(NSS_Shutdown() == SECSuccess) -fail01: - ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS) - PL_ArenaFinish(); - } - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish objects - DebugObjectGlobal_Finish(); - return 1; -} - -void terminate (void) -{ - BLog(BLOG_NOTICE, "tearing down"); - - // exit event loop - BReactor_Quit(&ss, 0); -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--threads <integer>]\n" - " [--use-threads-for-ssl-handshake]\n" - " [--use-threads-for-ssl-data]\n" - " [--ssl --nssdb <string> --client-cert-name <string>]\n" - " [--server-name <string>]\n" - " --server-addr <addr>\n" - " [--tapdev <name>]\n" - " [--scope <scope_name>] ...\n" - " [\n" - " --bind-addr <addr>\n" - " (transport-mode=udp? --num-ports <num>)\n" - " [--ext-addr <addr / {server_reported}:port> <scope_name>] ...\n" - " ] ...\n" - " --transport-mode <udp/tcp>\n" - " (transport-mode=udp?\n" - " --encryption-mode <blowfish/aes/none>\n" - " --hash-mode <md5/sha1/none>\n" - " [--otp <blowfish/aes> <num> <num-warn>]\n" - " [--fragmentation-latency <milliseconds>]\n" - " )\n" - " (transport-mode=tcp?\n" - " (ssl? [--peer-ssl])\n" - " [--peer-tcp-socket-sndbuf <bytes / 0>]\n" - " )\n" - " [--send-buffer-size <num-packets>]\n" - " [--send-buffer-relay-size <num-packets>]\n" - " [--max-macs <num>]\n" - " [--max-groups <num>]\n" - " [--igmp-group-membership-interval <ms>]\n" - " [--igmp-last-member-query-time <ms>]\n" - " [--allow-peer-talk-without-ssl]\n" - " [--max-peers <number>]\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.threads = 0; - options.use_threads_for_ssl_handshake = 0; - options.use_threads_for_ssl_data = 0; - options.ssl = 0; - options.nssdb = NULL; - options.client_cert_name = NULL; - options.server_name = NULL; - options.server_addr = NULL; - options.tapdev = NULL; - options.num_scopes = 0; - options.num_bind_addrs = 0; - options.transport_mode = -1; - options.encryption_mode = -1; - options.hash_mode = -1; - options.otp_mode = SPPROTO_OTP_MODE_NONE; - options.fragmentation_latency = PEER_DEFAULT_UDP_FRAGMENTATION_LATENCY; - options.peer_ssl = 0; - options.peer_tcp_socket_sndbuf = -1; - options.send_buffer_size = PEER_DEFAULT_SEND_BUFFER_SIZE; - options.send_buffer_relay_size = PEER_DEFAULT_SEND_BUFFER_RELAY_SIZE; - options.max_macs = PEER_DEFAULT_MAX_MACS; - options.max_groups = PEER_DEFAULT_MAX_GROUPS; - options.igmp_group_membership_interval = DEFAULT_IGMP_GROUP_MEMBERSHIP_INTERVAL; - options.igmp_last_member_query_time = DEFAULT_IGMP_LAST_MEMBER_QUERY_TIME; - options.allow_peer_talk_without_ssl = 0; - options.max_peers = DEFAULT_MAX_PEERS; - - int have_fragmentation_latency = 0; - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--threads")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.threads = atoi(argv[i + 1]); - i++; - } - else if (!strcmp(arg, "--use-threads-for-ssl-handshake")) { - options.use_threads_for_ssl_handshake = 1; - } - else if (!strcmp(arg, "--use-threads-for-ssl-data")) { - options.use_threads_for_ssl_data = 1; - } - else if (!strcmp(arg, "--ssl")) { - options.ssl = 1; - } - else if (!strcmp(arg, "--nssdb")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.nssdb = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--client-cert-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.client_cert_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--tapdev")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.tapdev = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--scope")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_scopes == MAX_SCOPES) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.scopes[options.num_scopes] = argv[i + 1]; - options.num_scopes++; - i++; - } - else if (!strcmp(arg, "--bind-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_bind_addrs == MAX_BIND_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs]; - addr->addr = argv[i + 1]; - addr->num_ports = -1; - addr->num_ext_addrs = 0; - options.num_bind_addrs++; - i++; - } - else if (!strcmp(arg, "--num-ports")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_bind_addrs == 0) { - fprintf(stderr, "%s: must folow --bind-addr\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs - 1]; - if ((addr->num_ports = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--ext-addr")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - if (options.num_bind_addrs == 0) { - fprintf(stderr, "%s: must folow --bind-addr\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs - 1]; - if (addr->num_ext_addrs == MAX_EXT_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - struct ext_addr_option *eaddr = &addr->ext_addrs[addr->num_ext_addrs]; - eaddr->addr = argv[i + 1]; - eaddr->scope = argv[i + 2]; - addr->num_ext_addrs++; - i += 2; - } - else if (!strcmp(arg, "--transport-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "udp")) { - options.transport_mode = TRANSPORT_MODE_UDP; - } - else if (!strcmp(arg2, "tcp")) { - options.transport_mode = TRANSPORT_MODE_TCP; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--encryption-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "none")) { - options.encryption_mode = SPPROTO_ENCRYPTION_MODE_NONE; - } - else if (!strcmp(arg2, "blowfish")) { - options.encryption_mode = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(arg2, "aes")) { - options.encryption_mode = BENCRYPTION_CIPHER_AES; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--hash-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "none")) { - options.hash_mode = SPPROTO_HASH_MODE_NONE; - } - else if (!strcmp(arg2, "md5")) { - options.hash_mode = BHASH_TYPE_MD5; - } - else if (!strcmp(arg2, "sha1")) { - options.hash_mode = BHASH_TYPE_SHA1; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--otp")) { - if (3 >= argc - i) { - fprintf(stderr, "%s: requires three arguments\n", arg); - return 0; - } - char *otp_mode = argv[i + 1]; - char *otp_num = argv[i + 2]; - char *otp_num_warn = argv[i + 3]; - if (!strcmp(otp_mode, "blowfish")) { - options.otp_mode = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(otp_mode, "aes")) { - options.otp_mode = BENCRYPTION_CIPHER_AES; - } - else { - fprintf(stderr, "%s: wrong mode\n", arg); - return 0; - } - if ((options.otp_num = atoi(otp_num)) <= 0) { - fprintf(stderr, "%s: wrong num\n", arg); - return 0; - } - options.otp_num_warn = atoi(otp_num_warn); - if (options.otp_num_warn <= 0 || options.otp_num_warn > options.otp_num) { - fprintf(stderr, "%s: wrong num warn\n", arg); - return 0; - } - i += 3; - } - else if (!strcmp(arg, "--fragmentation-latency")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.fragmentation_latency = atoi(argv[i + 1]); - have_fragmentation_latency = 1; - i++; - } - else if (!strcmp(arg, "--peer-ssl")) { - options.peer_ssl = 1; - } - else if (!strcmp(arg, "--peer-tcp-socket-sndbuf")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.peer_tcp_socket_sndbuf = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--send-buffer-size")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.send_buffer_size = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--send-buffer-relay-size")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.send_buffer_relay_size = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-macs")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_macs = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-groups")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_groups = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--igmp-group-membership-interval")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.igmp_group_membership_interval = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--igmp-last-member-query-time")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.igmp_last_member_query_time = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-peers")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_peers = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--allow-peer-talk-without-ssl")) { - options.allow_peer_talk_without_ssl = 1; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (options.ssl != !!options.nssdb) { - fprintf(stderr, "False: --ssl <=> --nssdb\n"); - return 0; - } - - if (options.ssl != !!options.client_cert_name) { - fprintf(stderr, "False: --ssl <=> --client-cert-name\n"); - return 0; - } - - if (!options.server_addr) { - fprintf(stderr, "False: --server-addr\n"); - return 0; - } - - if (options.transport_mode < 0) { - fprintf(stderr, "False: --transport-mode\n"); - return 0; - } - - if ((options.transport_mode == TRANSPORT_MODE_UDP) != (options.encryption_mode >= 0)) { - fprintf(stderr, "False: UDP <=> --encryption-mode\n"); - return 0; - } - - if ((options.transport_mode == TRANSPORT_MODE_UDP) != (options.hash_mode >= 0)) { - fprintf(stderr, "False: UDP <=> --hash-mode\n"); - return 0; - } - - if (!(!(options.otp_mode != SPPROTO_OTP_MODE_NONE) || (options.transport_mode == TRANSPORT_MODE_UDP))) { - fprintf(stderr, "False: --otp => UDP\n"); - return 0; - } - - if (!(!have_fragmentation_latency || (options.transport_mode == TRANSPORT_MODE_UDP))) { - fprintf(stderr, "False: --fragmentation-latency => UDP\n"); - return 0; - } - - if (!(!options.peer_ssl || (options.ssl && options.transport_mode == TRANSPORT_MODE_TCP))) { - fprintf(stderr, "False: --peer-ssl => (--ssl && TCP)\n"); - return 0; - } - - if (!(!(options.peer_tcp_socket_sndbuf >= 0) || options.transport_mode == TRANSPORT_MODE_TCP)) { - fprintf(stderr, "False: --peer-tcp-socket-sndbuf => TCP\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve server address - ASSERT(options.server_addr) - if (!BAddr_Parse(&server_addr, options.server_addr, server_name, sizeof(server_name))) { - BLog(BLOG_ERROR, "server addr: BAddr_Parse failed"); - return 0; - } - - // override server name if requested - if (options.server_name) { - if (strlen(options.server_name) >= sizeof(server_name)) { - BLog(BLOG_ERROR, "server name: too long"); - return 0; - } - strcpy(server_name, options.server_name); - } - - // resolve bind addresses and external addresses - num_bind_addrs = 0; - for (int i = 0; i < options.num_bind_addrs; i++) { - struct bind_addr_option *addr = &options.bind_addrs[i]; - struct bind_addr *out = &bind_addrs[num_bind_addrs]; - - // read addr - if (!BAddr_Parse(&out->addr, addr->addr, NULL, 0)) { - BLog(BLOG_ERROR, "bind addr: BAddr_Parse failed"); - return 0; - } - - // read num ports - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (addr->num_ports < 0) { - BLog(BLOG_ERROR, "bind addr: num ports missing"); - return 0; - } - out->num_ports = addr->num_ports; - } - else if (addr->num_ports >= 0) { - BLog(BLOG_ERROR, "bind addr: num ports given, but not using UDP"); - return 0; - } - - // read ext addrs - out->num_ext_addrs = 0; - for (int j = 0; j < addr->num_ext_addrs; j++) { - struct ext_addr_option *eaddr = &addr->ext_addrs[j]; - struct ext_addr *eout = &out->ext_addrs[out->num_ext_addrs]; - - // read addr - if (string_begins_with(eaddr->addr, "{server_reported}:")) { - char *colon = strstr(eaddr->addr, ":"); - if ((eout->server_reported_port = atoi(colon + 1)) < 0) { - BLog(BLOG_ERROR, "ext addr: wrong port"); - return 0; - } - } else { - eout->server_reported_port = -1; - if (!BAddr_Parse(&eout->addr, eaddr->addr, NULL, 0)) { - BLog(BLOG_ERROR, "ext addr: BAddr_Parse failed"); - return 0; - } - if (!addr_supported(eout->addr)) { - BLog(BLOG_ERROR, "ext addr: addr_supported failed"); - return 0; - } - } - - // read scope - if (strlen(eaddr->scope) >= sizeof(eout->scope)) { - BLog(BLOG_ERROR, "ext addr: too long"); - return 0; - } - strcpy(eout->scope, eaddr->scope); - - out->num_ext_addrs++; - } - - num_bind_addrs++; - } - - // initialize SPProto parameters - if (options.transport_mode == TRANSPORT_MODE_UDP) { - sp_params.encryption_mode = options.encryption_mode; - sp_params.hash_mode = options.hash_mode; - sp_params.otp_mode = options.otp_mode; - if (options.otp_mode > 0) { - sp_params.otp_num = options.otp_num; - } - } - - return 1; -} - -int ssl_flags (void) -{ - int flags = 0; - if (options.use_threads_for_ssl_handshake) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE; - } - if (options.use_threads_for_ssl_data) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_IO; - } - return flags; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - terminate(); -} - -void peer_add (peerid_t id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - ASSERT(num_peers < options.max_peers) - ASSERT(!find_peer_by_id(id)) - ASSERT(id != my_id) - ASSERT(cert_len >= 0) - ASSERT(cert_len <= SCID_NEWCLIENT_MAX_CERT_LEN) - - // allocate structure - struct peer_data *peer = (struct peer_data *)malloc(sizeof(*peer)); - if (!peer) { - BLog(BLOG_ERROR, "peer %d: failed to allocate memory", (int)id); - goto fail0; - } - - // remember id - peer->id = id; - - // remember flags - peer->flags = flags; - - // set no common name - peer->common_name = NULL; - - if (options.ssl) { - // remember certificate - memcpy(peer->cert, cert, cert_len); - peer->cert_len = cert_len; - - // make sure that CERT_DecodeCertFromPackage will interpretet the input as raw DER and not base64, - // in which case following workaroud wouldn't help - if (!(cert_len > 0 && (cert[0] & 0x1f) == 0x10)) { - peer_log(peer, BLOG_ERROR, "certificate does not look like DER"); - goto fail1; - } - - // copy the certificate and append it a good load of zero bytes, - // hopefully preventing the crappy CERT_DecodeCertFromPackage from crashing - // by reading past the of its input - uint8_t *certbuf = (uint8_t *)malloc(cert_len + 100); - if (!certbuf) { - peer_log(peer, BLOG_ERROR, "malloc failed"); - goto fail1; - } - memcpy(certbuf, cert, cert_len); - memset(certbuf + cert_len, 0, 100); - - // decode certificate, so we can extract the common name - CERTCertificate *nsscert = CERT_DecodeCertFromPackage((char *)certbuf, cert_len); - if (!nsscert) { - peer_log(peer, BLOG_ERROR, "CERT_DecodeCertFromPackage failed (%d)", PORT_GetError()); - free(certbuf); - goto fail1; - } - - free(certbuf); - - // remember common name - if (!(peer->common_name = CERT_GetCommonName(&nsscert->subject))) { - peer_log(peer, BLOG_ERROR, "CERT_GetCommonName failed"); - CERT_DestroyCertificate(nsscert); - goto fail1; - } - - CERT_DestroyCertificate(nsscert); - } - - // init and set init job (must be before initing server flow so we can send) - BPending_Init(&peer->job_init, BReactor_PendingGroup(&ss), (BPending_handler)peer_job_init, peer); - BPending_Set(&peer->job_init); - - // init server flow - if (!(peer->server_flow = server_flow_init())) { - peer_log(peer, BLOG_ERROR, "server_flow_init failed"); - goto fail2; - } - - if ((peer->flags & SCID_NEWCLIENT_FLAG_SSL) && !options.ssl) { - peer_log(peer, BLOG_ERROR, "peer requires talking with SSL, but we're not using SSL!?"); - goto fail3; - } - - if (options.ssl && !(peer->flags & SCID_NEWCLIENT_FLAG_SSL) && !options.allow_peer_talk_without_ssl) { - peer_log(peer, BLOG_ERROR, "peer requires talking without SSL, but we don't allow that"); - goto fail3; - } - - // choose chat SSL mode - int chat_ssl_mode = PEERCHAT_SSL_NONE; - if ((peer->flags & SCID_NEWCLIENT_FLAG_SSL)) { - chat_ssl_mode = (peer_am_master(peer) ? PEERCHAT_SSL_SERVER : PEERCHAT_SSL_CLIENT); - } - - // init chat - if (!PeerChat_Init(&peer->chat, peer->id, chat_ssl_mode, ssl_flags(), client_cert, client_key, peer->cert, peer->cert_len, BReactor_PendingGroup(&ss), &twd, peer, - (BLog_logfunc)peer_logfunc, - (PeerChat_handler_error)peer_chat_handler_error, - (PeerChat_handler_message)peer_chat_handler_message - )) { - peer_log(peer, BLOG_ERROR, "PeerChat_Init failed"); - goto fail3; - } - - // set no message - peer->chat_send_msg_len = -1; - - // connect server flow to chat - server_flow_connect(peer->server_flow, PeerChat_GetSendOutput(&peer->chat)); - - // set have chat - peer->have_chat = 1; - - // set have no resetpeer - peer->have_resetpeer = 0; - - // init local flow - if (!DataProtoFlow_Init(&peer->local_dpflow, &device_dpsource, my_id, peer->id, options.send_buffer_size, -1, NULL, NULL)) { - peer_log(peer, BLOG_ERROR, "DataProtoFlow_Init failed"); - goto fail4; - } - - // init frame decider peer - if (!FrameDeciderPeer_Init(&peer->decider_peer, &frame_decider, peer, (BLog_logfunc)peer_logfunc)) { - peer_log(peer, BLOG_ERROR, "FrameDeciderPeer_Init failed"); - goto fail5; - } - - // init receive peer - DPReceivePeer_Init(&peer->receive_peer, &device_output_dprd, peer->id, &peer->decider_peer, !!(peer->flags & SCID_NEWCLIENT_FLAG_RELAY_CLIENT)); - - // have no link - peer->have_link = 0; - - // have no relaying - peer->relaying_peer = NULL; - - // not waiting for relay - peer->waiting_relay = 0; - - // init reset timer - BTimer_Init(&peer->reset_timer, PEER_RETRY_TIME, (BTimer_handler)peer_reset_timer_handler, peer); - - // is not relay server - peer->is_relay = 0; - - // init binding - peer->binding = 0; - - // add to peers list - LinkedList1_Append(&peers, &peer->list_node); - num_peers++; - - switch (chat_ssl_mode) { - case PEERCHAT_SSL_NONE: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in plaintext mode"); - break; - case PEERCHAT_SSL_CLIENT: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in SSL client mode"); - break; - case PEERCHAT_SSL_SERVER: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in SSL server mode"); - break; - } - - return; - -fail5: - DataProtoFlow_Free(&peer->local_dpflow); -fail4: - server_flow_disconnect(peer->server_flow); - PeerChat_Free(&peer->chat); -fail3: - server_flow_free(peer->server_flow); -fail2: - BPending_Free(&peer->job_init); - if (peer->common_name) { - PORT_Free(peer->common_name); - } -fail1: - free(peer); -fail0: - return; -} - -void peer_remove (struct peer_data *peer, int exiting) -{ - peer_log(peer, BLOG_INFO, "removing"); - - // cleanup connections - peer_cleanup_connections(peer); - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - ASSERT(!peer->is_relay) - - // remove from peers list - LinkedList1_Remove(&peers, &peer->list_node); - num_peers--; - - // free reset timer - BReactor_RemoveTimer(&ss, &peer->reset_timer); - - // free receive peer - DPReceivePeer_Free(&peer->receive_peer); - - // free frame decider - FrameDeciderPeer_Free(&peer->decider_peer); - - // free local flow - DataProtoFlow_Free(&peer->local_dpflow); - - // free chat - if (peer->have_chat) { - peer_free_chat(peer); - } - - // free resetpeer - if (peer->have_resetpeer) { - // disconnect resetpeer source from server flow - server_flow_disconnect(peer->server_flow); - - // free resetpeer source - SinglePacketSource_Free(&peer->resetpeer_source); - } - - // free/die server flow - if (exiting || !PacketPassFairQueueFlow_IsBusy(&peer->server_flow->qflow)) { - server_flow_free(peer->server_flow); - } else { - server_flow_die(peer->server_flow); - } - - // free jobs - BPending_Free(&peer->job_init); - - // free common name - if (peer->common_name) { - PORT_Free(peer->common_name); - } - - // free peer structure - free(peer); -} - -void peer_logfunc (struct peer_data *peer) -{ - BLog_Append("peer %d", (int)peer->id); - if (peer->common_name) { - BLog_Append(" (%s)", peer->common_name); - } - BLog_Append(": "); -} - -void peer_log (struct peer_data *peer, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)peer_logfunc, peer, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -int peer_am_master (struct peer_data *peer) -{ - return (my_id > peer->id); -} - -void peer_free_chat (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - - // disconnect chat from server flow - server_flow_disconnect(peer->server_flow); - - // free chat - PeerChat_Free(&peer->chat); - - // set have no chat - peer->have_chat = 0; -} - -int peer_init_link (struct peer_data *peer) -{ - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - ASSERT(!peer->is_relay) - - // init receive receiver - DPReceiveReceiver_Init(&peer->receive_receiver, &peer->receive_peer); - PacketPassInterface *recv_if = DPReceiveReceiver_GetInput(&peer->receive_receiver); - - // init transport-specific link objects - PacketPassInterface *link_if; - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // init DatagramPeerIO - if (!DatagramPeerIO_Init( - &peer->pio.udp.pio, &ss, data_mtu, CLIENT_UDP_MTU, sp_params, - options.fragmentation_latency, PEER_UDP_ASSEMBLER_NUM_FRAMES, recv_if, - options.otp_num_warn, &twd, peer, - (BLog_logfunc)peer_logfunc, - (DatagramPeerIO_handler_error)peer_udp_pio_handler_error, - (DatagramPeerIO_handler_otp_warning)peer_udp_pio_handler_seed_warning, - (DatagramPeerIO_handler_otp_ready)peer_udp_pio_handler_seed_ready - )) { - peer_log(peer, BLOG_ERROR, "DatagramPeerIO_Init failed"); - goto fail1; - } - - if (SPPROTO_HAVE_OTP(sp_params)) { - // init send seed state - peer->pio.udp.sendseed_nextid = 0; - peer->pio.udp.sendseed_sent = 0; - - // init send seed job - BPending_Init(&peer->pio.udp.job_send_seed, BReactor_PendingGroup(&ss), (BPending_handler)peer_job_send_seed, peer); - } - - link_if = DatagramPeerIO_GetSendInput(&peer->pio.udp.pio); - } else { - // init StreamPeerIO - if (!StreamPeerIO_Init( - &peer->pio.tcp.pio, &ss, &twd, options.peer_ssl, ssl_flags(), - (options.peer_ssl ? peer->cert : NULL), - (options.peer_ssl ? peer->cert_len : -1), - data_mtu, - (options.peer_tcp_socket_sndbuf >= 0 ? options.peer_tcp_socket_sndbuf : PEER_DEFAULT_TCP_SOCKET_SNDBUF), - recv_if, - (BLog_logfunc)peer_logfunc, - (StreamPeerIO_handler_error)peer_tcp_pio_handler_error, peer - )) { - peer_log(peer, BLOG_ERROR, "StreamPeerIO_Init failed"); - goto fail1; - } - - link_if = StreamPeerIO_GetSendInput(&peer->pio.tcp.pio); - } - - // init sending - if (!DataProtoSink_Init(&peer->send_dp, &ss, link_if, PEER_KEEPALIVE_INTERVAL, PEER_KEEPALIVE_RECEIVE_TIMER, (DataProtoSink_handler)peer_dataproto_handler, peer)) { - peer_log(peer, BLOG_ERROR, "DataProto_Init failed"); - goto fail2; - } - - // attach local flow to our DataProtoSink - DataProtoFlow_Attach(&peer->local_dpflow, &peer->send_dp); - - // attach receive peer to our DataProtoSink - DPReceivePeer_AttachSink(&peer->receive_peer, &peer->send_dp); - - // set have link - peer->have_link = 1; - - return 1; - -fail2: - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Free(&peer->pio.udp.job_send_seed); - } - DatagramPeerIO_Free(&peer->pio.udp.pio); - } else { - StreamPeerIO_Free(&peer->pio.tcp.pio); - } -fail1: - DPReceiveReceiver_Free(&peer->receive_receiver); - return 0; -} - -void peer_free_link (struct peer_data *peer) -{ - ASSERT(peer->have_link) - ASSERT(!peer->is_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // detach receive peer from our DataProtoSink - DPReceivePeer_DetachSink(&peer->receive_peer); - - // detach local flow from our DataProtoSink - DataProtoFlow_Detach(&peer->local_dpflow); - - // free sending - DataProtoSink_Free(&peer->send_dp); - - // free transport-specific link objects - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Free(&peer->pio.udp.job_send_seed); - } - DatagramPeerIO_Free(&peer->pio.udp.pio); - } else { - StreamPeerIO_Free(&peer->pio.tcp.pio); - } - - // free receive receiver - DPReceiveReceiver_Free(&peer->receive_receiver); - - // set have no link - peer->have_link = 0; -} - -void peer_cleanup_connections (struct peer_data *peer) -{ - if (peer->have_link) { - if (peer->is_relay) { - peer_disable_relay_provider(peer); - } - peer_free_link(peer); - } - else if (peer->relaying_peer) { - peer_free_relaying(peer); - } - else if (peer->waiting_relay) { - peer_unregister_need_relay(peer); - } - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - ASSERT(!peer->is_relay) -} - -void peer_enable_relay_provider (struct peer_data *peer) -{ - ASSERT(peer->have_link) - ASSERT(!peer->is_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // add to relays list - LinkedList1_Append(&relays, &peer->relay_list_node); - - // init users list - LinkedList1_Init(&peer->relay_users); - - // set is relay - peer->is_relay = 1; - - // assign relays - assign_relays(); -} - -void peer_disable_relay_provider (struct peer_data *peer) -{ - ASSERT(peer->is_relay) - - ASSERT(peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // disconnect relay users - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&peer->relay_users)) { - struct peer_data *relay_user = UPPER_OBJECT(list_node, struct peer_data, relaying_list_node); - ASSERT(relay_user->relaying_peer == peer) - - // disconnect relay user - peer_free_relaying(relay_user); - - // add it to need relay list - peer_register_need_relay(relay_user); - } - - // remove from relays list - LinkedList1_Remove(&relays, &peer->relay_list_node); - - // set is not relay - peer->is_relay = 0; - - // assign relays - assign_relays(); -} - -void peer_install_relaying (struct peer_data *peer, struct peer_data *relay) -{ - ASSERT(!peer->relaying_peer) - ASSERT(!peer->have_link) - ASSERT(!peer->waiting_relay) - ASSERT(relay->is_relay) - - ASSERT(!peer->is_relay) - ASSERT(relay->have_link) - - peer_log(peer, BLOG_INFO, "installing relaying through %d", (int)relay->id); - - // add to relay's users list - LinkedList1_Append(&relay->relay_users, &peer->relaying_list_node); - - // attach local flow to relay - DataProtoFlow_Attach(&peer->local_dpflow, &relay->send_dp); - - // set relaying - peer->relaying_peer = relay; -} - -void peer_free_relaying (struct peer_data *peer) -{ - ASSERT(peer->relaying_peer) - - ASSERT(!peer->have_link) - ASSERT(!peer->waiting_relay) - - struct peer_data *relay = peer->relaying_peer; - ASSERT(relay->is_relay) - ASSERT(relay->have_link) - - peer_log(peer, BLOG_INFO, "uninstalling relaying through %d", (int)relay->id); - - // detach local flow from relay - DataProtoFlow_Detach(&peer->local_dpflow); - - // remove from relay's users list - LinkedList1_Remove(&relay->relay_users, &peer->relaying_list_node); - - // set not relaying - peer->relaying_peer = NULL; -} - -void peer_need_relay (struct peer_data *peer) -{ - ASSERT(!peer->is_relay) - - if (peer->waiting_relay) { - // already waiting for relay, do nothing - return; - } - - if (peer->have_link) { - peer_free_link(peer); - } - else if (peer->relaying_peer) { - peer_free_relaying(peer); - } - - // register the peer as needing a relay - peer_register_need_relay(peer); - - // assign relays - assign_relays(); -} - -void peer_register_need_relay (struct peer_data *peer) -{ - ASSERT(!peer->waiting_relay) - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - - ASSERT(!peer->is_relay) - - // add to need relay list - LinkedList1_Append(&waiting_relay_peers, &peer->waiting_relay_list_node); - - // set waiting relay - peer->waiting_relay = 1; -} - -void peer_unregister_need_relay (struct peer_data *peer) -{ - ASSERT(peer->waiting_relay) - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->is_relay) - - // remove from need relay list - LinkedList1_Remove(&waiting_relay_peers, &peer->waiting_relay_list_node); - - // set not waiting relay - peer->waiting_relay = 0; -} - -void peer_reset (struct peer_data *peer) -{ - peer_log(peer, BLOG_NOTICE, "resetting"); - - // cleanup connections - peer_cleanup_connections(peer); - - if (peer_am_master(peer)) { - // if we're the master, schedule retry - BReactor_SetTimer(&ss, &peer->reset_timer); - } else { - // if we're the slave, report to master - peer_send_simple(peer, MSGID_YOURETRY); - } -} - -void peer_resetpeer (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - ASSERT(!peer->have_resetpeer) - - // free chat - peer_free_chat(peer); - - // build resetpeer packet - struct packetproto_header pp_header; - struct sc_header sc_header; - struct sc_client_resetpeer sc_resetpeer; - pp_header.len = htol16(sizeof(struct sc_header) + sizeof(struct sc_client_resetpeer)); - sc_header.type = htol8(SCID_RESETPEER); - sc_resetpeer.clientid = htol16(peer->id); - memcpy(peer->resetpeer_packet, &pp_header, sizeof(pp_header)); - memcpy(peer->resetpeer_packet + sizeof(pp_header), &sc_header, sizeof(sc_header)); - memcpy(peer->resetpeer_packet + sizeof(pp_header) + sizeof(sc_header), &sc_resetpeer, sizeof(sc_resetpeer)); - - // init resetpeer sourse - SinglePacketSource_Init(&peer->resetpeer_source, peer->resetpeer_packet, sizeof(peer->resetpeer_packet), BReactor_PendingGroup(&ss)); - - // connect server flow to resetpeer source - server_flow_connect(peer->server_flow, SinglePacketSource_GetOutput(&peer->resetpeer_source)); - - // set have resetpeer - peer->have_resetpeer = 1; -} - -void peer_chat_handler_error (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - ASSERT(!peer->have_resetpeer) - - peer_log(peer, BLOG_ERROR, "chat error, sending resetpeer"); - - peer_resetpeer(peer); -} - -void peer_chat_handler_message (struct peer_data *peer, uint8_t *data, int data_len) -{ - ASSERT(peer->have_chat) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // parse message - msgParser parser; - if (!msgParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_NOTICE, "msg: failed to parse"); - return; - } - - // read message - uint16_t type = 0; // to remove warning - ASSERT_EXECUTE(msgParser_Gettype(&parser, &type)) - uint8_t *payload = NULL; // to remove warning - int payload_len = 0; // to remove warning - ASSERT_EXECUTE(msgParser_Getpayload(&parser, &payload, &payload_len)) - - // dispatch according to message type - switch (type) { - case MSGID_YOUCONNECT: - peer_msg_youconnect(peer, payload, payload_len); - return; - case MSGID_CANNOTCONNECT: - peer_msg_cannotconnect(peer, payload, payload_len); - return; - case MSGID_CANNOTBIND: - peer_msg_cannotbind(peer, payload, payload_len); - return; - case MSGID_YOURETRY: - peer_msg_youretry(peer, payload, payload_len); - return; - case MSGID_SEED: - peer_msg_seed(peer, payload, payload_len); - return; - case MSGID_CONFIRMSEED: - peer_msg_confirmseed(peer, payload, payload_len); - return; - default: - BLog(BLOG_NOTICE, "msg: unknown type"); - return; - } -} - -void peer_msg_youconnect (struct peer_data *peer, uint8_t *data, int data_len) -{ - // init parser - msg_youconnectParser parser; - if (!msg_youconnectParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to parse"); - return; - } - - // try addresses - BAddr addr; - while (1) { - // get address message - uint8_t *addrmsg_data; - int addrmsg_len; - if (!msg_youconnectParser_Getaddr(&parser, &addrmsg_data, &addrmsg_len)) { - peer_log(peer, BLOG_NOTICE, "msg_youconnect: no usable addresses"); - peer_send_simple(peer, MSGID_CANNOTCONNECT); - return; - } - - // parse address message - msg_youconnect_addrParser aparser; - if (!msg_youconnect_addrParser_Init(&aparser, addrmsg_data, addrmsg_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to parse address message"); - return; - } - - // check if the address scope is known - uint8_t *name_data = NULL; // to remove warning - int name_len = 0; // to remove warning - ASSERT_EXECUTE(msg_youconnect_addrParser_Getname(&aparser, &name_data, &name_len)) - char *name; - if (!(name = address_scope_known(name_data, name_len))) { - continue; - } - - // read address - uint8_t *addr_data = NULL; // to remove warning - int addr_len = 0; // to remove warning - ASSERT_EXECUTE(msg_youconnect_addrParser_Getaddr(&aparser, &addr_data, &addr_len)) - if (!addr_read(addr_data, addr_len, &addr)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to read address"); - continue; - } - - peer_log(peer, BLOG_NOTICE, "msg_youconnect: using address in scope '%s'", name); - break; - } - - // discard further addresses - msg_youconnectParser_Forwardaddr(&parser); - - uint8_t *key = NULL; - uint64_t password = 0; - - // read additonal parameters - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - int key_len; - if (!msg_youconnectParser_Getkey(&parser, &key, &key_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: no key"); - return; - } - if (key_len != BEncryption_cipher_key_size(sp_params.encryption_mode)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: wrong key size"); - return; - } - } - } else { - if (!msg_youconnectParser_Getpassword(&parser, &password)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: no password"); - return; - } - } - - if (!msg_youconnectParser_GotEverything(&parser)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: stray data"); - return; - } - - peer_log(peer, BLOG_INFO, "connecting"); - - peer_connect(peer, addr, key, password); -} - -void peer_msg_cannotconnect (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_cannotconnect: invalid length"); - return; - } - - if (!peer->binding) { - peer_log(peer, BLOG_WARNING, "msg_cannotconnect: not binding"); - return; - } - - peer_log(peer, BLOG_INFO, "peer could not connect"); - - // continue trying bind addresses - peer_bind(peer); - return; -} - -void peer_msg_cannotbind (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_cannotbind: invalid length"); - return; - } - - peer_log(peer, BLOG_INFO, "peer cannot bind"); - - if (!peer_am_master(peer)) { - peer_start_binding(peer); - } else { - if (!peer->is_relay) { - peer_need_relay(peer); - } - } -} - -void peer_msg_seed (struct peer_data *peer, uint8_t *data, int data_len) -{ - msg_seedParser parser; - if (!msg_seedParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_seed: failed to parse"); - return; - } - - // read message - uint16_t seed_id = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getseed_id(&parser, &seed_id)) - uint8_t *key = NULL; // to remove warning - int key_len = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getkey(&parser, &key, &key_len)) - uint8_t *iv = NULL; // to remove warning - int iv_len = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getiv(&parser, &iv, &iv_len)) - - if (options.transport_mode != TRANSPORT_MODE_UDP) { - peer_log(peer, BLOG_WARNING, "msg_seed: not in UDP mode"); - return; - } - - if (!SPPROTO_HAVE_OTP(sp_params)) { - peer_log(peer, BLOG_WARNING, "msg_seed: OTPs disabled"); - return; - } - - if (key_len != BEncryption_cipher_key_size(sp_params.otp_mode)) { - peer_log(peer, BLOG_WARNING, "msg_seed: wrong key length"); - return; - } - - if (iv_len != BEncryption_cipher_block_size(sp_params.otp_mode)) { - peer_log(peer, BLOG_WARNING, "msg_seed: wrong IV length"); - return; - } - - if (!peer->have_link) { - peer_log(peer, BLOG_WARNING, "msg_seed: have no link"); - return; - } - - peer_log(peer, BLOG_DEBUG, "received OTP receive seed"); - - // add receive seed - DatagramPeerIO_AddOTPRecvSeed(&peer->pio.udp.pio, seed_id, key, iv); - - // remember seed ID so we can confirm it from peer_udp_pio_handler_seed_ready - peer->pio.udp.pending_recvseed_id = seed_id; -} - -void peer_msg_confirmseed (struct peer_data *peer, uint8_t *data, int data_len) -{ - msg_confirmseedParser parser; - if (!msg_confirmseedParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: failed to parse"); - return; - } - - // read message - uint16_t seed_id = 0; // to remove warning - ASSERT_EXECUTE(msg_confirmseedParser_Getseed_id(&parser, &seed_id)) - - if (options.transport_mode != TRANSPORT_MODE_UDP) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: not in UDP mode"); - return; - } - - if (!SPPROTO_HAVE_OTP(sp_params)) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: OTPs disabled"); - return; - } - - if (!peer->have_link) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: have no link"); - return; - } - - if (!peer->pio.udp.sendseed_sent) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: no seed has been sent"); - return; - } - - if (seed_id != peer->pio.udp.sendseed_sent_id) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: invalid seed: expecting %d, received %d", (int)peer->pio.udp.sendseed_sent_id, (int)seed_id); - return; - } - - peer_log(peer, BLOG_DEBUG, "OTP send seed confirmed"); - - // no longer waiting for confirmation - peer->pio.udp.sendseed_sent = 0; - - // start using the seed - DatagramPeerIO_SetOTPSendSeed(&peer->pio.udp.pio, peer->pio.udp.sendseed_sent_id, peer->pio.udp.sendseed_sent_key, peer->pio.udp.sendseed_sent_iv); -} - -void peer_msg_youretry (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_youretry: invalid length"); - return; - } - - if (!peer_am_master(peer)) { - peer_log(peer, BLOG_WARNING, "msg_youretry: we are not master"); - return; - } - - peer_log(peer, BLOG_NOTICE, "requests reset"); - - peer_reset(peer); -} - -void peer_udp_pio_handler_seed_warning (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - - // generate and send a new seed - if (!peer->pio.udp.sendseed_sent) { - BPending_Set(&peer->pio.udp.job_send_seed); - } -} - -void peer_udp_pio_handler_seed_ready (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - - // send confirmation - peer_send_confirmseed(peer, peer->pio.udp.pending_recvseed_id); -} - -void peer_udp_pio_handler_error (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(peer->have_link) - - peer_log(peer, BLOG_NOTICE, "UDP connection failed"); - - peer_reset(peer); - return; -} - -void peer_tcp_pio_handler_error (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_TCP) - ASSERT(peer->have_link) - - peer_log(peer, BLOG_NOTICE, "TCP connection failed"); - - peer_reset(peer); - return; -} - -void peer_reset_timer_handler (struct peer_data *peer) -{ - ASSERT(peer_am_master(peer)) - - BLog(BLOG_NOTICE, "retry timer expired"); - - // start setup process - peer_start_binding(peer); -} - -void peer_start_binding (struct peer_data *peer) -{ - peer->binding = 1; - peer->binding_addrpos = 0; - - peer_bind(peer); -} - -void peer_bind (struct peer_data *peer) -{ - ASSERT(peer->binding) - ASSERT(peer->binding_addrpos >= 0) - ASSERT(peer->binding_addrpos <= num_bind_addrs) - - while (peer->binding_addrpos < num_bind_addrs) { - // if there are no external addresses, skip bind address - if (bind_addrs[peer->binding_addrpos].num_ext_addrs == 0) { - peer->binding_addrpos++; - continue; - } - - // try to bind - int cont; - peer_bind_one_address(peer, peer->binding_addrpos, &cont); - - // increment address counter - peer->binding_addrpos++; - - if (!cont) { - return; - } - } - - peer_log(peer, BLOG_NOTICE, "no more addresses to bind to"); - - // no longer binding - peer->binding = 0; - - // tell the peer we failed to bind - peer_send_simple(peer, MSGID_CANNOTBIND); - - // if we are the slave, setup relaying - if (!peer_am_master(peer)) { - if (!peer->is_relay) { - peer_need_relay(peer); - } - } -} - -void peer_bind_one_address (struct peer_data *peer, int addr_index, int *cont) -{ - ASSERT(addr_index >= 0) - ASSERT(addr_index < num_bind_addrs) - ASSERT(bind_addrs[addr_index].num_ext_addrs > 0) - - // get a fresh link - peer_cleanup_connections(peer); - if (!peer_init_link(peer)) { - peer_log(peer, BLOG_ERROR, "cannot get link"); - *cont = 0; - peer_reset(peer); - return; - } - - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // get addr - struct bind_addr *addr = &bind_addrs[addr_index]; - - // try binding to all ports in the range - int port_add; - for (port_add = 0; port_add < addr->num_ports; port_add++) { - BAddr tryaddr = addr->addr; - BAddr_SetPort(&tryaddr, hton16(ntoh16(BAddr_GetPort(&tryaddr)) + port_add)); - if (DatagramPeerIO_Bind(&peer->pio.udp.pio, tryaddr)) { - break; - } - } - if (port_add == addr->num_ports) { - BLog(BLOG_NOTICE, "failed to bind to any port"); - *cont = 1; - return; - } - - uint8_t key[BENCRYPTION_MAX_KEY_SIZE]; - - // generate and set encryption key - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - BRandom_randomize(key, BEncryption_cipher_key_size(sp_params.encryption_mode)); - DatagramPeerIO_SetEncryptionKey(&peer->pio.udp.pio, key); - } - - // schedule sending OTP seed - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Set(&peer->pio.udp.job_send_seed); - } - - // send connectinfo - peer_send_conectinfo(peer, addr_index, port_add, key, 0); - } else { - // order StreamPeerIO to listen - uint64_t pass; - StreamPeerIO_Listen(&peer->pio.tcp.pio, &listeners[addr_index], &pass); - - // send connectinfo - peer_send_conectinfo(peer, addr_index, 0, NULL, pass); - } - - peer_log(peer, BLOG_NOTICE, "bound to address number %d", addr_index); - - *cont = 0; -} - -void peer_connect (struct peer_data *peer, BAddr addr, uint8_t* encryption_key, uint64_t password) -{ - // get a fresh link - peer_cleanup_connections(peer); - if (!peer_init_link(peer)) { - peer_log(peer, BLOG_ERROR, "cannot get link"); - peer_reset(peer); - return; - } - - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // order DatagramPeerIO to connect - if (!DatagramPeerIO_Connect(&peer->pio.udp.pio, addr)) { - peer_log(peer, BLOG_NOTICE, "DatagramPeerIO_Connect failed"); - peer_reset(peer); - return; - } - - // set encryption key - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - DatagramPeerIO_SetEncryptionKey(&peer->pio.udp.pio, encryption_key); - } - - // generate and send a send seed - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Set(&peer->pio.udp.job_send_seed); - } - } else { - // order StreamPeerIO to connect - if (!StreamPeerIO_Connect(&peer->pio.tcp.pio, addr, password, client_cert, client_key)) { - peer_log(peer, BLOG_NOTICE, "StreamPeerIO_Connect failed"); - peer_reset(peer); - return; - } - } -} - -static int peer_start_msg (struct peer_data *peer, void **data, int type, int len) -{ - ASSERT(len >= 0) - ASSERT(len <= MSG_MAX_PAYLOAD) - ASSERT(!(len > 0) || data) - ASSERT(peer->chat_send_msg_len == -1) - - // make sure we have chat - if (!peer->have_chat) { - peer_log(peer, BLOG_ERROR, "cannot send message, chat is down"); - return 0; - } - -#ifdef SIMULATE_PEER_OUT_OF_BUFFER - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < SIMULATE_PEER_OUT_OF_BUFFER) { - peer_log(peer, BLOG_ERROR, "simulating out of buffer, sending resetpeer"); - peer_resetpeer(peer); - return 0; - } -#endif - - // obtain buffer location - uint8_t *packet; - if (!PeerChat_StartMessage(&peer->chat, &packet)) { - peer_log(peer, BLOG_ERROR, "cannot send message, out of buffer, sending resetpeer"); - peer_resetpeer(peer); - return 0; - } - - // write fields - msgWriter writer; - msgWriter_Init(&writer, packet); - msgWriter_Addtype(&writer, type); - uint8_t *payload_dst = msgWriter_Addpayload(&writer, len); - msgWriter_Finish(&writer); - - // set have message - peer->chat_send_msg_len = len; - - if (data) { - *data = payload_dst; - } - return 1; -} - -static void peer_end_msg (struct peer_data *peer) -{ - ASSERT(peer->chat_send_msg_len >= 0) - ASSERT(peer->have_chat) - - // submit packet to buffer - PeerChat_EndMessage(&peer->chat, msg_SIZEtype + msg_SIZEpayload(peer->chat_send_msg_len)); - - // set no message - peer->chat_send_msg_len = -1; -} - -void peer_send_simple (struct peer_data *peer, int msgid) -{ - if (!peer_start_msg(peer, NULL, msgid, 0)) { - return; - } - peer_end_msg(peer); -} - -void peer_send_conectinfo (struct peer_data *peer, int addr_index, int port_adjust, uint8_t *enckey, uint64_t pass) -{ - ASSERT(addr_index >= 0) - ASSERT(addr_index < num_bind_addrs) - ASSERT(bind_addrs[addr_index].num_ext_addrs > 0) - - // get address - struct bind_addr *bind_addr = &bind_addrs[addr_index]; - - // remember encryption key size - int key_size = 0; // to remove warning - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - key_size = BEncryption_cipher_key_size(sp_params.encryption_mode); - } - - // calculate message length .. - int msg_len = 0; - - // addresses - for (int i = 0; i < bind_addr->num_ext_addrs; i++) { - int addrmsg_len = - msg_youconnect_addr_SIZEname(strlen(bind_addr->ext_addrs[i].scope)) + - msg_youconnect_addr_SIZEaddr(addr_size(bind_addr->ext_addrs[i].addr)); - msg_len += msg_youconnect_SIZEaddr(addrmsg_len); - } - - // encryption key - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - msg_len += msg_youconnect_SIZEkey(key_size); - } - - // password - if (options.transport_mode == TRANSPORT_MODE_TCP) { - msg_len += msg_youconnect_SIZEpassword; - } - - // check if it's too big (because of the addresses) - if (msg_len > MSG_MAX_PAYLOAD) { - BLog(BLOG_ERROR, "cannot send too big youconnect message"); - return; - } - - // start message - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_YOUCONNECT, msg_len)) { - return; - } - - // init writer - msg_youconnectWriter writer; - msg_youconnectWriter_Init(&writer, msg); - - // write addresses - for (int i = 0; i < bind_addr->num_ext_addrs; i++) { - int name_len = strlen(bind_addr->ext_addrs[i].scope); - int addr_len = addr_size(bind_addr->ext_addrs[i].addr); - - // get a pointer for writing the address - int addrmsg_len = - msg_youconnect_addr_SIZEname(name_len) + - msg_youconnect_addr_SIZEaddr(addr_len); - uint8_t *addrmsg_dst = msg_youconnectWriter_Addaddr(&writer, addrmsg_len); - - // init address writer - msg_youconnect_addrWriter awriter; - msg_youconnect_addrWriter_Init(&awriter, addrmsg_dst); - - // write scope - uint8_t *name_dst = msg_youconnect_addrWriter_Addname(&awriter, name_len); - memcpy(name_dst, bind_addr->ext_addrs[i].scope, name_len); - - // write address with adjusted port - BAddr addr = bind_addr->ext_addrs[i].addr; - BAddr_SetPort(&addr, hton16(ntoh16(BAddr_GetPort(&addr)) + port_adjust)); - uint8_t *addr_dst = msg_youconnect_addrWriter_Addaddr(&awriter, addr_len); - addr_write(addr_dst, addr); - - // finish address writer - msg_youconnect_addrWriter_Finish(&awriter); - } - - // write encryption key - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - uint8_t *key_dst = msg_youconnectWriter_Addkey(&writer, key_size); - memcpy(key_dst, enckey, key_size); - } - - // write password - if (options.transport_mode == TRANSPORT_MODE_TCP) { - msg_youconnectWriter_Addpassword(&writer, pass); - } - - // finish writer - msg_youconnectWriter_Finish(&writer); - - // end message - peer_end_msg(peer); -} - -void peer_send_confirmseed (struct peer_data *peer, uint16_t seed_id) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - - // send confirmation - int msg_len = msg_confirmseed_SIZEseed_id; - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_CONFIRMSEED, msg_len)) { - return; - } - msg_confirmseedWriter writer; - msg_confirmseedWriter_Init(&writer, msg); - msg_confirmseedWriter_Addseed_id(&writer, seed_id); - msg_confirmseedWriter_Finish(&writer); - peer_end_msg(peer); -} - -void peer_dataproto_handler (struct peer_data *peer, int up) -{ - ASSERT(peer->have_link) - - if (up) { - peer_log(peer, BLOG_INFO, "up"); - - // if it can be a relay provided, enable it - if ((peer->flags & SCID_NEWCLIENT_FLAG_RELAY_SERVER) && !peer->is_relay) { - peer_enable_relay_provider(peer); - } - } else { - peer_log(peer, BLOG_INFO, "down"); - - // if it is a relay provider, disable it - if (peer->is_relay) { - peer_disable_relay_provider(peer); - } - } -} - -struct peer_data * find_peer_by_id (peerid_t id) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&peers); node; node = LinkedList1Node_Next(node)) { - struct peer_data *peer = UPPER_OBJECT(node, struct peer_data, list_node); - if (peer->id == id) { - return peer; - } - } - - return NULL; -} - -void device_error_handler (void *unused) -{ - BLog(BLOG_ERROR, "device error"); - - terminate(); -} - -void device_dpsource_handler (void *unused, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - ASSERT(frame_len <= device_mtu) - - // give frame to decider - FrameDecider_AnalyzeAndDecide(&frame_decider, frame, frame_len); - - // forward frame to peers - FrameDeciderPeer *decider_peer = FrameDecider_NextDestination(&frame_decider); - while (decider_peer) { - FrameDeciderPeer *next = FrameDecider_NextDestination(&frame_decider); - struct peer_data *peer = UPPER_OBJECT(decider_peer, struct peer_data, decider_peer); - DataProtoFlow_Route(&peer->local_dpflow, !!next); - decider_peer = next; - } -} - -void assign_relays (void) -{ - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&waiting_relay_peers)) { - struct peer_data *peer = UPPER_OBJECT(list_node, struct peer_data, waiting_relay_list_node); - ASSERT(peer->waiting_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->have_link) - - // get a relay - LinkedList1Node *list_node2 = LinkedList1_GetFirst(&relays); - if (!list_node2) { - BLog(BLOG_NOTICE, "no relays"); - return; - } - struct peer_data *relay = UPPER_OBJECT(list_node2, struct peer_data, relay_list_node); - ASSERT(relay->is_relay) - - // no longer waiting for relay - peer_unregister_need_relay(peer); - - // install the relay - peer_install_relaying(peer, relay); - } -} - -char * address_scope_known (uint8_t *name, int name_len) -{ - ASSERT(name_len >= 0) - - for (int i = 0; i < options.num_scopes; i++) { - if (name_len == strlen(options.scopes[i]) && !memcmp(name, options.scopes[i], name_len)) { - return options.scopes[i]; - } - } - - return NULL; -} - -void server_handler_error (void *user) -{ - BLog(BLOG_ERROR, "server connection failed, exiting"); - - terminate(); -} - -void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip) -{ - ASSERT(!server_ready) - - // remember our ID - my_id = param_my_id; - - // store server reported addresses - for (int i = 0; i < num_bind_addrs; i++) { - struct bind_addr *addr = &bind_addrs[i]; - for (int j = 0; j < addr->num_ext_addrs; j++) { - struct ext_addr *eaddr = &addr->ext_addrs[j]; - if (eaddr->server_reported_port >= 0) { - if (ext_ip == 0) { - BLog(BLOG_ERROR, "server did not provide our address"); - terminate(); - return; - } - BAddr_InitIPv4(&eaddr->addr, ext_ip, hton16(eaddr->server_reported_port)); - char str[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&eaddr->addr, str); - BLog(BLOG_INFO, "external address (%d,%d): server reported %s", i, j, str); - } - } - } - - // give receive device the ID - DPReceiveDevice_SetPeerID(&device_output_dprd, my_id); - - // init server queue - if (!PacketPassFairQueue_Init(&server_queue, ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss), 0, 1)) { - BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed"); - terminate(); - return; - } - - // set server ready - server_ready = 1; - - BLog(BLOG_INFO, "server: ready, my ID is %d", (int)my_id); -} - -void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - ASSERT(cert_len >= 0) - ASSERT(cert_len <= SCID_NEWCLIENT_MAX_CERT_LEN) - - // check if the peer already exists - if (find_peer_by_id(peer_id)) { - BLog(BLOG_WARNING, "server: newclient: peer already known"); - return; - } - - // make sure it's not the same ID as us - if (peer_id == my_id) { - BLog(BLOG_WARNING, "server: newclient: peer has our ID"); - return; - } - - // check if there is spece for the peer - if (num_peers >= options.max_peers) { - BLog(BLOG_WARNING, "server: newclient: no space for new peer (maximum number reached)"); - return; - } - - if (!options.ssl && cert_len > 0) { - BLog(BLOG_WARNING, "server: newclient: certificate supplied, but not using TLS"); - return; - } - - peer_add(peer_id, flags, cert, cert_len); -} - -void server_handler_endclient (void *user, peerid_t peer_id) -{ - ASSERT(server_ready) - - // find peer - struct peer_data *peer = find_peer_by_id(peer_id); - if (!peer) { - BLog(BLOG_WARNING, "server: endclient: peer %d not known", (int)peer_id); - return; - } - - // remove peer - peer_remove(peer, 0); -} - -void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len) -{ - ASSERT(server_ready) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // find peer - struct peer_data *peer = find_peer_by_id(peer_id); - if (!peer) { - BLog(BLOG_WARNING, "server: message: peer not known"); - return; - } - - // make sure we have chat - if (!peer->have_chat) { - peer_log(peer, BLOG_ERROR, "cannot process message, chat is down"); - return; - } - - // pass message to chat - PeerChat_InputReceived(&peer->chat, data, data_len); -} - -void peer_job_send_seed (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - ASSERT(!peer->pio.udp.sendseed_sent) - - peer_log(peer, BLOG_DEBUG, "sending OTP send seed"); - - int key_len = BEncryption_cipher_key_size(sp_params.otp_mode); - int iv_len = BEncryption_cipher_block_size(sp_params.otp_mode); - - // generate seed - peer->pio.udp.sendseed_sent_id = peer->pio.udp.sendseed_nextid; - BRandom_randomize(peer->pio.udp.sendseed_sent_key, key_len); - BRandom_randomize(peer->pio.udp.sendseed_sent_iv, iv_len); - - // set as sent, increment next seed ID - peer->pio.udp.sendseed_sent = 1; - peer->pio.udp.sendseed_nextid++; - - // send seed to the peer - int msg_len = msg_seed_SIZEseed_id + msg_seed_SIZEkey(key_len) + msg_seed_SIZEiv(iv_len); - if (msg_len > MSG_MAX_PAYLOAD) { - peer_log(peer, BLOG_ERROR, "OTP send seed message too big"); - return; - } - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_SEED, msg_len)) { - return; - } - msg_seedWriter writer; - msg_seedWriter_Init(&writer, msg); - msg_seedWriter_Addseed_id(&writer, peer->pio.udp.sendseed_sent_id); - uint8_t *key_dst = msg_seedWriter_Addkey(&writer, key_len); - memcpy(key_dst, peer->pio.udp.sendseed_sent_key, key_len); - uint8_t *iv_dst = msg_seedWriter_Addiv(&writer, iv_len); - memcpy(iv_dst, peer->pio.udp.sendseed_sent_iv, iv_len); - msg_seedWriter_Finish(&writer); - peer_end_msg(peer); -} - -void peer_job_init (struct peer_data *peer) -{ - // start setup process - if (peer_am_master(peer)) { - peer_start_binding(peer); - } -} - -struct server_flow * server_flow_init (void) -{ - ASSERT(server_ready) - - // allocate structure - struct server_flow *flow = (struct server_flow *)malloc(sizeof(*flow)); - if (!flow) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init queue flow - PacketPassFairQueueFlow_Init(&flow->qflow, &server_queue); - - // init connector - PacketRecvConnector_Init(&flow->connector, sizeof(struct packetproto_header) + SC_MAX_ENC, BReactor_PendingGroup(&ss)); - - // init encoder buffer - if (!SinglePacketBuffer_Init(&flow->encoder_buffer, PacketRecvConnector_GetOutput(&flow->connector), PacketPassFairQueueFlow_GetInput(&flow->qflow), BReactor_PendingGroup(&ss))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail1; - } - - // set not connected - flow->connected = 0; - - return flow; - -fail1: - PacketRecvConnector_Free(&flow->connector); - PacketPassFairQueueFlow_Free(&flow->qflow); - free(flow); -fail0: - return NULL; -} - -void server_flow_free (struct server_flow *flow) -{ - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - ASSERT(!flow->connected) - - // remove dying flow reference - if (flow == dying_server_flow) { - dying_server_flow = NULL; - } - - // free encoder buffer - SinglePacketBuffer_Free(&flow->encoder_buffer); - - // free connector - PacketRecvConnector_Free(&flow->connector); - - // free queue flow - PacketPassFairQueueFlow_Free(&flow->qflow); - - // free structure - free(flow); -} - -void server_flow_die (struct server_flow *flow) -{ - ASSERT(PacketPassFairQueueFlow_IsBusy(&flow->qflow)) - ASSERT(!flow->connected) - ASSERT(!dying_server_flow) - - // request notification when flow is done - PacketPassFairQueueFlow_SetBusyHandler(&flow->qflow, (PacketPassFairQueue_handler_busy)server_flow_qflow_handler_busy, flow); - - // set dying flow - dying_server_flow = flow; -} - -void server_flow_qflow_handler_busy (struct server_flow *flow) -{ - ASSERT(flow == dying_server_flow) - ASSERT(!flow->connected) - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - - // finally free flow - server_flow_free(flow); -} - -void server_flow_connect (struct server_flow *flow, PacketRecvInterface *input) -{ - ASSERT(!flow->connected) - ASSERT(flow != dying_server_flow) - - // connect input - PacketRecvConnector_ConnectInput(&flow->connector, input); - - // set connected - flow->connected = 1; -} - -void server_flow_disconnect (struct server_flow *flow) -{ - ASSERT(flow->connected) - ASSERT(flow != dying_server_flow) - - // disconnect input - PacketRecvConnector_DisconnectInput(&flow->connector); - - // set not connected - flow->connected = 0; -} diff --git a/external/badvpn_dns/client/client.h b/external/badvpn_dns/client/client.h deleted file mode 100644 index 595ed59..0000000 --- a/external/badvpn_dns/client/client.h +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @file client.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdint.h> - -#include <protocol/scproto.h> -#include <structure/LinkedList1.h> -#include <flow/PacketPassFairQueue.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketRecvConnector.h> -#include <client/DatagramPeerIO.h> -#include <client/StreamPeerIO.h> -#include <client/DataProto.h> -#include <client/DPReceive.h> -#include <client/FrameDecider.h> -#include <client/PeerChat.h> -#include <client/SinglePacketSource.h> - -// NOTE: all time values are in milliseconds - -// name of the program -#define PROGRAM_NAME "client" - -// server output buffer size -#define SERVER_BUFFER_MIN_PACKETS 200 - -// maximum UDP payload size -#define CLIENT_UDP_MTU 1472 - -// maximum number of pending TCP PasswordListener clients -#define TCP_MAX_PASSWORD_LISTENER_CLIENTS 50 - -// maximum number of peers -#define DEFAULT_MAX_PEERS 256 -// maximum number of peer's MAC addresses to remember -#define PEER_DEFAULT_MAX_MACS 16 -// maximum number of multicast addresses per peer -#define PEER_DEFAULT_MAX_GROUPS 16 -// how long we wait for a packet to reach full size before sending it (see FragmentProtoDisassembler latency argument) -#define PEER_DEFAULT_UDP_FRAGMENTATION_LATENCY 0 -// value related to how much out-of-order input we tolerate (see FragmentProtoAssembler num_frames argument) -#define PEER_UDP_ASSEMBLER_NUM_FRAMES 4 -// socket send buffer (SO_SNDBUF) for peer TCP connections, <=0 to not set -#define PEER_DEFAULT_TCP_SOCKET_SNDBUF 1048576 -// keep-alive packet interval for p2p communication -#define PEER_KEEPALIVE_INTERVAL 10000 -// keep-alive receive timer for p2p communication (after how long to consider the link down) -#define PEER_KEEPALIVE_RECEIVE_TIMER 22000 -// size of frame send buffer, in number of frames -#define PEER_DEFAULT_SEND_BUFFER_SIZE 32 -// size of frame send buffer for relayed packets, in number of frames -#define PEER_DEFAULT_SEND_BUFFER_RELAY_SIZE 32 -// time after an unused relay flow is freed (-1 for never) -#define PEER_RELAY_FLOW_INACTIVITY_TIME 10000 -// retry time -#define PEER_RETRY_TIME 5000 - -// for how long a peer can send no Membership Reports for a group -// before the peer and group are disassociated -#define DEFAULT_IGMP_GROUP_MEMBERSHIP_INTERVAL 260000 -// how long to wait for joins after a Group Specific query has been -// forwarded to a peer before assuming there are no listeners at the peer -#define DEFAULT_IGMP_LAST_MEMBER_QUERY_TIME 2000 - -// maximum bind addresses -#define MAX_BIND_ADDRS 8 -// maximum external addresses per bind address -#define MAX_EXT_ADDRS 8 -// maximum scopes -#define MAX_SCOPES 8 - -//#define SIMULATE_PEER_OUT_OF_BUFFER 70 - -struct server_flow { - PacketPassFairQueueFlow qflow; - SinglePacketBuffer encoder_buffer; - PacketRecvConnector connector; - int connected; -}; - -struct peer_data { - // peer identifier - peerid_t id; - - // flags provided by the server - int flags; - - // certificate reported by the server, defined only if using SSL - uint8_t cert[SCID_NEWCLIENT_MAX_CERT_LEN]; - int cert_len; - char *common_name; - - // init job - BPending job_init; - - // server flow - struct server_flow *server_flow; - - // chat - int have_chat; - PeerChat chat; - int chat_send_msg_len; - - // resetpeer source (when chat fails) - int have_resetpeer; - uint8_t resetpeer_packet[sizeof(struct packetproto_header) + sizeof(struct sc_header) + sizeof(struct sc_client_resetpeer)]; - SinglePacketSource resetpeer_source; - - // local flow - DataProtoFlow local_dpflow; - - // frame decider peer - FrameDeciderPeer decider_peer; - - // receive peer - DPReceivePeer receive_peer; - - // flag if link objects are initialized - int have_link; - - // receive receiver - DPReceiveReceiver receive_receiver; - - // transport-specific link objects - union { - struct { - DatagramPeerIO pio; - uint16_t sendseed_nextid; - int sendseed_sent; - uint16_t sendseed_sent_id; - uint8_t sendseed_sent_key[BENCRYPTION_MAX_KEY_SIZE]; - uint8_t sendseed_sent_iv[BENCRYPTION_MAX_BLOCK_SIZE]; - uint16_t pending_recvseed_id; - BPending job_send_seed; - } udp; - struct { - StreamPeerIO pio; - } tcp; - } pio; - - // link sending - DataProtoSink send_dp; - - // relaying objects - struct peer_data *relaying_peer; // peer through which we are relaying, or NULL - LinkedList1Node relaying_list_node; // node in relay peer's relay_users - - // waiting for relay data - int waiting_relay; - LinkedList1Node waiting_relay_list_node; - - // retry timer - BTimer reset_timer; - - // relay server specific - int is_relay; - LinkedList1Node relay_list_node; - LinkedList1 relay_users; - - // binding state - int binding; - int binding_addrpos; - - // peers linked list node - LinkedList1Node list_node; -}; diff --git a/external/badvpn_dns/cmake/modules/COPYING-CMAKE-SCRIPTS b/external/badvpn_dns/cmake/modules/COPYING-CMAKE-SCRIPTS deleted file mode 100644 index 4b41776..0000000 --- a/external/badvpn_dns/cmake/modules/COPYING-CMAKE-SCRIPTS +++ /dev/null @@ -1,22 +0,0 @@ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/badvpn_dns/cmake/modules/FindGLIB2.cmake b/external/badvpn_dns/cmake/modules/FindGLIB2.cmake deleted file mode 100644 index 09fd98d..0000000 --- a/external/badvpn_dns/cmake/modules/FindGLIB2.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# - Try to find the GLIB2 libraries -# Once done this will define -# -# GLIB2_FOUND - system has glib2 -# GLIB2_INCLUDE_DIR - the glib2 include directory -# GLIB2_LIBRARIES - glib2 library - -# Copyright (c) 2008 Laurent Montel, <montel@kde.org> -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES) - # Already in cache, be silent - set(GLIB2_FIND_QUIETLY TRUE) -endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES) - -find_package(PkgConfig) -pkg_check_modules(PC_LibGLIB2 QUIET glib-2.0) - -find_path(GLIB2_MAIN_INCLUDE_DIR - NAMES glib.h - HINTS ${PC_LibGLIB2_INCLUDEDIR} - PATH_SUFFIXES glib-2.0) - -find_library(GLIB2_LIBRARY - NAMES glib-2.0 - HINTS ${PC_LibGLIB2_LIBDIR} -) - -set(GLIB2_LIBRARIES ${GLIB2_LIBRARY}) - -# search the glibconfig.h include dir under the same root where the library is found -get_filename_component(glib2LibDir "${GLIB2_LIBRARIES}" PATH) - -find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h - PATH_SUFFIXES glib-2.0/include - HINTS ${PC_LibGLIB2_INCLUDEDIR} "${glib2LibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH}) - -set(GLIB2_INCLUDE_DIR "${GLIB2_MAIN_INCLUDE_DIR}") - -# not sure if this include dir is optional or required -# for now it is optional -if(GLIB2_INTERNAL_INCLUDE_DIR) - set(GLIB2_INCLUDE_DIR ${GLIB2_INCLUDE_DIR} "${GLIB2_INTERNAL_INCLUDE_DIR}") -endif(GLIB2_INTERNAL_INCLUDE_DIR) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR) - -mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES) diff --git a/external/badvpn_dns/cmake/modules/FindLibraryWithDebug.cmake b/external/badvpn_dns/cmake/modules/FindLibraryWithDebug.cmake deleted file mode 100644 index 58cd730..0000000 --- a/external/badvpn_dns/cmake/modules/FindLibraryWithDebug.cmake +++ /dev/null @@ -1,113 +0,0 @@ -# -# FIND_LIBRARY_WITH_DEBUG -# -> enhanced FIND_LIBRARY to allow the search for an -# optional debug library with a WIN32_DEBUG_POSTFIX similar -# to CMAKE_DEBUG_POSTFIX when creating a shared lib -# it has to be the second and third argument - -# Copyright (c) 2007, Christian Ehrlicher, <ch.ehrlicher@gmx.de> -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -MACRO(FIND_LIBRARY_WITH_DEBUG var_name win32_dbg_postfix_name dgb_postfix libname) - - IF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - - # no WIN32_DEBUG_POSTFIX -> simply pass all arguments to FIND_LIBRARY - FIND_LIBRARY(${var_name} - ${win32_dbg_postfix_name} - ${dgb_postfix} - ${libname} - ${ARGN} - ) - - ELSE(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - - IF(NOT WIN32) - # on non-win32 we don't need to take care about WIN32_DEBUG_POSTFIX - - FIND_LIBRARY(${var_name} ${libname} ${ARGN}) - - ELSE(NOT WIN32) - - # 1. get all possible libnames - SET(args ${ARGN}) - SET(newargs "") - SET(libnames_release "") - SET(libnames_debug "") - - LIST(LENGTH args listCount) - - IF("${libname}" STREQUAL "NAMES") - SET(append_rest 0) - LIST(APPEND args " ") - - FOREACH(i RANGE ${listCount}) - LIST(GET args ${i} val) - - IF(append_rest) - LIST(APPEND newargs ${val}) - ELSE(append_rest) - IF("${val}" STREQUAL "PATHS") - LIST(APPEND newargs ${val}) - SET(append_rest 1) - ELSE("${val}" STREQUAL "PATHS") - LIST(APPEND libnames_release "${val}") - LIST(APPEND libnames_debug "${val}${dgb_postfix}") - ENDIF("${val}" STREQUAL "PATHS") - ENDIF(append_rest) - - ENDFOREACH(i) - - ELSE("${libname}" STREQUAL "NAMES") - - # just one name - LIST(APPEND libnames_release "${libname}") - LIST(APPEND libnames_debug "${libname}${dgb_postfix}") - - SET(newargs ${args}) - - ENDIF("${libname}" STREQUAL "NAMES") - - # search the release lib - FIND_LIBRARY(${var_name}_RELEASE - NAMES ${libnames_release} - ${newargs} - ) - - # search the debug lib - FIND_LIBRARY(${var_name}_DEBUG - NAMES ${libnames_debug} - ${newargs} - ) - - IF(${var_name}_RELEASE AND ${var_name}_DEBUG) - - # both libs found - SET(${var_name} optimized ${${var_name}_RELEASE} - debug ${${var_name}_DEBUG}) - - ELSE(${var_name}_RELEASE AND ${var_name}_DEBUG) - - IF(${var_name}_RELEASE) - - # only release found - SET(${var_name} ${${var_name}_RELEASE}) - - ELSE(${var_name}_RELEASE) - - # only debug (or nothing) found - SET(${var_name} ${${var_name}_DEBUG}) - - ENDIF(${var_name}_RELEASE) - - ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG) - - MARK_AS_ADVANCED(${var_name}_RELEASE) - MARK_AS_ADVANCED(${var_name}_DEBUG) - - ENDIF(NOT WIN32) - - ENDIF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - -ENDMACRO(FIND_LIBRARY_WITH_DEBUG) diff --git a/external/badvpn_dns/cmake/modules/FindNSPR.cmake b/external/badvpn_dns/cmake/modules/FindNSPR.cmake deleted file mode 100644 index 6e8fed9..0000000 --- a/external/badvpn_dns/cmake/modules/FindNSPR.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Try to find the NSPR library -# Once done this will define -# -# NSPR_FOUND - system has the NSPR library -# NSPR_INCLUDE_DIRS - Include paths needed -# NSPR_LIBRARY_DIRS - Linker paths needed -# NSPR_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, <ambrop7@gmail.com> -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (NSPR_LIBRARIES) - set(NSPR_FIND_QUIETLY TRUE) -endif () - -set(NSPR_FOUND FALSE) - -if (WIN32) - find_path(NSPR_FIND_INCLUDE_DIR prerror.h) - - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_PLDS WIN32_DEBUG_POSTFIX d NAMES plds4 libplds4) - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_PLC WIN32_DEBUG_POSTFIX d NAMES plc4 libplc4) - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_NSPR WIN32_DEBUG_POSTFIX d NAMES nspr4 libnspr4) - - if (NSPR_FIND_INCLUDE_DIR AND NSPR_FIND_LIBRARIES_PLDS AND NSPR_FIND_LIBRARIES_PLC AND NSPR_FIND_LIBRARIES_NSPR) - set(NSPR_FOUND TRUE) - set(NSPR_INCLUDE_DIRS "${NSPR_FIND_INCLUDE_DIR}" CACHE STRING "NSPR include dirs") - set(NSPR_LIBRARY_DIRS "" CACHE STRING "NSPR library dirs") - set(NSPR_LIBRARIES "${NSPR_FIND_LIBRARIES_PLDS};${NSPR_FIND_LIBRARIES_PLC};${NSPR_FIND_LIBRARIES_NSPR}" CACHE STRING "NSPR libraries") - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(NSPR_PC nspr) - - if (NSPR_PC_FOUND) - set(NSPR_FOUND TRUE) - set(NSPR_INCLUDE_DIRS "${NSPR_PC_INCLUDE_DIRS}" CACHE STRING "NSPR include dirs") - set(NSPR_LIBRARY_DIRS "${NSPR_PC_LIBRARY_DIRS}" CACHE STRING "NSPR library dirs") - set(NSPR_LIBRARIES "${NSPR_PC_LIBRARIES}" CACHE STRING "NSPR libraries") - endif () -endif () - -if (NSPR_FOUND) - if (NOT NSPR_FIND_QUIETLY) - MESSAGE(STATUS "Found NSPR: ${NSPR_INCLUDE_DIRS} ${NSPR_LIBRARY_DIRS} ${NSPR_LIBRARIES}") - endif () -else () - if (NSPR_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find NSPR") - endif () -endif () - -mark_as_advanced(NSPR_INCLUDE_DIRS NSPR_LIBRARY_DIRS NSPR_LIBRARIES) diff --git a/external/badvpn_dns/cmake/modules/FindNSS.cmake b/external/badvpn_dns/cmake/modules/FindNSS.cmake deleted file mode 100644 index 17fd45a..0000000 --- a/external/badvpn_dns/cmake/modules/FindNSS.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Try to find the NSS library -# Once done this will define -# -# NSS_FOUND - system has the NSS library -# NSS_INCLUDE_DIRS - Include paths needed -# NSS_LIBRARY_DIRS - Linker paths needed -# NSS_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, <ambrop7@gmail.com> -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (NSS_LIBRARIES) - set(NSS_FIND_QUIETLY TRUE) -endif () - -set(NSS_FOUND FALSE) - -if (WIN32) - find_path(NSS_FIND_INCLUDE_DIR nss.h) - - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_SSL WIN32_DEBUG_POSTFIX d NAMES ssl3) - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_SMIME WIN32_DEBUG_POSTFIX d NAMES smime3) - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_NSS WIN32_DEBUG_POSTFIX d NAMES nss3) - - if (NSS_FIND_INCLUDE_DIR AND NSS_FIND_LIBRARIES_SSL AND NSS_FIND_LIBRARIES_SMIME AND NSS_FIND_LIBRARIES_NSS) - set(NSS_FOUND TRUE) - set(NSS_INCLUDE_DIRS "${NSS_FIND_INCLUDE_DIR}" CACHE STRING "NSS include dirs") - set(NSS_LIBRARY_DIRS "" CACHE STRING "NSS library dirs") - set(NSS_LIBRARIES "${NSS_FIND_LIBRARIES_SSL};${NSS_FIND_LIBRARIES_SMIME};${NSS_FIND_LIBRARIES_NSS}" CACHE STRING "NSS libraries") - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(NSS_PC nss) - - if (NSS_PC_FOUND) - set(NSS_FOUND TRUE) - set(NSS_INCLUDE_DIRS "${NSS_PC_INCLUDE_DIRS}" CACHE STRING "NSS include dirs") - set(NSS_LIBRARY_DIRS "${NSS_PC_LIBRARY_DIRS}" CACHE STRING "NSS library dirs") - set(NSS_LIBRARIES "${NSS_PC_LIBRARIES}" CACHE STRING "NSS libraries") - endif () -endif () - -if (NSS_FOUND) - if (NOT NSS_FIND_QUIETLY) - MESSAGE(STATUS "Found NSS: ${NSS_INCLUDE_DIRS} ${NSS_LIBRARY_DIRS} ${NSS_LIBRARIES}") - endif () -else () - if (NSS_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find NSS") - endif () -endif () - -mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARY_DIRS NSS_LIBRARIES) diff --git a/external/badvpn_dns/cmake/modules/FindOpenSSL.cmake b/external/badvpn_dns/cmake/modules/FindOpenSSL.cmake deleted file mode 100644 index 4434e95..0000000 --- a/external/badvpn_dns/cmake/modules/FindOpenSSL.cmake +++ /dev/null @@ -1,72 +0,0 @@ -# - Try to find the OpenSSL library -# Once done this will define -# -# OpenSSL_FOUND - system has the OpenSSL library -# OpenSSL_INCLUDE_DIRS - Include paths needed -# OpenSSL_LIBRARY_DIRS - Linker paths needed -# OpenSSL_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, <ambrop7@gmail.com> -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (OpenSSL_LIBRARIES) - set(OpenSSL_FIND_QUIETLY TRUE) -endif () - -set(OpenSSL_FOUND FALSE) - -if (WIN32) - find_path(OpenSSL_FIND_INCLUDE_DIR openssl/ssl.h) - - if (OpenSSL_FIND_INCLUDE_DIR) - # look for libraries built with GCC - find_library(OpenSSL_FIND_LIBRARIES_SSL NAMES ssl) - find_library(OpenSSL_FIND_LIBRARIES_CRYPTO NAMES crypto) - - if (OpenSSL_FIND_LIBRARIES_SSL AND OpenSSL_FIND_LIBRARIES_CRYPTO) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_LIBRARY_DIRS "" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_FIND_LIBRARIES_SSL};${OpenSSL_FIND_LIBRARIES_CRYPTO}" CACHE STRING "OpenSSL libraries") - else () - # look for libraries built with MSVC - FIND_LIBRARY_WITH_DEBUG(OpenSSL_FIND_LIBRARIES_SSL WIN32_DEBUG_POSTFIX d NAMES ssl ssleay ssleay32 libssleay32 ssleay32MD) - FIND_LIBRARY_WITH_DEBUG(OpenSSL_FIND_LIBRARIES_EAY WIN32_DEBUG_POSTFIX d NAMES eay libeay libeay32 libeay32MD) - - if (OpenSSL_FIND_LIBRARIES_SSL AND OpenSSL_FIND_LIBRARIES_EAY) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_LIBRARY_DIRS "" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_FIND_LIBRARIES_SSL};${OpenSSL_FIND_LIBRARIES_EAY}" CACHE STRING "OpenSSL libraries") - endif () - endif () - - if (OpenSSL_FOUND) - set(OpenSSL_INCLUDE_DIRS "${OpenSSL_FIND_INCLUDE_DIR}" CACHE STRING "OpenSSL include dirs") - endif () - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(OpenSSL_PC openssl) - - if (OpenSSL_PC_FOUND) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_INCLUDE_DIRS "${OpenSSL_PC_INCLUDE_DIRS}" CACHE STRING "OpenSSL include dirs") - set(OpenSSL_LIBRARY_DIRS "${OpenSSL_PC_LIBRARY_DIRS}" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_PC_LIBRARIES}" CACHE STRING "OpenSSL libraries") - endif () -endif () - -if (OpenSSL_FOUND) - if (NOT OpenSSL_FIND_QUIETLY) - MESSAGE(STATUS "Found OpenSSL: ${OpenSSL_INCLUDE_DIRS} ${OpenSSL_LIBRARY_DIRS} ${OpenSSL_LIBRARIES}") - endif () -else () - if (OpenSSL_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find OpenSSL") - endif () -endif () - -mark_as_advanced(OpenSSL_INCLUDE_DIRS OpenSSL_LIBRARY_DIRS OpenSSL_LIBRARIES) diff --git a/external/badvpn_dns/compile-tun2sock.sh b/external/badvpn_dns/compile-tun2sock.sh deleted file mode 100755 index fbc2388..0000000 --- a/external/badvpn_dns/compile-tun2sock.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -# -# Compiles tun2socks for Linux. -# Intended as a convenience if you don't want to deal with CMake. - -# Input environment vars: -# SRCDIR - BadVPN source code -# CC - compiler -# CFLAGS - compiler compile flags -# LDFLAGS - compiler link flags -# ENDIAN - "little" or "big" -# KERNEL - "2.6" or "2.4", default "2.6" -# -# Puts object files and the executable in the working directory. -# - -if [[ -z $SRCDIR ]] || [[ ! -e $SRCDIR/CMakeLists.txt ]]; then - echo "SRCDIR is wrong" - exit 1 -fi - -if ! "${CC}" --version &>/dev/null; then - echo "CC is wrong" - exit 1 -fi - -if [[ $ENDIAN != "little" ]] && [[ $ENDIAN != "big" ]]; then - echo "ENDIAN is wrong" - exit 1 -fi - -if [[ -z $KERNEL ]]; then - KERNEL="2.6" -elif [[ $KERNEL != "2.6" ]] && [[ $KERNEL != "2.4" ]]; then - echo "KERNEL is wrong" - exit 1 -fi - -CFLAGS="${CFLAGS} -std=gnu99" -INCLUDES=( "-I${SRCDIR}" "-I${SRCDIR}/lwip/src/include/ipv4" "-I${SRCDIR}/lwip/src/include/ipv6" "-I${SRCDIR}/lwip/src/include" "-I${SRCDIR}/lwip/custom" ) -DEFS=( -DBADVPN_THREAD_SAFE=0 -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE ) - -[[ $KERNEL = "2.4" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_USE_SELFPIPE -DBADVPN_USE_POLL ) || DEFS=( "${DEFS[@]}" -DBADVPN_USE_SIGNALFD -DBADVPN_USE_EPOLL ) - -[[ $ENDIAN = "little" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_LITTLE_ENDIAN ) || DEFS=( "${DEFS[@]}" -DBADVPN_BIG_ENDIAN ) - -SOURCES=" -base/BLog_syslog.c -system/BReactor_badvpn.c -system/BSignal.c -system/BConnection_unix.c -system/BTime.c -system/BUnixSignal.c -system/BNetwork.c -flow/StreamRecvInterface.c -flow/PacketRecvInterface.c -flow/PacketPassInterface.c -flow/StreamPassInterface.c -flow/SinglePacketBuffer.c -flow/BufferWriter.c -flow/PacketBuffer.c -flow/PacketStreamSender.c -flow/PacketPassConnector.c -flow/PacketProtoFlow.c -flow/PacketPassFairQueue.c -flow/PacketProtoEncoder.c -flow/PacketProtoDecoder.c -socksclient/BSocksClient.c -tuntap/BTap.c -lwip/src/core/timers.c -lwip/src/core/udp.c -lwip/src/core/memp.c -lwip/src/core/init.c -lwip/src/core/pbuf.c -lwip/src/core/tcp.c -lwip/src/core/tcp_out.c -lwip/src/core/netif.c -lwip/src/core/def.c -lwip/src/core/mem.c -lwip/src/core/tcp_in.c -lwip/src/core/stats.c -lwip/src/core/inet_chksum.c -lwip/src/core/ipv4/icmp.c -lwip/src/core/ipv4/ip4.c -lwip/src/core/ipv4/ip4_addr.c -lwip/src/core/ipv4/ip_frag.c -lwip/src/core/ipv6/ip6.c -lwip/src/core/ipv6/nd6.c -lwip/src/core/ipv6/icmp6.c -lwip/src/core/ipv6/ip6_addr.c -lwip/src/core/ipv6/ip6_frag.c -lwip/custom/sys.c -tun2socks/tun2socks.c -base/DebugObject.c -base/BLog.c -base/BPending.c -flowextra/PacketPassInactivityMonitor.c -tun2socks/SocksUdpGwClient.c -udpgw_client/UdpGwClient.c -" - -set -e -set -x - -OBJS=() -for f in $SOURCES; do - obj=$(basename "${f}").o - "${CC}" -c ${CFLAGS} "${INCLUDES[@]}" "${DEFS[@]}" "${SRCDIR}/${f}" -o "${obj}" - OBJS=( "${OBJS[@]}" "${obj}" ) -done - -"${CC}" ${LDFLAGS} "${OBJS[@]}" -o tun2socks -lrt diff --git a/external/badvpn_dns/compile-udpgw.sh b/external/badvpn_dns/compile-udpgw.sh deleted file mode 100755 index 5f132f9..0000000 --- a/external/badvpn_dns/compile-udpgw.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash -# -# Compiles udpgw for Linux. -# Intended as a convenience if you don't want to deal with CMake. - -# Input environment vars: -# SRCDIR - BadVPN source code -# CC - compiler -# CFLAGS - compiler compile flags -# LDFLAGS - compiler link flags -# ENDIAN - "little" or "big" -# KERNEL - "2.6" or "2.4", default "2.6" -# -# Puts object files and the executable in the working directory. -# - -if [[ -z $SRCDIR ]] || [[ ! -e $SRCDIR/CMakeLists.txt ]]; then - echo "SRCDIR is wrong" - exit 1 -fi - -if ! "${CC}" --version &>/dev/null; then - echo "CC is wrong" - exit 1 -fi - -if [[ $ENDIAN != "little" ]] && [[ $ENDIAN != "big" ]]; then - echo "ENDIAN is wrong" - exit 1 -fi - -if [[ -z $KERNEL ]]; then - KERNEL="2.6" -elif [[ $KERNEL != "2.6" ]] && [[ $KERNEL != "2.4" ]]; then - echo "KERNEL is wrong" - exit 1 -fi - -CFLAGS="${CFLAGS} -std=gnu99" -INCLUDES=( "-I${SRCDIR}" ) -DEFS=( -DBADVPN_THREAD_SAFE=0 -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE ) - -[[ $KERNEL = "2.4" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_USE_SELFPIPE -DBADVPN_USE_POLL ) || DEFS=( "${DEFS[@]}" -DBADVPN_USE_SIGNALFD -DBADVPN_USE_EPOLL ) - -[[ $ENDIAN = "little" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_LITTLE_ENDIAN ) || DEFS=( "${DEFS[@]}" -DBADVPN_BIG_ENDIAN ) - -SOURCES=" -base/BLog_syslog.c -system/BReactor_badvpn.c -system/BSignal.c -system/BConnection_unix.c -system/BDatagram_unix.c -system/BTime.c -system/BUnixSignal.c -system/BNetwork.c -flow/StreamRecvInterface.c -flow/PacketRecvInterface.c -flow/PacketPassInterface.c -flow/StreamPassInterface.c -flow/SinglePacketBuffer.c -flow/BufferWriter.c -flow/PacketBuffer.c -flow/PacketStreamSender.c -flow/PacketProtoFlow.c -flow/PacketPassFairQueue.c -flow/PacketProtoEncoder.c -flow/PacketProtoDecoder.c -base/DebugObject.c -base/BLog.c -base/BPending.c -udpgw/udpgw.c -" - -set -e -set -x - -OBJS=() -for f in $SOURCES; do - obj=$(basename "${f}").o - "${CC}" -c ${CFLAGS} "${INCLUDES[@]}" "${DEFS[@]}" "${SRCDIR}/${f}" -o "${obj}" - OBJS=( "${OBJS[@]}" "${obj}" ) -done - -"${CC}" ${LDFLAGS} "${OBJS[@]}" -o udpgw -lrt diff --git a/external/badvpn_dns/dhcpclient/BDHCPClient.c b/external/badvpn_dns/dhcpclient/BDHCPClient.c deleted file mode 100644 index 70ee6ad..0000000 --- a/external/badvpn_dns/dhcpclient/BDHCPClient.c +++ /dev/null @@ -1,340 +0,0 @@ -/** - * @file BDHCPClient.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <sys/ioctl.h> -#include <linux/filter.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/ethernet_proto.h> -#include <misc/ipv4_proto.h> -#include <misc/udp_proto.h> -#include <misc/dhcp_proto.h> -#include <misc/get_iface_info.h> -#include <base/BLog.h> - -#include <dhcpclient/BDHCPClient.h> - -#include <generated/blog_channel_BDHCPClient.h> - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_OVERHEAD (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static const struct sock_filter dhcp_sock_filter[] = { - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9), // A <- IP protocol - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPV4_PROTOCOL_UDP, 0, 3), // IP protocol = UDP ? - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 22), // A <- UDP destination port - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1), // UDP destination port = DHCP client ? - BPF_STMT(BPF_RET + BPF_K, 65535), // return all - BPF_STMT(BPF_RET + BPF_K, 0) // ignore -}; - -static void dgram_handler (BDHCPClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - - BLog(BLOG_ERROR, "packet socket error"); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BDHCPCLIENT_EVENT_ERROR)); - return; -} - -static void dhcp_handler (BDHCPClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - - switch (event) { - case BDHCPCLIENTCORE_EVENT_UP: - ASSERT(!o->up) - o->up = 1; - o->handler(o->user, BDHCPCLIENT_EVENT_UP); - return; - - case BDHCPCLIENTCORE_EVENT_DOWN: - ASSERT(o->up) - o->up = 0; - o->handler(o->user, BDHCPCLIENT_EVENT_DOWN); - return; - - default: - ASSERT(0); - } -} - -static void dhcp_func_getsendermac (BDHCPClient *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - - BAddr remote_addr; - BIPAddr local_addr; - if (!BDatagram_GetLastReceiveAddrs(&o->dgram, &remote_addr, &local_addr)) { - BLog(BLOG_ERROR, "BDatagram_GetLastReceiveAddrs failed"); - goto fail; - } - - if (remote_addr.type != BADDR_TYPE_PACKET) { - BLog(BLOG_ERROR, "address type invalid"); - goto fail; - } - - if (remote_addr.packet.header_type != BADDR_PACKET_HEADER_TYPE_ETHERNET) { - BLog(BLOG_ERROR, "address header type invalid"); - goto fail; - } - - memcpy(out_mac, remote_addr.packet.phys_addr, 6); - return; - -fail: - memset(out_mac, 0, 6); -} - -int BDHCPClient_Init (BDHCPClient *o, const char *ifname, struct BDHCPClient_opts opts, BReactor *reactor, BRandom2 *random2, BDHCPClient_handler handler, void *user) -{ - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // get interface information - uint8_t if_mac[6]; - int if_mtu; - int if_index; - if (!badvpn_get_iface_info(ifname, if_mac, &if_mtu, &if_index)) { - BLog(BLOG_ERROR, "failed to get interface information"); - goto fail0; - } - - BLog(BLOG_INFO, "if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d", - if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index); - - if (if_mtu < IPUDP_OVERHEAD) { - BLog(BLOG_ERROR, "MTU is too small for UDP/IP !?!"); - goto fail0; - } - - int dhcp_mtu = if_mtu - IPUDP_OVERHEAD; - - // init dgram - if (!BDatagram_Init(&o->dgram, BADDR_TYPE_PACKET, o->reactor, o, (BDatagram_handler)dgram_handler)) { - BLog(BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // set socket filter - { - struct sock_filter filter[sizeof(dhcp_sock_filter) / sizeof(dhcp_sock_filter[0])]; - memcpy(filter, dhcp_sock_filter, sizeof(filter)); - struct sock_fprog fprog = { - .len = sizeof(filter) / sizeof(filter[0]), - .filter = filter - }; - if (setsockopt(BDatagram_GetFd(&o->dgram), SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) { - BLog(BLOG_NOTICE, "not using socket filter"); - } - } - - // bind dgram - BAddr bind_addr; - BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac); - if (!BDatagram_Bind(&o->dgram, bind_addr)) { - BLog(BLOG_ERROR, "BDatagram_Bind failed"); - goto fail1; - } - - // set dgram send addresses - BAddr dest_addr; - uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BAddr_InitPacket(&dest_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_BROADCAST, broadcast_mac); - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, dest_addr, local_addr); - - // init dgram interfaces - BDatagram_SendAsync_Init(&o->dgram, if_mtu); - BDatagram_RecvAsync_Init(&o->dgram, if_mtu); - - // init sending - - // init copier - PacketCopier_Init(&o->send_copier, dhcp_mtu, BReactor_PendingGroup(o->reactor)); - - // init encoder - DHCPIpUdpEncoder_Init(&o->send_encoder, PacketCopier_GetOutput(&o->send_copier), BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->send_buffer, DHCPIpUdpEncoder_GetOutput(&o->send_encoder), BDatagram_SendAsync_GetIf(&o->dgram), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init receiving - - // init copier - PacketCopier_Init(&o->recv_copier, dhcp_mtu, BReactor_PendingGroup(o->reactor)); - - // init decoder - DHCPIpUdpDecoder_Init(&o->recv_decoder, PacketCopier_GetInput(&o->recv_copier), BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->recv_buffer, BDatagram_RecvAsync_GetIf(&o->dgram), DHCPIpUdpDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail3; - } - - // init options - struct BDHCPClientCore_opts core_opts; - core_opts.hostname = opts.hostname; - core_opts.vendorclassid = opts.vendorclassid; - core_opts.clientid = opts.clientid; - core_opts.clientid_len = opts.clientid_len; - - // auto-generate clientid from MAC if requested - uint8_t mac_cid[7]; - if (opts.auto_clientid) { - mac_cid[0] = DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET; - memcpy(mac_cid + 1, if_mac, 6); - core_opts.clientid = mac_cid; - core_opts.clientid_len = sizeof(mac_cid); - } - - // init dhcp - if (!BDHCPClientCore_Init(&o->dhcp, PacketCopier_GetInput(&o->send_copier), PacketCopier_GetOutput(&o->recv_copier), if_mac, core_opts, o->reactor, random2, o, - (BDHCPClientCore_func_getsendermac)dhcp_func_getsendermac, - (BDHCPClientCore_handler)dhcp_handler - )) { - BLog(BLOG_ERROR, "BDHCPClientCore_Init failed"); - goto fail4; - } - - // set not up - o->up = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail4: - SinglePacketBuffer_Free(&o->recv_buffer); -fail3: - DHCPIpUdpDecoder_Free(&o->recv_decoder); - PacketCopier_Free(&o->recv_copier); - SinglePacketBuffer_Free(&o->send_buffer); -fail2: - DHCPIpUdpEncoder_Free(&o->send_encoder); - PacketCopier_Free(&o->send_copier); - BDatagram_RecvAsync_Free(&o->dgram); - BDatagram_SendAsync_Free(&o->dgram); -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void BDHCPClient_Free (BDHCPClient *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free dhcp - BDHCPClientCore_Free(&o->dhcp); - - // free receiving - SinglePacketBuffer_Free(&o->recv_buffer); - DHCPIpUdpDecoder_Free(&o->recv_decoder); - PacketCopier_Free(&o->recv_copier); - - // free sending - SinglePacketBuffer_Free(&o->send_buffer); - DHCPIpUdpEncoder_Free(&o->send_encoder); - PacketCopier_Free(&o->send_copier); - - // free dgram interfaces - BDatagram_RecvAsync_Free(&o->dgram); - BDatagram_SendAsync_Free(&o->dgram); - - // free dgram - BDatagram_Free(&o->dgram); -} - -int BDHCPClient_IsUp (BDHCPClient *o) -{ - DebugObject_Access(&o->d_obj); - - return o->up; -} - -void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetClientIP(&o->dhcp, out_ip); -} - -void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetClientMask(&o->dhcp, out_mask); -} - -int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return BDHCPClientCore_GetRouter(&o->dhcp, out_router); -} - -int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return BDHCPClientCore_GetDNS(&o->dhcp, out_dns_servers, max_dns_servers); -} - -void BDHCPClient_GetServerMAC (BDHCPClient *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetServerMAC(&o->dhcp, out_mac); -} diff --git a/external/badvpn_dns/dhcpclient/BDHCPClient.h b/external/badvpn_dns/dhcpclient/BDHCPClient.h deleted file mode 100644 index c0da0c4..0000000 --- a/external/badvpn_dns/dhcpclient/BDHCPClient.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file BDHCPClient.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DHCP client. - */ - -#ifndef BADVPN_DHCPCLIENT_BDHCPCLIENT_H -#define BADVPN_DHCPCLIENT_BDHCPCLIENT_H - -#include <base/DebugObject.h> -#include <system/BDatagram.h> -#include <flow/PacketCopier.h> -#include <flow/SinglePacketBuffer.h> -#include <dhcpclient/BDHCPClientCore.h> -#include <dhcpclient/DHCPIpUdpDecoder.h> -#include <dhcpclient/DHCPIpUdpEncoder.h> - -#define BDHCPCLIENT_EVENT_UP 1 -#define BDHCPCLIENT_EVENT_DOWN 2 -#define BDHCPCLIENT_EVENT_ERROR 3 - -#define BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS - -typedef void (*BDHCPClient_handler) (void *user, int event); - -typedef struct { - BReactor *reactor; - BDatagram dgram; - BDHCPClient_handler handler; - void *user; - PacketCopier send_copier; - DHCPIpUdpEncoder send_encoder; - SinglePacketBuffer send_buffer; - SinglePacketBuffer recv_buffer; - DHCPIpUdpDecoder recv_decoder; - PacketCopier recv_copier; - BDHCPClientCore dhcp; - int up; - DebugError d_err; - DebugObject d_obj; -} BDHCPClient; - -struct BDHCPClient_opts { - const char *hostname; - const char *vendorclassid; - const uint8_t *clientid; - size_t clientid_len; - int auto_clientid; -}; - -int BDHCPClient_Init (BDHCPClient *o, const char *ifname, struct BDHCPClient_opts opts, BReactor *reactor, BRandom2 *random2, BDHCPClient_handler handler, void *user); -void BDHCPClient_Free (BDHCPClient *o); -int BDHCPClient_IsUp (BDHCPClient *o); -void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip); -void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask); -int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router); -int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers); -void BDHCPClient_GetServerMAC (BDHCPClient *o, uint8_t *out_mac); - -#endif diff --git a/external/badvpn_dns/dhcpclient/BDHCPClientCore.c b/external/badvpn_dns/dhcpclient/BDHCPClientCore.c deleted file mode 100644 index 5a605e4..0000000 --- a/external/badvpn_dns/dhcpclient/BDHCPClientCore.c +++ /dev/null @@ -1,860 +0,0 @@ -/** - * @file BDHCPClientCore.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdlib.h> - -#include <misc/byteorder.h> -#include <misc/minmax.h> -#include <misc/balloc.h> -#include <misc/bsize.h> -#include <misc/dhcp_proto.h> -#include <base/BLog.h> - -#include <dhcpclient/BDHCPClientCore.h> - -#include <generated/blog_channel_BDHCPClientCore.h> - -#define RESET_TIMEOUT 4000 -#define REQUEST_TIMEOUT 3000 -#define RENEW_REQUEST_TIMEOUT 20000 -#define MAX_REQUESTS 4 -#define RENEW_TIMEOUT(lease) ((btime_t)500 * (lease)) -#define XID_REUSE_MAX 8 - -#define LEASE_TIMEOUT(lease) ((btime_t)1000 * (lease) - RENEW_TIMEOUT(lease)) - -#define STATE_RESETTING 1 -#define STATE_SENT_DISCOVER 2 -#define STATE_SENT_REQUEST 3 -#define STATE_FINISHED 4 -#define STATE_RENEWING 5 - -#define IP_UDP_HEADERS_SIZE 28 - -static void report_up (BDHCPClientCore *o) -{ - o->handler(o->user, BDHCPCLIENTCORE_EVENT_UP); - return; -} - -static void report_down (BDHCPClientCore *o) -{ - o->handler(o->user, BDHCPCLIENTCORE_EVENT_DOWN); - return; -} - -static void send_message ( - BDHCPClientCore *o, - int type, - uint32_t xid, - int have_requested_ip_address, uint32_t requested_ip_address, - int have_dhcp_server_identifier, uint32_t dhcp_server_identifier -) -{ - ASSERT(type == DHCP_MESSAGE_TYPE_DISCOVER || type == DHCP_MESSAGE_TYPE_REQUEST) - - if (o->sending) { - BLog(BLOG_ERROR, "already sending"); - return; - } - - // write header - struct dhcp_header header; - memset(&header, 0, sizeof(header)); - header.op = hton8(DHCP_OP_BOOTREQUEST); - header.htype = hton8(DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET); - header.hlen = hton8(6); - header.xid = xid; - header.secs = hton16(0); - memcpy(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr)); - header.magic = hton32(DHCP_MAGIC); - memcpy(o->send_buf, &header, sizeof(header)); - - // write options - - char *out = o->send_buf + sizeof(header); - struct dhcp_option_header oh; - - // DHCP message type - { - oh.type = hton8(DHCP_OPTION_DHCP_MESSAGE_TYPE); - oh.len = hton8(sizeof(struct dhcp_option_dhcp_message_type)); - struct dhcp_option_dhcp_message_type opt; - opt.type = hton8(type); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (have_requested_ip_address) { - // requested IP address - oh.type = hton8(DHCP_OPTION_REQUESTED_IP_ADDRESS); - oh.len = hton8(sizeof(struct dhcp_option_addr)); - struct dhcp_option_addr opt; - opt.addr = requested_ip_address; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (have_dhcp_server_identifier) { - // DHCP server identifier - oh.type = hton8(DHCP_OPTION_DHCP_SERVER_IDENTIFIER); - oh.len = hton8(sizeof(struct dhcp_option_dhcp_server_identifier)); - struct dhcp_option_dhcp_server_identifier opt; - opt.id = dhcp_server_identifier; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - // maximum message size - { - oh.type = hton8(DHCP_OPTION_MAXIMUM_MESSAGE_SIZE); - oh.len = hton8(sizeof(struct dhcp_option_maximum_message_size)); - struct dhcp_option_maximum_message_size opt; - opt.size = hton16(IP_UDP_HEADERS_SIZE + PacketRecvInterface_GetMTU(o->recv_if)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - // parameter request list - { - oh.type = hton8(DHCP_OPTION_PARAMETER_REQUEST_LIST); - oh.len = hton8(4); - uint8_t opt[4]; - opt[0] = DHCP_OPTION_SUBNET_MASK; - opt[1] = DHCP_OPTION_ROUTER; - opt[2] = DHCP_OPTION_DOMAIN_NAME_SERVER; - opt[3] = DHCP_OPTION_IP_ADDRESS_LEASE_TIME; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (o->hostname) { - // host name - oh.type = hton8(DHCP_OPTION_HOST_NAME); - oh.len = hton8(strlen(o->hostname)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->hostname, strlen(o->hostname)); - out += sizeof(oh) + strlen(o->hostname); - } - - if (o->vendorclassid) { - // vendor class identifier - oh.type = hton8(DHCP_OPTION_VENDOR_CLASS_IDENTIFIER); - oh.len = hton8(strlen(o->vendorclassid)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->vendorclassid, strlen(o->vendorclassid)); - out += sizeof(oh) + strlen(o->vendorclassid); - } - - if (o->clientid) { - // client identifier - oh.type = hton8(DHCP_OPTION_CLIENT_IDENTIFIER); - oh.len = hton8(o->clientid_len); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->clientid, o->clientid_len); - out += sizeof(oh) + o->clientid_len; - } - - // end option - uint8_t end = 0xFF; - memcpy(out, &end, sizeof(end)); - out += sizeof(end); - - // send it - PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)o->send_buf, out - o->send_buf); - o->sending = 1; -} - -static void send_handler_done (BDHCPClientCore *o) -{ - ASSERT(o->sending) - DebugObject_Access(&o->d_obj); - - o->sending = 0; -} - -static void recv_handler_done (BDHCPClientCore *o, int data_len) -{ - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - // receive more packets - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)o->recv_buf); - - if (o->state == STATE_RESETTING) { - return; - } - - // check header - - if (data_len < sizeof(struct dhcp_header)) { - return; - } - - struct dhcp_header header; - memcpy(&header, o->recv_buf, sizeof(header)); - - if (ntoh8(header.op) != DHCP_OP_BOOTREPLY) { - return; - } - - if (ntoh8(header.htype) != DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET) { - return; - } - - if (ntoh8(header.hlen) != 6) { - return; - } - - if (header.xid != o->xid) { - return; - } - - if (memcmp(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr))) { - return; - } - - if (ntoh32(header.magic) != DHCP_MAGIC) { - return; - } - - // parse and check options - - uint8_t *pos = (uint8_t *)o->recv_buf + sizeof(header); - int len = data_len - sizeof(header); - - int have_end = 0; - - int dhcp_message_type = -1; - - int have_dhcp_server_identifier = 0; - uint32_t dhcp_server_identifier = 0; // to remove warning - - int have_ip_address_lease_time = 0; - uint32_t ip_address_lease_time = 0; // to remove warning - - int have_subnet_mask = 0; - uint32_t subnet_mask = 0; // to remove warning - - int have_router = 0; - uint32_t router = 0; // to remove warning - - int domain_name_servers_count = 0; - uint32_t domain_name_servers[BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS]; - - while (len > 0) { - // padding option ? - if (*pos == 0) { - pos++; - len--; - continue; - } - - if (have_end) { - return; - } - - // end option ? - if (*pos == 0xff) { - pos++; - len--; - have_end = 1; - continue; - } - - // check option header - if (len < sizeof(struct dhcp_option_header)) { - return; - } - struct dhcp_option_header opt; - memcpy(&opt, pos, sizeof(opt)); - pos += sizeof(opt); - len -= sizeof(opt); - int opt_type = ntoh8(opt.type); - int opt_len = ntoh8(opt.len); - - // check option payload - if (opt_len > len) { - return; - } - uint8_t *optval = pos; - pos += opt_len; - len -= opt_len; - - switch (opt_type) { - case DHCP_OPTION_DHCP_MESSAGE_TYPE: { - if (opt_len != sizeof(struct dhcp_option_dhcp_message_type)) { - return; - } - struct dhcp_option_dhcp_message_type val; - memcpy(&val, optval, sizeof(val)); - - dhcp_message_type = ntoh8(val.type); - } break; - - case DHCP_OPTION_DHCP_SERVER_IDENTIFIER: { - if (opt_len != sizeof(struct dhcp_option_dhcp_server_identifier)) { - return; - } - struct dhcp_option_dhcp_server_identifier val; - memcpy(&val, optval, sizeof(val)); - - dhcp_server_identifier = val.id; - have_dhcp_server_identifier = 1; - } break; - - case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: { - if (opt_len != sizeof(struct dhcp_option_time)) { - return; - } - struct dhcp_option_time val; - memcpy(&val, optval, sizeof(val)); - - ip_address_lease_time = ntoh32(val.time); - have_ip_address_lease_time = 1; - } break; - - case DHCP_OPTION_SUBNET_MASK: { - if (opt_len != sizeof(struct dhcp_option_addr)) { - return; - } - struct dhcp_option_addr val; - memcpy(&val, optval, sizeof(val)); - - subnet_mask = val.addr; - have_subnet_mask = 1; - } break; - - case DHCP_OPTION_ROUTER: { - if (opt_len != sizeof(struct dhcp_option_addr)) { - return; - } - struct dhcp_option_addr val; - memcpy(&val, optval, sizeof(val)); - - router = val.addr; - have_router = 1; - } break; - - case DHCP_OPTION_DOMAIN_NAME_SERVER: { - if (opt_len % sizeof(struct dhcp_option_addr)) { - return; - } - - int num_servers = opt_len / sizeof(struct dhcp_option_addr); - - int i; - for (i = 0; i < num_servers && i < BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS; i++) { - struct dhcp_option_addr addr; - memcpy(&addr, optval + i * sizeof(addr), sizeof(addr)); - domain_name_servers[i] = addr.addr; - } - - domain_name_servers_count = i; - } break; - } - } - - if (!have_end) { - return; - } - - if (dhcp_message_type == -1) { - return; - } - - if (dhcp_message_type != DHCP_MESSAGE_TYPE_OFFER && dhcp_message_type != DHCP_MESSAGE_TYPE_ACK && dhcp_message_type != DHCP_MESSAGE_TYPE_NAK) { - return; - } - - if (!have_dhcp_server_identifier) { - return; - } - - if (dhcp_message_type == DHCP_MESSAGE_TYPE_NAK) { - if (o->state != STATE_SENT_REQUEST && o->state != STATE_FINISHED && o->state != STATE_RENEWING) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - if (o->state == STATE_SENT_REQUEST) { - BLog(BLOG_INFO, "received NAK (in sent request)"); - - // stop request timer - BReactor_RemoveTimer(o->reactor, &o->request_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - } - else if (o->state == STATE_FINISHED) { - BLog(BLOG_INFO, "received NAK (in finished)"); - - // stop renew timer - BReactor_RemoveTimer(o->reactor, &o->renew_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - - // report to user - report_down(o); - return; - } - else { // STATE_RENEWING - BLog(BLOG_INFO, "received NAK (in renewing)"); - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // stop lease timer - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - - // report to user - report_down(o); - return; - } - - return; - } - - if (ntoh32(header.yiaddr) == 0) { - return; - } - - if (!have_ip_address_lease_time) { - return; - } - - if (!have_subnet_mask) { - return; - } - - if (o->state == STATE_SENT_DISCOVER && dhcp_message_type == DHCP_MESSAGE_TYPE_OFFER) { - BLog(BLOG_INFO, "received OFFER"); - - // remember offer - o->offered.yiaddr = header.yiaddr; - o->offered.dhcp_server_identifier = dhcp_server_identifier; - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 1, o->offered.dhcp_server_identifier); - - // stop reset timer - BReactor_RemoveTimer(o->reactor, &o->reset_timer); - - // start request timer - BReactor_SetTimer(o->reactor, &o->request_timer); - - // set state - o->state = STATE_SENT_REQUEST; - - // set request count - o->request_count = 1; - } - else if (o->state == STATE_SENT_REQUEST && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) { - if (header.yiaddr != o->offered.yiaddr) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - BLog(BLOG_INFO, "received ACK (in sent request)"); - - // remember stuff - o->acked.ip_address_lease_time = ip_address_lease_time; - o->acked.subnet_mask = subnet_mask; - o->acked.have_router = have_router; - if (have_router) { - o->acked.router = router; - } - o->acked.domain_name_servers_count = domain_name_servers_count; - memcpy(o->acked.domain_name_servers, domain_name_servers, domain_name_servers_count * sizeof(uint32_t)); - o->func_getsendermac(o->user, o->acked.server_mac); - - // stop request timer - BReactor_RemoveTimer(o->reactor, &o->request_timer); - - // start renew timer - BReactor_SetTimerAfter(o->reactor, &o->renew_timer, RENEW_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_FINISHED; - - // report to user - report_up(o); - return; - } - else if (o->state == STATE_RENEWING && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) { - if (header.yiaddr != o->offered.yiaddr) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - // TODO: check parameters? - - BLog(BLOG_INFO, "received ACK (in renewing)"); - - // remember stuff - o->acked.ip_address_lease_time = ip_address_lease_time; - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // stop lease timer - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - - // start renew timer - BReactor_SetTimerAfter(o->reactor, &o->renew_timer, RENEW_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_FINISHED; - } -} - -static void start_process (BDHCPClientCore *o, int force_new_xid) -{ - if (force_new_xid || o->xid_reuse_counter == XID_REUSE_MAX) { - // generate xid - if (!BRandom2_GenBytes(o->random2, &o->xid, sizeof(o->xid))) { - BLog(BLOG_ERROR, "BRandom2_GenBytes failed"); - o->xid = UINT32_C(3416960072); - } - - // reset counter - o->xid_reuse_counter = 0; - } - - // increment counter - o->xid_reuse_counter++; - - // send discover - send_message(o, DHCP_MESSAGE_TYPE_DISCOVER, o->xid, 0, 0, 0, 0); - - // set timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_SENT_DISCOVER; -} - -static void reset_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RESETTING || o->state == STATE_SENT_DISCOVER) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "reset timer"); - - start_process(o, (o->state == STATE_RESETTING)); -} - -static void request_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_SENT_REQUEST) - ASSERT(o->request_count >= 1) - ASSERT(o->request_count <= MAX_REQUESTS) - DebugObject_Access(&o->d_obj); - - // if we have sent enough requests, start again - if (o->request_count == MAX_REQUESTS) { - BLog(BLOG_INFO, "request timer, aborting"); - - start_process(o, 0); - return; - } - - BLog(BLOG_INFO, "request timer, retrying"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 1, o->offered.dhcp_server_identifier); - - // start request timer - BReactor_SetTimer(o->reactor, &o->request_timer); - - // increment request count - o->request_count++; -} - -static void renew_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_FINISHED) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "renew timer"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 0, 0); - - // start renew request timer - BReactor_SetTimer(o->reactor, &o->renew_request_timer); - - // start lease timer - BReactor_SetTimerAfter(o->reactor, &o->lease_timer, LEASE_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_RENEWING; -} - -static void renew_request_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "renew request timer"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 0, 0); - - // start renew request timer - BReactor_SetTimer(o->reactor, &o->renew_request_timer); -} - -static void lease_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "lease timer"); - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // start again now - start_process(o, 1); - - // report to user - report_down(o); - return; -} - -static bsize_t maybe_len (const char *str) -{ - return bsize_fromsize(str ? strlen(str) : 0); -} - -int BDHCPClientCore_Init (BDHCPClientCore *o, PacketPassInterface *send_if, PacketRecvInterface *recv_if, - uint8_t *client_mac_addr, struct BDHCPClientCore_opts opts, BReactor *reactor, - BRandom2 *random2, void *user, - BDHCPClientCore_func_getsendermac func_getsendermac, - BDHCPClientCore_handler handler) -{ - ASSERT(PacketPassInterface_GetMTU(send_if) == PacketRecvInterface_GetMTU(recv_if)) - ASSERT(PacketPassInterface_GetMTU(send_if) >= 576 - IP_UDP_HEADERS_SIZE) - ASSERT(func_getsendermac) - ASSERT(handler) - - // init arguments - o->send_if = send_if; - o->recv_if = recv_if; - memcpy(o->client_mac_addr, client_mac_addr, sizeof(o->client_mac_addr)); - o->reactor = reactor; - o->random2 = random2; - o->user = user; - o->func_getsendermac = func_getsendermac; - o->handler = handler; - - o->hostname = NULL; - o->vendorclassid = NULL; - o->clientid = NULL; - o->clientid_len = 0; - - // copy options - if (opts.hostname && !(o->hostname = strdup(opts.hostname))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail0; - } - if (opts.vendorclassid && !(o->vendorclassid = strdup(opts.vendorclassid))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail0; - } - if (opts.clientid) { - if (!(o->clientid = BAlloc(opts.clientid_len))) { - BLog(BLOG_ERROR, "BAlloc failed"); - goto fail0; - } - memcpy(o->clientid, opts.clientid, opts.clientid_len); - o->clientid_len = opts.clientid_len; - } - - // make sure options aren't too long - bsize_t opts_size = bsize_add(maybe_len(o->hostname), bsize_add(maybe_len(o->vendorclassid), bsize_fromsize(o->clientid_len))); - if (opts_size.is_overflow || opts_size.value > 100) { - BLog(BLOG_ERROR, "options too long together"); - goto fail0; - } - if (o->hostname && strlen(o->hostname) > 255) { - BLog(BLOG_ERROR, "hostname too long"); - goto fail0; - } - if (o->vendorclassid && strlen(o->vendorclassid) > 255) { - BLog(BLOG_ERROR, "vendorclassid too long"); - goto fail0; - } - if (o->clientid && o->clientid_len > 255) { - BLog(BLOG_ERROR, "clientid too long"); - goto fail0; - } - - // allocate buffers - if (!(o->send_buf = BAlloc(PacketPassInterface_GetMTU(send_if)))) { - BLog(BLOG_ERROR, "BAlloc send buf failed"); - goto fail0; - } - if (!(o->recv_buf = BAlloc(PacketRecvInterface_GetMTU(recv_if)))) { - BLog(BLOG_ERROR, "BAlloc recv buf failed"); - goto fail1; - } - - // init send interface - PacketPassInterface_Sender_Init(o->send_if, (PacketPassInterface_handler_done)send_handler_done, o); - - // init receive interface - PacketRecvInterface_Receiver_Init(o->recv_if, (PacketRecvInterface_handler_done)recv_handler_done, o); - - // set not sending - o->sending = 0; - - // init timers - BTimer_Init(&o->reset_timer, RESET_TIMEOUT, (BTimer_handler)reset_timer_handler, o); - BTimer_Init(&o->request_timer, REQUEST_TIMEOUT, (BTimer_handler)request_timer_handler, o); - BTimer_Init(&o->renew_timer, 0, (BTimer_handler)renew_timer_handler, o); - BTimer_Init(&o->renew_request_timer, RENEW_REQUEST_TIMEOUT, (BTimer_handler)renew_request_timer_handler, o); - BTimer_Init(&o->lease_timer, 0, (BTimer_handler)lease_timer_handler, o); - - // start receving - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)o->recv_buf); - - // start - start_process(o, 1); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - BFree(o->send_buf); -fail0: - BFree(o->clientid); - free(o->vendorclassid); - free(o->hostname); - return 0; -} - -void BDHCPClientCore_Free (BDHCPClientCore *o) -{ - DebugObject_Free(&o->d_obj); - - // free timers - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - BReactor_RemoveTimer(o->reactor, &o->renew_timer); - BReactor_RemoveTimer(o->reactor, &o->request_timer); - BReactor_RemoveTimer(o->reactor, &o->reset_timer); - - // free buffers - BFree(o->recv_buf); - BFree(o->send_buf); - - // free options - BFree(o->clientid); - free(o->vendorclassid); - free(o->hostname); -} - -void BDHCPClientCore_GetClientIP (BDHCPClientCore *o, uint32_t *out_ip) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - *out_ip = o->offered.yiaddr; -} - -void BDHCPClientCore_GetClientMask (BDHCPClientCore *o, uint32_t *out_mask) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - *out_mask = o->acked.subnet_mask; -} - -int BDHCPClientCore_GetRouter (BDHCPClientCore *o, uint32_t *out_router) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - if (!o->acked.have_router) { - return 0; - } - - *out_router = o->acked.router; - return 1; -} - -int BDHCPClientCore_GetDNS (BDHCPClientCore *o, uint32_t *out_dns_servers, size_t max_dns_servers) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - int num_return = bmin_int(o->acked.domain_name_servers_count, max_dns_servers); - - memcpy(out_dns_servers, o->acked.domain_name_servers, num_return * sizeof(uint32_t)); - return num_return; -} - -void BDHCPClientCore_GetServerMAC (BDHCPClientCore *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - - memcpy(out_mac, o->acked.server_mac, 6); -} diff --git a/external/badvpn_dns/dhcpclient/BDHCPClientCore.h b/external/badvpn_dns/dhcpclient/BDHCPClientCore.h deleted file mode 100644 index 98cda36..0000000 --- a/external/badvpn_dns/dhcpclient/BDHCPClientCore.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file BDHCPClientCore.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DHCP client, excluding system-dependent details. - */ - -#ifndef BADVPN_DHCPCLIENT_BDHCPCLIENTCORE_H -#define BADVPN_DHCPCLIENT_BDHCPCLIENTCORE_H - -#include <stdint.h> -#include <stddef.h> - -#include <system/BReactor.h> -#include <base/DebugObject.h> -#include <random/BRandom2.h> -#include <flow/PacketPassInterface.h> -#include <flow/PacketRecvInterface.h> - -#define BDHCPCLIENTCORE_EVENT_UP 1 -#define BDHCPCLIENTCORE_EVENT_DOWN 2 - -#define BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS 16 - -typedef void (*BDHCPClientCore_func_getsendermac) (void *user, uint8_t *out_mac); -typedef void (*BDHCPClientCore_handler) (void *user, int event); - -struct BDHCPClientCore_opts { - const char *hostname; - const char *vendorclassid; - const uint8_t *clientid; - size_t clientid_len; -}; - -typedef struct { - PacketPassInterface *send_if; - PacketRecvInterface *recv_if; - uint8_t client_mac_addr[6]; - BReactor *reactor; - BRandom2 *random2; - void *user; - BDHCPClientCore_func_getsendermac func_getsendermac; - BDHCPClientCore_handler handler; - char *hostname; - char *vendorclassid; - uint8_t *clientid; - size_t clientid_len; - char *send_buf; - char *recv_buf; - int sending; - BTimer reset_timer; - BTimer request_timer; - BTimer renew_timer; - BTimer renew_request_timer; - BTimer lease_timer; - int state; - int request_count; - uint32_t xid; - int xid_reuse_counter; - struct { - uint32_t yiaddr; - uint32_t dhcp_server_identifier; - } offered; - struct { - uint32_t ip_address_lease_time; - uint32_t subnet_mask; - int have_router; - uint32_t router; - int domain_name_servers_count; - uint32_t domain_name_servers[BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS]; - uint8_t server_mac[6]; - } acked; - DebugObject d_obj; -} BDHCPClientCore; - -int BDHCPClientCore_Init (BDHCPClientCore *o, PacketPassInterface *send_if, PacketRecvInterface *recv_if, - uint8_t *client_mac_addr, struct BDHCPClientCore_opts opts, BReactor *reactor, - BRandom2 *random2, void *user, - BDHCPClientCore_func_getsendermac func_getsendermac, - BDHCPClientCore_handler handler); -void BDHCPClientCore_Free (BDHCPClientCore *o); -void BDHCPClientCore_GetClientIP (BDHCPClientCore *o, uint32_t *out_ip); -void BDHCPClientCore_GetClientMask (BDHCPClientCore *o, uint32_t *out_mask); -int BDHCPClientCore_GetRouter (BDHCPClientCore *o, uint32_t *out_router); -int BDHCPClientCore_GetDNS (BDHCPClientCore *o, uint32_t *out_dns_servers, size_t max_dns_servers); -void BDHCPClientCore_GetServerMAC (BDHCPClientCore *o, uint8_t *out_mac); - -#endif diff --git a/external/badvpn_dns/dhcpclient/CMakeLists.txt b/external/badvpn_dns/dhcpclient/CMakeLists.txt deleted file mode 100644 index 5fd1300..0000000 --- a/external/badvpn_dns/dhcpclient/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -badvpn_add_library(dhcpclientcore "system;flow;flowextra;badvpn_random" "" BDHCPClientCore.c) - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(DHCPCLIENT_SOURCES - BDHCPClient.c - DHCPIpUdpEncoder.c - DHCPIpUdpDecoder.c - ) - badvpn_add_library(dhcpclient "system;flow;dhcpclientcore" "" "${DHCPCLIENT_SOURCES}") -endif () diff --git a/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.c b/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.c deleted file mode 100644 index 1d1c7a7..0000000 --- a/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file DHCPIpUdpDecoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <limits.h> -#include <string.h> - -#include <misc/ipv4_proto.h> -#include <misc/udp_proto.h> -#include <misc/byteorder.h> - -#include <dhcpclient/DHCPIpUdpDecoder.h> - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_HEADER_SIZE (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static void input_handler_send (DHCPIpUdpDecoder *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - struct ipv4_header iph; - uint8_t *pl; - int pl_len; - - if (!ipv4_check(data, data_len, &iph, &pl, &pl_len)) { - goto fail; - } - - if (ntoh8(iph.protocol) != IPV4_PROTOCOL_UDP) { - goto fail; - } - - if (pl_len < sizeof(struct udp_header)) { - goto fail; - } - struct udp_header udph; - memcpy(&udph, pl, sizeof(udph)); - - if (ntoh16(udph.source_port) != DHCP_SERVER_PORT) { - goto fail; - } - - if (ntoh16(udph.dest_port) != DHCP_CLIENT_PORT) { - goto fail; - } - - int udph_length = ntoh16(udph.length); - if (udph_length < sizeof(udph)) { - goto fail; - } - if (udph_length > data_len - (pl - data)) { - goto fail; - } - - if (ntoh16(udph.checksum) != 0) { - uint16_t checksum_in_packet = udph.checksum; - udph.checksum = 0; - uint16_t checksum_computed = udp_checksum(&udph, pl + sizeof(udph), udph_length - sizeof(udph), iph.source_address, iph.destination_address); - if (checksum_in_packet != checksum_computed) { - goto fail; - } - } - - // pass payload to output - PacketPassInterface_Sender_Send(o->output, pl + sizeof(udph), udph_length - sizeof(udph)); - - return; - -fail: - PacketPassInterface_Done(&o->input); -} - -static void output_handler_done (DHCPIpUdpDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Done(&o->input); -} - -void DHCPIpUdpDecoder_Init (DHCPIpUdpDecoder *o, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) <= INT_MAX - IPUDP_HEADER_SIZE) - - // init arguments - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init input - PacketPassInterface_Init(&o->input, IPUDP_HEADER_SIZE + PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DHCPIpUdpDecoder_Free (DHCPIpUdpDecoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * DHCPIpUdpDecoder_GetInput (DHCPIpUdpDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.h b/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.h deleted file mode 100644 index ce92138..0000000 --- a/external/badvpn_dns/dhcpclient/DHCPIpUdpDecoder.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file DHCPIpUdpDecoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_DHCPCLIENT_DHCPIPUDPDECODER_H -#define BADVPN_DHCPCLIENT_DHCPIPUDPDECODER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -typedef struct { - PacketPassInterface *output; - PacketPassInterface input; - uint8_t *data; - DebugObject d_obj; -} DHCPIpUdpDecoder; - -void DHCPIpUdpDecoder_Init (DHCPIpUdpDecoder *o, PacketPassInterface *output, BPendingGroup *pg); -void DHCPIpUdpDecoder_Free (DHCPIpUdpDecoder *o); -PacketPassInterface * DHCPIpUdpDecoder_GetInput (DHCPIpUdpDecoder *o); - -#endif diff --git a/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.c b/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.c deleted file mode 100644 index da6645c..0000000 --- a/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file DHCPIpUdpEncoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <limits.h> -#include <string.h> -#include <stddef.h> - -#include <misc/ipv4_proto.h> -#include <misc/udp_proto.h> -#include <misc/byteorder.h> - -#include <dhcpclient/DHCPIpUdpEncoder.h> - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_HEADER_SIZE (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static void output_handler_recv (DHCPIpUdpEncoder *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - // remember output packet - o->data = data; - - // receive payload - PacketRecvInterface_Receiver_Recv(o->input, o->data + IPUDP_HEADER_SIZE); -} - -static void input_handler_done (DHCPIpUdpEncoder *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // build IP header - struct ipv4_header iph; - iph.version4_ihl4 = IPV4_MAKE_VERSION_IHL(sizeof(iph)); - iph.ds = hton8(0); - iph.total_length = hton16(IPUDP_HEADER_SIZE + data_len); - iph.identification = hton16(0); - iph.flags3_fragmentoffset13 = hton16(0); - iph.ttl = hton8(64); - iph.protocol = hton8(IPV4_PROTOCOL_UDP); - iph.checksum = hton16(0); - iph.source_address = hton32(0x00000000); - iph.destination_address = hton32(0xFFFFFFFF); - iph.checksum = ipv4_checksum(&iph, NULL, 0); - - // write UDP header - struct udp_header udph; - udph.source_port = hton16(DHCP_CLIENT_PORT); - udph.dest_port = hton16(DHCP_SERVER_PORT); - udph.length = hton16(sizeof(udph) + data_len); - udph.checksum = hton16(0); - udph.checksum = udp_checksum(&udph, o->data + IPUDP_HEADER_SIZE, data_len, iph.source_address, iph.destination_address); - - // write header - memcpy(o->data, &iph, sizeof(iph)); - memcpy(o->data + sizeof(iph), &udph, sizeof(udph)); - - // finish packet - PacketRecvInterface_Done(&o->output, IPUDP_HEADER_SIZE + data_len); -} - -void DHCPIpUdpEncoder_Init (DHCPIpUdpEncoder *o, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - IPUDP_HEADER_SIZE) - - // init arguments - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketRecvInterface_Init(&o->output, IPUDP_HEADER_SIZE + PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DHCPIpUdpEncoder_Free (DHCPIpUdpEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * DHCPIpUdpEncoder_GetOutput (DHCPIpUdpEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.h b/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.h deleted file mode 100644 index d3e0ac0..0000000 --- a/external/badvpn_dns/dhcpclient/DHCPIpUdpEncoder.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file DHCPIpUdpEncoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_DHCPCLIENT_DHCPIPUDPENCODER_H -#define BADVPN_DHCPCLIENT_DHCPIPUDPENCODER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -typedef struct { - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *data; - DebugObject d_obj; -} DHCPIpUdpEncoder; - -void DHCPIpUdpEncoder_Init (DHCPIpUdpEncoder *o, PacketRecvInterface *input, BPendingGroup *pg); -void DHCPIpUdpEncoder_Free (DHCPIpUdpEncoder *o); -PacketRecvInterface * DHCPIpUdpEncoder_GetOutput (DHCPIpUdpEncoder *o); - -#endif diff --git a/external/badvpn_dns/dostest/CMakeLists.txt b/external/badvpn_dns/dostest/CMakeLists.txt deleted file mode 100644 index 8d3b742..0000000 --- a/external/badvpn_dns/dostest/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_executable(dostest-server - dostest-server.c - StreamBuffer.c -) -target_link_libraries(dostest-server base system) - -add_executable(dostest-attacker - dostest-attacker.c -) -target_link_libraries(dostest-attacker base system) diff --git a/external/badvpn_dns/dostest/StreamBuffer.c b/external/badvpn_dns/dostest/StreamBuffer.c deleted file mode 100644 index d439127..0000000 --- a/external/badvpn_dns/dostest/StreamBuffer.c +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file StreamBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/balloc.h> -#include <misc/minmax.h> - -#include "StreamBuffer.h" - -// called when receive operation is complete -static void input_handler_done (void *vo, int data_len) -{ - StreamBuffer *o = (StreamBuffer *)vo; - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_size - (o->buf_start + o->buf_used)) - - // remember if buffer was empty - int was_empty = (o->buf_used == 0); - - // increment buf_used by the amount that was received - o->buf_used += data_len; - - // start another receive operation unless buffer is full - if (o->buf_used < o->buf_size - o->buf_start) { - int end = o->buf_start + o->buf_used; - StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, o->buf_size - end); - } - else if (o->buf_used < o->buf_size) { - // wrap around - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_start); - } - - // if buffer was empty before, start send operation - if (was_empty) { - StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, o->buf_used); - } -} - -// called when send operation is complete -static void output_handler_done (void *vo, int data_len) -{ - StreamBuffer *o = (StreamBuffer *)vo; - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_used) - ASSERT(data_len <= o->buf_size - o->buf_start) - - // remember if buffer was full - int was_full = (o->buf_used == o->buf_size); - - // increment buf_start and decrement buf_used by the - // amount that was sent - o->buf_start += data_len; - o->buf_used -= data_len; - - // wrap around buf_start - if (o->buf_start == o->buf_size) { - o->buf_start = 0; - } - - // start receive operation if buffer was full - if (was_full) { - int end; - int avail; - if (o->buf_used >= o->buf_size - o->buf_start) { - end = o->buf_used - (o->buf_size - o->buf_start); - avail = o->buf_start - end; - } else { - end = o->buf_start + o->buf_used; - avail = o->buf_size - end; - } - StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, avail); - } - - // start another receive send unless buffer is empty - if (o->buf_used > 0) { - int to_send = bmin_int(o->buf_used, o->buf_size - o->buf_start); - StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, to_send); - } -} - -int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output) -{ - ASSERT(buf_size > 0) - ASSERT(input) - ASSERT(output) - - // remember arguments - o->buf_size = buf_size; - o->input = input; - o->output = output; - - // allocate buffer memory - o->buf = (uint8_t *)BAllocSize(bsize_fromint(o->buf_size)); - if (!o->buf) { - goto fail0; - } - - // set initial buffer state - o->buf_start = 0; - o->buf_used = 0; - - // set receive and send done callbacks - StreamRecvInterface_Receiver_Init(o->input, input_handler_done, o); - StreamPassInterface_Sender_Init(o->output, output_handler_done, o); - - // start receive operation - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void StreamBuffer_Free (StreamBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer memory - BFree(o->buf); -} diff --git a/external/badvpn_dns/dostest/StreamBuffer.h b/external/badvpn_dns/dostest/StreamBuffer.h deleted file mode 100644 index dd441f5..0000000 --- a/external/badvpn_dns/dostest/StreamBuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file StreamBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STREAMBUFFER_H -#define BADVPN_STREAMBUFFER_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> -#include <flow/StreamPassInterface.h> - -/** - * Buffer object which reads data from a \link StreamRecvInterface and writes - * it to a \link StreamPassInterface. - */ -typedef struct { - int buf_size; - StreamRecvInterface *input; - StreamPassInterface *output; - uint8_t *buf; - int buf_start; - int buf_used; - DebugObject d_obj; -} StreamBuffer; - -/** - * Initializes the buffer object. - * - * @param o object to initialize - * @param buf_size size of the buffer. Must be >0. - * @param input input interface - * @param outout output interface - * @return 1 on success, 0 on failure - */ -int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output) WARN_UNUSED; - -/** - * Frees the buffer object. - * - * @param o object to free - */ -void StreamBuffer_Free (StreamBuffer *o); - -#endif diff --git a/external/badvpn_dns/dostest/dostest-attacker.c b/external/badvpn_dns/dostest/dostest-attacker.c deleted file mode 100644 index 723dadd..0000000 --- a/external/badvpn_dns/dostest/dostest-attacker.c +++ /dev/null @@ -1,512 +0,0 @@ -/** - * @file dostest-attacker.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/version.h> -#include <misc/offset.h> -#include <misc/open_standard_streams.h> -#include <misc/balloc.h> -#include <misc/loglevel.h> -#include <misc/minmax.h> -#include <structure/LinkedList1.h> -#include <base/BLog.h> -#include <system/BAddr.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> -#include <system/BConnection.h> -#include <system/BSignal.h> - -#include <generated/blog_channel_dostest_attacker.h> - -#define PROGRAM_NAME "dostest-attacker" - -// connection structure -struct connection { - int connected; - BConnector connector; - BConnection con; - StreamRecvInterface *recv_if; - uint8_t buf[512]; - LinkedList1Node connections_list_node; -}; - -// command-line options -static struct { - int help; - int version; - char *connect_addr; - int max_connections; - int max_connecting; - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; -} options; - -// connect address -static BAddr connect_addr; - -// reactor -static BReactor reactor; - -// connections -static LinkedList1 connections_list; -static int num_connections; -static int num_connecting; - -// timer for scheduling creation of more connections -static BTimer make_connections_timer; - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static int connection_new (void); -static void connection_free (struct connection *conn); -static void connection_logfunc (struct connection *conn); -static void connection_log (struct connection *conn, int level, const char *fmt, ...); -static void connection_connector_handler (struct connection *conn, int is_error); -static void connection_connection_handler (struct connection *conn, int event); -static void connection_recv_handler_done (struct connection *conn, int data_len); -static void make_connections_timer_handler (void *unused); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // init loger - BLog_InitStderr(); - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&reactor)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // init connections list - LinkedList1_Init(&connections_list); - num_connections = 0; - num_connecting = 0; - - // init make connections timer - BTimer_Init(&make_connections_timer, 0, make_connections_timer_handler, NULL); - BReactor_SetTimer(&reactor, &make_connections_timer); - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&reactor); - - // free connections - while (!LinkedList1_IsEmpty(&connections_list)) { - struct connection *conn = UPPER_OBJECT(LinkedList1_GetFirst(&connections_list), struct connection, connections_list_node); - connection_free(conn); - } - // free make connections timer - BReactor_RemoveTimer(&reactor, &make_connections_timer); - // free signal - BSignal_Finish(); -fail2: - // free reactor - BReactor_Free(&reactor); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish debug objects - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " --connect-addr <addr>\n" - " --max-connections <number>\n" - " --max-connecting <number>\n" - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - options.help = 0; - options.version = 0; - options.connect_addr = NULL; - options.max_connections = -1; - options.max_connecting = -1; - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--connect-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.connect_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--max-connections")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_connections = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-connecting")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_connecting = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.connect_addr) { - fprintf(stderr, "--connect-addr missing\n"); - return 0; - } - - if (options.max_connections == -1) { - fprintf(stderr, "--max-connections missing\n"); - return 0; - } - - if (options.max_connecting == -1) { - fprintf(stderr, "--max-connecting missing\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen address - if (!BAddr_Parse(&connect_addr, options.connect_addr, NULL, 0)) { - BLog(BLOG_ERROR, "connect addr: BAddr_Parse failed"); - return 0; - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&reactor, 1); -} - -int connection_new (void) -{ - // allocate structure - struct connection *conn = (struct connection *)malloc(sizeof(*conn)); - if (!conn) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set not connected - conn->connected = 0; - - // init connector - if (!BConnector_Init(&conn->connector, connect_addr, &reactor, conn, (BConnector_handler)connection_connector_handler)) { - BLog(BLOG_ERROR, "BConnector_Init failed"); - goto fail1; - } - - // add to connections list - LinkedList1_Append(&connections_list, &conn->connections_list_node); - num_connections++; - num_connecting++; - - return 1; - -fail1: - free(conn); -fail0: - return 0; -} - -void connection_free (struct connection *conn) -{ - // remove from connections list - LinkedList1_Remove(&connections_list, &conn->connections_list_node); - num_connections--; - if (!conn->connected) { - num_connecting--; - } - - if (conn->connected) { - // free receive interface - BConnection_RecvAsync_Free(&conn->con); - - // free connection - BConnection_Free(&conn->con); - } - - // free connector - BConnector_Free(&conn->connector); - - // free structure - free(conn); -} - -void connection_logfunc (struct connection *conn) -{ - BLog_Append("%d connection (%p): ", num_connecting, (void *)conn); -} - -void connection_log (struct connection *conn, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)connection_logfunc, conn, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void connection_connector_handler (struct connection *conn, int is_error) -{ - ASSERT(!conn->connected) - - // check for connection error - if (is_error) { - connection_log(conn, BLOG_INFO, "failed to connect"); - goto fail0; - } - - // init connection from connector - if (!BConnection_Init(&conn->con, BConnection_source_connector(&conn->connector), &reactor, conn, (BConnection_handler)connection_connection_handler)) { - connection_log(conn, BLOG_INFO, "BConnection_Init failed"); - goto fail0; - } - - // init receive interface - BConnection_RecvAsync_Init(&conn->con); - conn->recv_if = BConnection_RecvAsync_GetIf(&conn->con); - StreamRecvInterface_Receiver_Init(conn->recv_if, (StreamRecvInterface_handler_done)connection_recv_handler_done, conn); - - // start receiving - StreamRecvInterface_Receiver_Recv(conn->recv_if, conn->buf, sizeof(conn->buf)); - - // no longer connecting - conn->connected = 1; - num_connecting--; - - connection_log(conn, BLOG_INFO, "connected"); - - // schedule making connections (because of connecting limit) - BReactor_SetTimer(&reactor, &make_connections_timer); - return; - -fail0: - // free connection - connection_free(conn); - - // schedule making connections - BReactor_SetTimer(&reactor, &make_connections_timer); -} - -void connection_connection_handler (struct connection *conn, int event) -{ - ASSERT(conn->connected) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - connection_log(conn, BLOG_INFO, "connection closed"); - } else { - connection_log(conn, BLOG_INFO, "connection error"); - } - - // free connection - connection_free(conn); - - // schedule making connections - BReactor_SetTimer(&reactor, &make_connections_timer); -} - -void connection_recv_handler_done (struct connection *conn, int data_len) -{ - ASSERT(conn->connected) - - // receive more - StreamRecvInterface_Receiver_Recv(conn->recv_if, conn->buf, sizeof(conn->buf)); - - connection_log(conn, BLOG_INFO, "received %d bytes", data_len); -} - -void make_connections_timer_handler (void *unused) -{ - int make_num = bmin_int(options.max_connections - num_connections, options.max_connecting - num_connecting); - - if (make_num <= 0) { - return; - } - - BLog(BLOG_INFO, "making %d connections", make_num); - - for (int i = 0; i < make_num; i++) { - if (!connection_new()) { - // can happen if fd limit is reached - BLog(BLOG_ERROR, "failed to make connection, waiting"); - BReactor_SetTimerAfter(&reactor, &make_connections_timer, 10); - return; - } - } -} diff --git a/external/badvpn_dns/dostest/dostest-server.c b/external/badvpn_dns/dostest/dostest-server.c deleted file mode 100644 index 7447591..0000000 --- a/external/badvpn_dns/dostest/dostest-server.c +++ /dev/null @@ -1,567 +0,0 @@ -/** - * @file dostest-server.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> - -#ifdef BADVPN_LINUX -#include <sys/types.h> -#include <sys/socket.h> -#endif - -#include <misc/debug.h> -#include <misc/version.h> -#include <misc/offset.h> -#include <misc/open_standard_streams.h> -#include <misc/balloc.h> -#include <misc/loglevel.h> -#include <structure/LinkedList1.h> -#include <base/BLog.h> -#include <system/BAddr.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> -#include <system/BConnection.h> -#include <system/BSignal.h> -#include "StreamBuffer.h" - -#include <generated/blog_channel_dostest_server.h> - -#define PROGRAM_NAME "dostest-server" - -#ifdef BADVPN_LINUX -#ifndef SO_DOSDEF_PREPARE -#define SO_DOSDEF_PREPARE 48 -#endif -#ifndef SO_DOSDEF_ACTIVATE -#define SO_DOSDEF_ACTIVATE 49 -#endif -#endif - -#define BUF_SIZE 1024 - -// client structure -struct client { - BConnection con; - BAddr addr; - StreamBuffer buf; - BTimer disconnect_timer; - LinkedList1Node clients_list_node; -}; - -// command-line options -static struct { - int help; - int version; - char *listen_addr; - int max_clients; - int disconnect_time; - int defense_prepare_clients; - int defense_activate_clients; - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; -} options; - -// listen address -static BAddr listen_addr; - -// reactor -static BReactor ss; - -// listener -static BListener listener; - -// clients -static LinkedList1 clients_list; -static int num_clients; - -// defense status -static int defense_prepare; -static int defense_activate; - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static void listener_handler (void *unused); -static void client_free (struct client *client); -static void client_logfunc (struct client *client); -static void client_log (struct client *client, int level, const char *fmt, ...); -static void client_disconnect_timer_handler (struct client *client); -static void client_connection_handler (struct client *client, int event); -static void update_defense (void); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // init loger - BLog_InitStderr(); - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // initialize listener - if (!BListener_Init(&listener, listen_addr, &ss, NULL, listener_handler)) { - BLog(BLOG_ERROR, "Listener_Init failed"); - goto fail3; - } - - // init clients list - LinkedList1_Init(&clients_list); - num_clients = 0; - - // clear defense state - defense_prepare = 0; - defense_activate = 0; - - // update defense - update_defense(); - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - // free clients - while (!LinkedList1_IsEmpty(&clients_list)) { - struct client *client = UPPER_OBJECT(LinkedList1_GetFirst(&clients_list), struct client, clients_list_node); - client_free(client); - } - // free listener - BListener_Free(&listener); -fail3: - // free signal - BSignal_Finish(); -fail2: - // free reactor - BReactor_Free(&ss); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish debug objects - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " --listen-addr <addr>\n" - " --max-clients <number>\n" - " --disconnect-time <milliseconds>\n" - " [--defense-prepare-clients <number>]\n" - " [--defense-activate-clients <number>]\n" - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - options.help = 0; - options.version = 0; - options.listen_addr = NULL; - options.max_clients = -1; - options.disconnect_time = -1; - options.defense_prepare_clients = -1; - options.defense_activate_clients = -1; - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--listen-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.listen_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--max-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--disconnect-time")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.disconnect_time = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--defense-prepare-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.defense_prepare_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--defense-activate-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.defense_activate_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.listen_addr) { - fprintf(stderr, "--listen-addr missing\n"); - return 0; - } - - if (options.max_clients == -1) { - fprintf(stderr, "--max-clients missing\n"); - return 0; - } - - if (options.disconnect_time == -1) { - fprintf(stderr, "--disconnect-time missing\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen address - if (!BAddr_Parse(&listen_addr, options.listen_addr, NULL, 0)) { - BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed"); - return 0; - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&ss, 1); -} - -void listener_handler (void *unused) -{ - if (num_clients == options.max_clients) { - BLog(BLOG_ERROR, "maximum number of clients reached"); - goto fail0; - } - - // allocate structure - struct client *client = (struct client *)malloc(sizeof(*client)); - if (!client) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // accept client - if (!BConnection_Init(&client->con, BConnection_source_listener(&listener, &client->addr), &ss, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // init connection interfaces - BConnection_RecvAsync_Init(&client->con); - BConnection_SendAsync_Init(&client->con); - StreamRecvInterface *recv_if = BConnection_RecvAsync_GetIf(&client->con); - StreamPassInterface *send_if = BConnection_SendAsync_GetIf(&client->con); - - // init stream buffer (to loop received data back to the client) - if (!StreamBuffer_Init(&client->buf, BUF_SIZE, recv_if, send_if)) { - BLog(BLOG_ERROR, "StreamBuffer_Init failed"); - goto fail2; - } - - // init disconnect timer - BTimer_Init(&client->disconnect_timer, options.disconnect_time, (BTimer_handler)client_disconnect_timer_handler, client); - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // insert to clients list - LinkedList1_Append(&clients_list, &client->clients_list_node); - num_clients++; - - client_log(client, BLOG_INFO, "connected"); - BLog(BLOG_NOTICE, "%d clients", num_clients); - - // update defense - update_defense(); - return; - -fail2: - BConnection_SendAsync_Free(&client->con); - BConnection_RecvAsync_Free(&client->con); - BConnection_Free(&client->con); -fail1: - free(client); -fail0: - return; -} - -void client_free (struct client *client) -{ - // remove from clients list - LinkedList1_Remove(&clients_list, &client->clients_list_node); - num_clients--; - - // free disconnect timer - BReactor_RemoveTimer(&ss, &client->disconnect_timer); - - // free stream buffer - StreamBuffer_Free(&client->buf); - - // free connection interfaces - BConnection_SendAsync_Free(&client->con); - BConnection_RecvAsync_Free(&client->con); - - // free connection - BConnection_Free(&client->con); - - // free structure - free(client); - - BLog(BLOG_NOTICE, "%d clients", num_clients); - - // update defense - update_defense(); -} - -void client_logfunc (struct client *client) -{ - char addr[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->addr, addr); - - BLog_Append("client (%s): ", addr); -} - -void client_log (struct client *client, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void client_disconnect_timer_handler (struct client *client) -{ - client_log(client, BLOG_INFO, "timed out, disconnecting"); - - // free client - client_free(client); -} - -void client_connection_handler (struct client *client, int event) -{ - if (event == BCONNECTION_EVENT_RECVCLOSED) { - client_log(client, BLOG_INFO, "client closed"); - } else { - client_log(client, BLOG_INFO, "client error"); - } - - // free client - client_free(client); -} - -void update_defense (void) -{ -#ifdef BADVPN_LINUX - if (options.defense_prepare_clients != -1) { - int val = num_clients >= options.defense_prepare_clients; - int res = setsockopt(listener.fd, SOL_SOCKET, SO_DOSDEF_PREPARE, &val, sizeof(val)); - if (res < 0) { - BLog(BLOG_ERROR, "failed to %s defense preparation", (val ? "enable" : "disable")); - } else { - if (!defense_prepare && val) { - BLog(BLOG_NOTICE, "defense preparation enabled"); - } - else if (defense_prepare && !val) { - BLog(BLOG_NOTICE, "defense preparation disabled"); - } - } - defense_prepare = val; - } - - if (options.defense_activate_clients != -1) { - int val = num_clients >= options.defense_activate_clients; - int res = setsockopt(listener.fd, SOL_SOCKET, SO_DOSDEF_ACTIVATE, &val, sizeof(val)); - if (res < 0) { - BLog(BLOG_ERROR, "failed to %s defense activation", (val ? "enable" : "disable")); - } else { - if (!defense_activate && val) { - BLog(BLOG_NOTICE, "defense activation enabled"); - } - else if (defense_activate && !val) { - BLog(BLOG_NOTICE, "defense activation disabled"); - } - } - defense_activate = val; - } -#endif -} diff --git a/external/badvpn_dns/examples/CMakeLists.txt b/external/badvpn_dns/examples/CMakeLists.txt deleted file mode 100644 index 27dbeaa..0000000 --- a/external/badvpn_dns/examples/CMakeLists.txt +++ /dev/null @@ -1,97 +0,0 @@ -if (NOT EMSCRIPTEN) - add_executable(btimer_example btimer_example.c) - target_link_libraries(btimer_example system) -endif () - -if (BUILDING_PREDICATE) - add_executable(predicate_test predicate_test.c) - target_link_libraries(predicate_test predicate) -endif () - -if (NOT EMSCRIPTEN) - add_executable(fairqueue_test fairqueue_test.c) - target_link_libraries(fairqueue_test system flow) -endif () - -add_executable(indexedlist_test indexedlist_test.c) - -if (BUILDING_SECURITY) - add_executable(fairqueue_test2 fairqueue_test2.c) - target_link_libraries(fairqueue_test2 system flow security) - - add_executable(bavl_test bavl_test.c) - target_link_libraries(bavl_test security) - - add_executable(savl_test savl_test.c) - target_link_libraries(savl_test security) - - add_executable(bencryption_bench bencryption_bench.c) - target_link_libraries(bencryption_bench system security) -endif () - -if (BUILD_NCD) - add_executable(ncd_tokenizer_test ncd_tokenizer_test.c) - target_link_libraries(ncd_tokenizer_test ncdtokenizer) - - add_executable(ncd_parser_test ncd_parser_test.c) - target_link_libraries(ncd_parser_test ncdconfigparser ncdvalgenerator ncdsugar) - - add_executable(ncd_value_parser_test ncd_value_parser_test.c) - target_link_libraries(ncd_value_parser_test ncdvalparser ncdvalgenerator) - - if (NOT EMSCRIPTEN) - add_executable(ncdinterfacemonitor_test ncdinterfacemonitor_test.c) - target_link_libraries(ncdinterfacemonitor_test ncdinterfacemonitor) - endif () - - add_executable(ncdval_test ncdval_test.c) - target_link_libraries(ncdval_test ncdval) - - add_executable(ncdvalcons_test ncdvalcons_test.c) - target_link_libraries(ncdvalcons_test ncdvalcons ncdvalgenerator) -endif () - -if (BUILDING_UDEVMONITOR) - add_executable(ncdudevmonitor_test ncdudevmonitor_test.c) - target_link_libraries(ncdudevmonitor_test udevmonitor) - - add_executable(ncdudevmanager_test ncdudevmanager_test.c) - target_link_libraries(ncdudevmanager_test udevmonitor) -endif () - -if (NOT WIN32 AND NOT EMSCRIPTEN) - add_executable(bprocess_example bprocess_example.c) - target_link_libraries(bprocess_example system) - - add_executable(stdin_input stdin_input.c) - target_link_libraries(stdin_input system flow flowextra) -endif () - -if (BUILDING_DHCPCLIENT) - add_executable(dhcpclient_test dhcpclient_test.c) - target_link_libraries(dhcpclient_test dhcpclient) -endif () - -if (BUILDING_ARPPROBE) - add_executable(arpprobe_test arpprobe_test.c) - target_link_libraries(arpprobe_test arpprobe) -endif () - -add_executable(substring_test substring_test.c) - -if (NOT WIN32) - add_executable(ipaddr6_test ipaddr6_test.c) - add_executable(parse_number_test parse_number_test.c) -endif () - -if (BUILDING_RANDOM) - add_executable(brandom2_test brandom2_test.c) - target_link_libraries(brandom2_test badvpn_random) -endif () - -add_executable(cavl_test cavl_test.c) - -if (EMSCRIPTEN) - add_executable(emscripten_test emscripten_test.c) - target_link_libraries(emscripten_test system) -endif () diff --git a/external/badvpn_dns/examples/FastPacketSource.h b/external/badvpn_dns/examples/FastPacketSource.h deleted file mode 100644 index e13e2f2..0000000 --- a/external/badvpn_dns/examples/FastPacketSource.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file FastPacketSource.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _FASTPACKETSOURCE_H -#define _FASTPACKETSOURCE_H - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -typedef struct { - PacketPassInterface *output; - int psize; - uint8_t *data; - int data_len; - DebugObject d_obj; -} FastPacketSource; - -static void _FastPacketSource_output_handler_done (FastPacketSource *s) -{ - DebugObject_Access(&s->d_obj); - - PacketPassInterface_Sender_Send(s->output, s->data, s->data_len); -} - -static void FastPacketSource_Init (FastPacketSource *s, PacketPassInterface *output, uint8_t *data, int data_len, BPendingGroup *pg) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= PacketPassInterface_GetMTU(output)); - - // init arguments - s->output = output; - s->data = data; - s->data_len = data_len; - - // init output - PacketPassInterface_Sender_Init(s->output, (PacketPassInterface_handler_done)_FastPacketSource_output_handler_done, s); - - // schedule send - PacketPassInterface_Sender_Send(s->output, s->data, s->data_len); - - DebugObject_Init(&s->d_obj); -} - -static void FastPacketSource_Free (FastPacketSource *s) -{ - DebugObject_Free(&s->d_obj); -} - -#endif diff --git a/external/badvpn_dns/examples/RandomPacketSink.h b/external/badvpn_dns/examples/RandomPacketSink.h deleted file mode 100644 index cbadf78..0000000 --- a/external/badvpn_dns/examples/RandomPacketSink.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file RandomPacketSink.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _RANDOMPACKETSINK_H -#define _RANDOMPACKETSINK_H - -#include <stdio.h> - -#include <misc/debug.h> -#include <security/BRandom.h> -#include <system/BReactor.h> -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -typedef struct { - BReactor *reactor; - PacketPassInterface input; - BTimer timer; - DebugObject d_obj; -} RandomPacketSink; - -static void _RandomPacketSink_input_handler_send (RandomPacketSink *s, uint8_t *data, int data_len) -{ - DebugObject_Access(&s->d_obj); - - printf("sink: send '"); - size_t res = fwrite(data, data_len, 1, stdout); - B_USE(res) - - uint8_t r; - BRandom_randomize(&r, sizeof(r)); - if (r&(uint8_t)1) { - printf("' accepting\n"); - PacketPassInterface_Done(&s->input); - } else { - printf("' delaying\n"); - BReactor_SetTimer(s->reactor, &s->timer); - } -} - -static void _RandomPacketSink_input_handler_requestcancel (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - printf("sink: cancelled\n"); - BReactor_RemoveTimer(s->reactor, &s->timer); - PacketPassInterface_Done(&s->input); -} - -static void _RandomPacketSink_timer_handler (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - PacketPassInterface_Done(&s->input); -} - -static void RandomPacketSink_Init (RandomPacketSink *s, BReactor *reactor, int mtu, int ms) -{ - // init arguments - s->reactor = reactor; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)_RandomPacketSink_input_handler_send, s, BReactor_PendingGroup(reactor)); - PacketPassInterface_EnableCancel(&s->input, (PacketPassInterface_handler_requestcancel)_RandomPacketSink_input_handler_requestcancel); - - // init timer - BTimer_Init(&s->timer, ms, (BTimer_handler)_RandomPacketSink_timer_handler, s); - - DebugObject_Init(&s->d_obj); -} - -static void RandomPacketSink_Free (RandomPacketSink *s) -{ - DebugObject_Free(&s->d_obj); - - // free timer - BReactor_RemoveTimer(s->reactor, &s->timer); - - // free input - PacketPassInterface_Free(&s->input); -} - -static PacketPassInterface * RandomPacketSink_GetInput (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - return &s->input; -} - -#endif diff --git a/external/badvpn_dns/examples/TimerPacketSink.h b/external/badvpn_dns/examples/TimerPacketSink.h deleted file mode 100644 index e1e8217..0000000 --- a/external/badvpn_dns/examples/TimerPacketSink.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file TimerPacketSink.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIMERPACKETSINK_H -#define _TIMERPACKETSINK_H - -#include <stdio.h> - -#include <misc/debug.h> -#include <system/BReactor.h> -#include <flow/PacketPassInterface.h> - -typedef struct { - BReactor *reactor; - PacketPassInterface input; - BTimer timer; -} TimerPacketSink; - -static void _TimerPacketSink_input_handler_send (TimerPacketSink *s, uint8_t *data, int data_len) -{ - printf("sink: send '"); - size_t res = fwrite(data, data_len, 1, stdout); - B_USE(res) - printf("'\n"); - - BReactor_SetTimer(s->reactor, &s->timer); -} - -static void _TimerPacketSink_input_handler_requestcancel (TimerPacketSink *s) -{ - printf("sink: cancelled\n"); - - BReactor_RemoveTimer(s->reactor, &s->timer); - PacketPassInterface_Done(&s->input); -} - -static void _TimerPacketSink_timer_handler (TimerPacketSink *s) -{ - printf("sink: done\n"); - - PacketPassInterface_Done(&s->input); -} - -static void TimerPacketSink_Init (TimerPacketSink *s, BReactor *reactor, int mtu, int ms) -{ - // init arguments - s->reactor = reactor; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)_TimerPacketSink_input_handler_send, s, BReactor_PendingGroup(s->reactor)); - PacketPassInterface_EnableCancel(&s->input, (PacketPassInterface_handler_requestcancel)_TimerPacketSink_input_handler_requestcancel); - - // init timer - BTimer_Init(&s->timer, ms, (BTimer_handler)_TimerPacketSink_timer_handler, s); -} - -static void TimerPacketSink_Free (TimerPacketSink *s) -{ - // free timer - BReactor_RemoveTimer(s->reactor, &s->timer); - - // free input - PacketPassInterface_Free(&s->input); -} - -static PacketPassInterface * TimerPacketSink_GetInput (TimerPacketSink *s) -{ - return &s->input; -} - -#endif diff --git a/external/badvpn_dns/examples/arpprobe_test.c b/external/badvpn_dns/examples/arpprobe_test.c deleted file mode 100644 index d075f52..0000000 --- a/external/badvpn_dns/examples/arpprobe_test.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file arpprobe_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BTime.h> -#include <system/BNetwork.h> -#include <arpprobe/BArpProbe.h> - -BReactor reactor; -BArpProbe arpprobe; - -static void signal_handler (void *user); -static void arpprobe_handler (void *unused, int event); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 3) { - printf("Usage: %s <interface> <addr>\n", argv[0]); - goto fail0; - } - - char *ifname = argv[1]; - uint32_t addr = inet_addr(argv[2]); - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - if (!BArpProbe_Init(&arpprobe, ifname, addr, &reactor, NULL, arpprobe_handler)) { - DEBUG("BArpProbe_Init failed"); - goto fail3; - } - - BReactor_Exec(&reactor); - - BArpProbe_Free(&arpprobe); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 0); -} - -void arpprobe_handler (void *unused, int event) -{ - switch (event) { - case BARPPROBE_EVENT_EXIST: { - printf("ARPPROBE: exist\n"); - } break; - - case BARPPROBE_EVENT_NOEXIST: { - printf("ARPPROBE: noexist\n"); - } break; - - case BARPPROBE_EVENT_ERROR: { - printf("ARPPROBE: error\n"); - - // exit reactor - BReactor_Quit(&reactor, 0); - } break; - - default: - ASSERT(0); - } -} diff --git a/external/badvpn_dns/examples/bavl_test.c b/external/badvpn_dns/examples/bavl_test.c deleted file mode 100644 index c30ae6f..0000000 --- a/external/badvpn_dns/examples/bavl_test.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file bavl_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <structure/BAVL.h> -#include <security/BRandom.h> - -struct mynode { - int used; - int num; - BAVLNode avl_node; -}; - -static int int_comparator (void *user, int *val1, int *val2) -{ - return B_COMPARE(*val1, *val2); -} - -static void verify (BAVL *tree) -{ - printf("Verifying...\n"); - BAVL_Verify(tree); -} - -int main (int argc, char **argv) -{ - int num_nodes; - int num_random_delete; - - if (argc != 3 || (num_nodes = atoi(argv[1])) <= 0 || (num_random_delete = atoi(argv[2])) < 0) { - fprintf(stderr, "Usage: %s <num> <numrandomdelete>\n", (argc > 0 ? argv[0] : NULL)); - return 1; - } - - struct mynode *nodes = (struct mynode *)BAllocArray(num_nodes, sizeof(*nodes)); - ASSERT_FORCE(nodes) - - int *values_ins = (int *)BAllocArray(num_nodes, sizeof(int)); - ASSERT_FORCE(values_ins) - - int *values = (int *)BAllocArray(num_random_delete, sizeof(int)); - ASSERT_FORCE(values) - - BAVL avl; - BAVL_Init(&avl, OFFSET_DIFF(struct mynode, num, avl_node), (BAVL_comparator)int_comparator, NULL); - verify(&avl); - - printf("Inserting random values...\n"); - int inserted = 0; - BRandom_randomize((uint8_t *)values_ins, num_nodes * sizeof(int)); - for (int i = 0; i < num_nodes; i++) { - nodes[i].num = values_ins[i]; - if (BAVL_Insert(&avl, &nodes[i].avl_node, NULL)) { - nodes[i].used = 1; - inserted++; - } else { - nodes[i].used = 0; - printf("Insert collision!\n"); - } - } - printf("Inserted %d entries\n", inserted); - verify(&avl); - - printf("Removing random entries...\n"); - int removed1 = 0; - BRandom_randomize((uint8_t *)values, num_random_delete * sizeof(int)); - for (int i = 0; i < num_random_delete; i++) { - int index = (((unsigned int *)values)[i] % num_nodes); - struct mynode *node = nodes + index; - if (node->used) { - BAVL_Remove(&avl, &node->avl_node); - node->used = 0; - removed1++; - } - } - printf("Removed %d entries\n", removed1); - verify(&avl); - - printf("Removing remaining...\n"); - int removed2 = 0; - while (!BAVL_IsEmpty(&avl)) { - struct mynode *node = UPPER_OBJECT(BAVL_GetFirst(&avl), struct mynode, avl_node); - ASSERT_FORCE(node->used) - BAVL_Remove(&avl, &node->avl_node); - node->used = 0; - removed2++; - } - printf("Removed %d entries\n", removed2); - ASSERT_FORCE(BAVL_IsEmpty(&avl)) - ASSERT_FORCE(removed1 + removed2 == inserted) - verify(&avl); - - BFree(nodes); - BFree(values_ins); - BFree(values); - - return 0; -} diff --git a/external/badvpn_dns/examples/bencryption_bench.c b/external/badvpn_dns/examples/bencryption_bench.c deleted file mode 100644 index c842bf2..0000000 --- a/external/badvpn_dns/examples/bencryption_bench.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file bencryption_bench.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <limits.h> - -#include <misc/balloc.h> -#include <security/BRandom.h> -#include <security/BEncryption.h> -#include <base/DebugObject.h> - -static void usage (char *name) -{ - printf( - "Usage: %s <enc/dec> <ciper> <num_blocks> <num_ops>\n" - " <cipher> is one of (blowfish, aes).\n", - name - ); - - exit(1); -} - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 5) { - usage(argv[0]); - } - - char *mode_str = argv[1]; - char *cipher_str = argv[2]; - - int mode; - int cipher = 0; // silence warning - int num_blocks = atoi(argv[3]); - int num_ops = atoi(argv[4]); - - if (!strcmp(mode_str, "enc")) { - mode = BENCRYPTION_MODE_ENCRYPT; - } - else if (!strcmp(mode_str, "dec")) { - mode = BENCRYPTION_MODE_DECRYPT; - } - else { - usage(argv[0]); - } - - if (!strcmp(cipher_str, "blowfish")) { - cipher = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(cipher_str, "aes")) { - cipher = BENCRYPTION_CIPHER_AES; - } - else { - usage(argv[0]); - } - - if (num_blocks < 0 || num_ops < 0) { - usage(argv[0]); - } - - int key_size = BEncryption_cipher_key_size(cipher); - int block_size = BEncryption_cipher_block_size(cipher); - - uint8_t key[BENCRYPTION_MAX_KEY_SIZE]; - BRandom_randomize(key, key_size); - - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - BRandom_randomize(iv, block_size); - - if (num_blocks > INT_MAX / block_size) { - printf("too much"); - goto fail0; - } - int unit_size = num_blocks * block_size; - - printf("unit size %d\n", unit_size); - - uint8_t *buf1 = (uint8_t *)BAlloc(unit_size); - if (!buf1) { - printf("BAlloc failed"); - goto fail0; - } - - uint8_t *buf2 = (uint8_t *)BAlloc(unit_size); - if (!buf2) { - printf("BAlloc failed"); - goto fail1; - } - - BEncryption enc; - BEncryption_Init(&enc, mode, cipher, key); - - uint8_t *in = buf1; - uint8_t *out = buf2; - BRandom_randomize(in, unit_size); - - for (int i = 0; i < num_ops; i++) { - BEncryption_Encrypt(&enc, in, out, unit_size, iv); - - uint8_t *t = in; - in = out; - out = t; - } - - BEncryption_Free(&enc); - BFree(buf2); -fail1: - BFree(buf1); -fail0: - DebugObjectGlobal_Finish(); - - return 0; -} diff --git a/external/badvpn_dns/examples/bprocess_example.c b/external/badvpn_dns/examples/bprocess_example.c deleted file mode 100644 index 0ece996..0000000 --- a/external/badvpn_dns/examples/bprocess_example.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file bprocess_example.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <unistd.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BUnixSignal.h> -#include <system/BTime.h> -#include <system/BProcess.h> - -BReactor reactor; -BUnixSignal unixsignal; -BProcessManager manager; -BProcess process; - -static void unixsignal_handler (void *user, int signo); -static void process_handler (void *user, int normally, uint8_t normally_exit_status); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - int ret = 1; - - if (argc < 2) { - printf("Usage: %s <program> [argument ...]\n", argv[0]); - goto fail0; - } - - char *program = argv[1]; - - // init time - BTime_Init(); - - // init logger - BLog_InitStdout(); - - // init reactor (event loop) - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - // choose signals to catch - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - - // init BUnixSignal for catching signals - if (!BUnixSignal_Init(&unixsignal, &reactor, set, unixsignal_handler, NULL)) { - DEBUG("BUnixSignal_Init failed"); - goto fail2; - } - - // init process manager - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - char **p_argv = argv + 1; - - // map fds 0, 1, 2 in child to fds 0, 1, 2 in parent - int fds[] = { 0, 1, 2, -1 }; - int fds_map[] = { 0, 1, 2 }; - - // start child process - if (!BProcess_InitWithFds(&process, &manager, process_handler, NULL, program, p_argv, NULL, fds, fds_map)) { - DEBUG("BProcess_Init failed"); - goto fail4; - } - - // enter event loop - ret = BReactor_Exec(&reactor); - - BProcess_Free(&process); -fail4: - BProcessManager_Free(&manager); -fail3: - BUnixSignal_Free(&unixsignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void unixsignal_handler (void *user, int signo) -{ - DEBUG("received %s, terminating child", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // send SIGTERM to child - BProcess_Terminate(&process); -} - -void process_handler (void *user, int normally, uint8_t normally_exit_status) -{ - DEBUG("process terminated"); - - int ret = (normally ? normally_exit_status : 1); - - // return from event loop - BReactor_Quit(&reactor, ret); -} diff --git a/external/badvpn_dns/examples/brandom2_test.c b/external/badvpn_dns/examples/brandom2_test.c deleted file mode 100644 index 539735c..0000000 --- a/external/badvpn_dns/examples/brandom2_test.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file brandom2_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <inttypes.h> - -#include <misc/debug.h> -#include <random/BRandom2.h> - -#define NUM_NUMBERS 10 - -static BRandom2 brandom; - -int main (int argc, char *argv[]) -{ - int ret = 1; - - if (!BRandom2_Init(&brandom, 0)) { - DEBUG("BRandom2_Init failed"); - goto fail0; - } - - uint32_t numbers[NUM_NUMBERS]; - if (!BRandom2_GenBytes(&brandom, numbers, sizeof(numbers))) { - DEBUG("BRandom2_GenBytes failed"); - goto fail1; - } - - for (int i = 0; i < NUM_NUMBERS; i++) { - printf("%"PRIu32"\n", numbers[i]); - } - - ret = 0; - -fail1: - BRandom2_Free(&brandom); -fail0: - return ret; -} diff --git a/external/badvpn_dns/examples/btimer_example.c b/external/badvpn_dns/examples/btimer_example.c deleted file mode 100644 index c4d8d54..0000000 --- a/external/badvpn_dns/examples/btimer_example.c +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file btimer_example.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> - -#include <system/BReactor.h> -#include <base/BLog.h> -#include <system/BTime.h> - -// gives average firing rate 100kHz -#define TIMER_NUM 500 -#define TIMER_MODULO 10 - -BReactor sys; - -void handle_timer (BTimer *bt) -{ - #ifdef BADVPN_USE_WINAPI - btime_t time = btime_gettime() + rand()%TIMER_MODULO; - #else - btime_t time = btime_gettime() + random()%TIMER_MODULO; - #endif - BReactor_SetTimerAbsolute(&sys, bt, time); -} - -int main () -{ - BLog_InitStdout(); - - #ifdef BADVPN_USE_WINAPI - srand(time(NULL)); - #else - srandom(time(NULL)); - #endif - - // init time - BTime_Init(); - - if (!BReactor_Init(&sys)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - BTimer timers[TIMER_NUM]; - - int i; - for (i=0; i<TIMER_NUM; i++) { - BTimer *timer = &timers[i]; - BTimer_Init(timer, 0, (BTimer_handler)handle_timer, timer); - BReactor_SetTimer(&sys, timer); - } - - int ret = BReactor_Exec(&sys); - BReactor_Free(&sys); - return ret; -} diff --git a/external/badvpn_dns/examples/cavl_test.c b/external/badvpn_dns/examples/cavl_test.c deleted file mode 100644 index 61fcbd6..0000000 --- a/external/badvpn_dns/examples/cavl_test.c +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @file cavl_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <stdint.h> -#include <limits.h> - -#include <misc/balloc.h> -#include <misc/compare.h> -#include <misc/debug.h> -#include <misc/print_macros.h> -#include <structure/CAvl.h> - -#define USE_COUNTS 0 -#define USE_ASSOC 1 - -typedef size_t entry_index; -#define MAX_INDICES SIZE_MAX - -typedef uint32_t entry_key; - -typedef uint8_t assoc_value; -typedef uint64_t assoc_sum; - -struct entry { - entry_index tree_child[2]; - entry_index tree_parent; - int8_t tree_balance; -#if USE_COUNTS - size_t tree_count; -#endif -#if USE_ASSOC - assoc_value assoc_value; - assoc_sum assoc_sum; -#endif - entry_key key; -}; - -typedef struct entry *entry_ptr; - -#include "cavl_test_tree.h" -#include <structure/CAvl_decl.h> - -#include "cavl_test_tree.h" -#include <structure/CAvl_impl.h> - -static void random_bytes (char *buf, size_t len) -{ - while (len > 0) { - *((unsigned char *)buf) = rand(); - buf++; - len--; - } -} - -static int uint64_less (void *user, uint64_t a, uint64_t b) -{ - return (a < b); -} - -#if USE_ASSOC -static MyTreeRef assoc_continue_last_lesser_equal (MyTree *tree, struct entry *arg, MyTreeRef ref, assoc_sum target_sum) -{ - assoc_sum cur_sum = MyTree_ExclusiveAssocPrefixSum(tree, arg, ref); - ASSERT(target_sum >= cur_sum) - while (cur_sum + ref.ptr->assoc_value <= target_sum) { - MyTreeRef next_ref = MyTree_GetNext(tree, arg, ref); - if (next_ref.link == -1) { - break; - } - cur_sum += ref.ptr->assoc_value; - ref = next_ref; - } - return ref; -} -#endif - -static void test_assoc (MyTree *tree, struct entry *arg) -{ -#if USE_ASSOC - assoc_sum sum = 0; - for (MyTreeRef ref = MyTree_GetFirst(tree, arg); ref.link != -1; ref = MyTree_GetNext(tree, arg, ref)) { - assoc_sum tree_sum = MyTree_ExclusiveAssocPrefixSum(tree, arg, ref); - ASSERT_FORCE(tree_sum == sum); - ASSERT_FORCE(MyTree_FindLastExclusiveAssocPrefixSumLesserEqual(tree, arg, sum, uint64_less, NULL).link == assoc_continue_last_lesser_equal(tree, arg, ref, sum).link); - ASSERT_FORCE(MyTree_FindLastExclusiveAssocPrefixSumLesserEqual(tree, arg, sum + 1, uint64_less, NULL).link == assoc_continue_last_lesser_equal(tree, arg, ref, sum + 1).link); - sum += ref.ptr->assoc_value; - } - ASSERT_FORCE(sum == MyTree_AssocSum(tree, arg)); -#endif -} - -int main (int argc, char *argv[]) -{ - //srand(time(NULL)); - - printf("sizeof(struct entry)=%" PRIsz "\n", sizeof(struct entry)); - - if (argc != 6) { - fprintf(stderr, "Usage: %s <num_keys> <num_lookups> <num_remove> <do_remove=1/0> <do_verify=1/0>\n", (argc > 0 ? argv[0] : "")); - return 1; - } - - size_t num_keys = atoi(argv[1]); - size_t num_lookups = atoi(argv[2]); - size_t num_remove = atoi(argv[3]); - size_t do_remove = atoi(argv[4]); - size_t do_verify = atoi(argv[5]); - - printf("Allocating keys...\n"); - entry_key *keys = (entry_key *)BAllocArray(num_keys, sizeof(keys[0])); - ASSERT_FORCE(keys); - - printf("Generating random keys...\n"); - random_bytes((char *)keys, num_keys * sizeof(keys[0])); - - printf("Allocating lookup indices...\n"); - uint64_t *lookup_indices = (uint64_t *)BAllocArray(num_lookups, sizeof(lookup_indices[0])); - ASSERT_FORCE(lookup_indices); - - printf("Generating random lookup indices...\n"); - random_bytes((char *)lookup_indices, num_lookups * sizeof(lookup_indices[0])); - - printf("Allocating remove indices...\n"); - uint64_t *remove_indices = (uint64_t *)BAllocArray(num_remove, sizeof(remove_indices[0])); - ASSERT_FORCE(remove_indices); - - printf("Generating random remove indices...\n"); - random_bytes((char *)remove_indices, num_remove * sizeof(remove_indices[0])); - -#if USE_ASSOC - printf("Allocating assoc values...\n"); - assoc_value *assoc_values = (assoc_value *)BAllocArray(num_keys, sizeof(assoc_values[0])); - ASSERT_FORCE(assoc_values); - - printf("Generating random assoc values...\n"); - random_bytes((char *)assoc_values, num_keys * sizeof(assoc_values[0])); -#endif - - printf("Allocating entries...\n"); - ASSERT_FORCE(num_keys <= MAX_INDICES); - struct entry *entries = (struct entry *)BAllocArray(num_keys, sizeof(*entries)); - ASSERT_FORCE(entries); - entry_index num_used_entries = 0; - - MyTree tree; - MyTree_Init(&tree); - - struct entry *arg = entries; - - ASSERT_FORCE(MyTree_IsEmpty(&tree)); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == 0); -#endif - test_assoc(&tree, arg); - - size_t num; -#if USE_COUNTS - size_t prevNum; -#endif - - printf("Inserting random numbers...\n"); - num = 0; - for (size_t i = 0; i < num_keys; i++) { - entries[num_used_entries].key = keys[i]; -#if USE_ASSOC - entries[num_used_entries].assoc_value = assoc_values[i]; -#endif - MyTreeRef ref = {&entries[num_used_entries], num_used_entries}; - if (!MyTree_Insert(&tree, arg, ref, NULL)) { - //printf("Insert collision!\n"); - continue; - } - num_used_entries++; - num++; - } - printf("Inserted %" PRIsz ".\n", num); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == num); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - test_assoc(&tree, arg); - } - - printf("Looking up random inserted keys...\n"); - for (size_t i = 0; i < num_lookups; i++) { - entry_index idx = lookup_indices[i] % num_keys; - MyTreeRef entry = MyTree_LookupExact(&tree, arg, keys[idx]); - ASSERT_FORCE(!MyTreeIsNullRef(entry)); - } - -#if USE_COUNTS - prevNum = MyTree_Count(&tree, arg); -#endif - num = 0; - printf("Looking up and removing random inserted keys...\n"); - for (size_t i = 0; i < num_remove; i++) { - entry_index idx = remove_indices[i] % num_keys; - MyTreeRef entry = MyTree_LookupExact(&tree, arg, keys[idx]); - if (MyTreeIsNullRef(entry)) { - //printf("Remove collision!\n"); - continue; - } - ASSERT_FORCE(entry.ptr->key == keys[idx]); - MyTree_Remove(&tree, arg, entry); - num++; - } - printf("Removed %" PRIsz ".\n", num); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == prevNum - num); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - test_assoc(&tree, arg); - } - - if (do_remove) { -#if USE_COUNTS - prevNum = MyTree_Count(&tree, arg); -#endif - num = 0; - printf("Removing remaining...\n"); - - MyTreeRef cur = MyTree_GetFirst(&tree, arg); - while (!MyTreeIsNullRef(cur)) { - MyTreeRef prev = cur; - cur = MyTree_GetNext(&tree, arg, cur); - MyTree_Remove(&tree, arg, prev); - num++; - } - - printf("Removed %" PRIsz ".\n", num); - ASSERT_FORCE(MyTree_IsEmpty(&tree)); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == 0); - ASSERT_FORCE(num == prevNum); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - } - } - - printf("Freeing...\n"); - BFree(keys); - BFree(lookup_indices); - BFree(remove_indices); -#if USE_ASSOC - BFree(assoc_values); -#endif - BFree(entries); - - return 0; -} diff --git a/external/badvpn_dns/examples/cavl_test_tree.h b/external/badvpn_dns/examples/cavl_test_tree.h deleted file mode 100644 index 463076f..0000000 --- a/external/badvpn_dns/examples/cavl_test_tree.h +++ /dev/null @@ -1,23 +0,0 @@ -#define CAVL_PARAM_NAME MyTree -#define CAVL_PARAM_FEATURE_COUNTS USE_COUNTS -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0 -#define CAVL_PARAM_FEATURE_ASSOC USE_ASSOC -#define CAVL_PARAM_TYPE_ENTRY struct entry -#define CAVL_PARAM_TYPE_LINK entry_index -#define CAVL_PARAM_TYPE_KEY entry_key -#define CAVL_PARAM_TYPE_ARG entry_ptr -#define CAVL_PARAM_TYPE_COUNT size_t -#define CAVL_PARAM_TYPE_ASSOC assoc_sum -#define CAVL_PARAM_VALUE_COUNT_MAX SIZE_MAX -#define CAVL_PARAM_VALUE_NULL ((entry_index)-1) -#define CAVL_PARAM_VALUE_ASSOC_ZERO 0 -#define CAVL_PARAM_FUN_DEREF(arg, link) (&(arg)[(link)]) -#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1).ptr->key, (entry2).ptr->key) -#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2).ptr->key) -#define CAVL_PARAM_FUN_ASSOC_VALUE(arg, entry) ((entry).ptr->assoc_value) -#define CAVL_PARAM_FUN_ASSOC_OPER(arg, value1, value2) ((value1) + (value2)) -#define CAVL_PARAM_MEMBER_CHILD tree_child -#define CAVL_PARAM_MEMBER_BALANCE tree_balance -#define CAVL_PARAM_MEMBER_PARENT tree_parent -#define CAVL_PARAM_MEMBER_COUNT tree_count -#define CAVL_PARAM_MEMBER_ASSOC assoc_sum diff --git a/external/badvpn_dns/examples/dhcpclient_test.c b/external/badvpn_dns/examples/dhcpclient_test.c deleted file mode 100644 index 9601c01..0000000 --- a/external/badvpn_dns/examples/dhcpclient_test.c +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @file dhcpclient_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BTime.h> -#include <system/BNetwork.h> -#include <dhcpclient/BDHCPClient.h> - -BReactor reactor; -BRandom2 random2; -BDHCPClient dhcp; - -static void signal_handler (void *user); -static void dhcp_handler (void *unused, int event); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 2) { - printf("Usage: %s <interface>\n", argv[0]); - goto fail0; - } - - char *ifname = argv[1]; - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BRandom2_Init(&random2, 0)) { - DEBUG("BRandom2_Init failed"); - goto fail1a; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - struct BDHCPClient_opts opts = {}; - - if (!BDHCPClient_Init(&dhcp, ifname, opts, &reactor, &random2, dhcp_handler, NULL)) { - DEBUG("BDHCPClient_Init failed"); - goto fail3; - } - - BReactor_Exec(&reactor); - - BDHCPClient_Free(&dhcp); -fail3: - BSignal_Finish(); -fail2: - BRandom2_Free(&random2); -fail1a: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 0); -} - -void dhcp_handler (void *unused, int event) -{ - switch (event) { - case BDHCPCLIENT_EVENT_UP: { - printf("DHCP: up"); - - uint32_t ip; - uint8_t *ipb = (void *)&ip; - - BDHCPClient_GetClientIP(&dhcp, &ip); - printf(" IP=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - - BDHCPClient_GetClientMask(&dhcp, &ip); - printf(" Mask=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - - if (BDHCPClient_GetRouter(&dhcp, &ip)) { - printf(" Router=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - } - - uint32_t dns[BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS]; - int num = BDHCPClient_GetDNS(&dhcp, dns, BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS); - for (int i = 0; i < num; i++) { - ip=dns[i]; - printf(" DNS=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - } - - printf("\n"); - } break; - - case BDHCPCLIENT_EVENT_DOWN: { - printf("DHCP: down\n"); - } break; - - case BDHCPCLIENT_EVENT_ERROR: { - printf("DHCP: error\n"); - - // exit reactor - BReactor_Quit(&reactor, 0); - } break; - - default: - ASSERT(0); - } -} diff --git a/external/badvpn_dns/examples/emscripten_test.c b/external/badvpn_dns/examples/emscripten_test.c deleted file mode 100644 index 52b0351..0000000 --- a/external/badvpn_dns/examples/emscripten_test.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file emscripten_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> - -#include <emscripten/emscripten.h> - -#include <misc/debug.h> -#include <system/BTime.h> -#include <system/BReactor.h> - -BReactor reactor; -BTimer timer; -BPending job; - -static void timer_handler (void *unused) -{ - printf("timer_handler %"PRIu64"\n", btime_gettime()); - - BPending_Set(&job); - BReactor_SetTimer(&reactor, &timer); -} - -static void job_handler (void *unused) -{ - printf("job_handler %"PRIu64"\n", btime_gettime()); -} - -int main () -{ - BTime_Init(); - - BReactor_EmscriptenInit(&reactor); - - BTimer_Init(&timer, 500, timer_handler, NULL); - BReactor_SetTimer(&reactor, &timer); - - BPending_Init(&job, BReactor_PendingGroup(&reactor), job_handler, NULL); - BPending_Set(&job); - - BReactor_EmscriptenSync(&reactor); - return 0; -} diff --git a/external/badvpn_dns/examples/fairqueue_test.c b/external/badvpn_dns/examples/fairqueue_test.c deleted file mode 100644 index 482e086..0000000 --- a/external/badvpn_dns/examples/fairqueue_test.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file fairqueue_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdio.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <system/BReactor.h> -#include <base/BLog.h> -#include <system/BTime.h> -#include <flow/PacketPassFairQueue.h> -#include <examples/FastPacketSource.h> -#include <examples/TimerPacketSink.h> - -#define OUTPUT_INTERVAL 0 -#define REMOVE_INTERVAL 1 -#define NUM_INPUTS 3 - -BReactor reactor; -TimerPacketSink sink; -PacketPassFairQueue fq; -PacketPassFairQueueFlow flows[NUM_INPUTS]; -FastPacketSource sources[NUM_INPUTS]; -char *data[] = {"0 data", "1 datadatadata", "2 datadatadatadatadata"}; -BTimer timer; -int current_cancel; - -static void init_input (int i) -{ - PacketPassFairQueueFlow_Init(&flows[i], &fq); - FastPacketSource_Init(&sources[i], PacketPassFairQueueFlow_GetInput(&flows[i]), (uint8_t *)data[i], strlen(data[i]), BReactor_PendingGroup(&reactor)); -} - -static void free_input (int i) -{ - FastPacketSource_Free(&sources[i]); - PacketPassFairQueueFlow_Free(&flows[i]); -} - -static void reset_input (void) -{ - PacketPassFairQueueFlow_AssertFree(&flows[current_cancel]); - - printf("removing %d\n", current_cancel); - - // remove flow - free_input(current_cancel); - - // init flow - init_input(current_cancel); - - // increment cancel - current_cancel = (current_cancel + 1) % NUM_INPUTS; - - // reset timer - BReactor_SetTimer(&reactor, &timer); -} - -static void flow_handler_busy (void *user) -{ - PacketPassFairQueueFlow_AssertFree(&flows[current_cancel]); - - reset_input(); -} - -static void timer_handler (void *user) -{ - // if flow is busy, request cancel and wait for it - if (PacketPassFairQueueFlow_IsBusy(&flows[current_cancel])) { - printf("cancelling %d\n", current_cancel); - PacketPassFairQueueFlow_RequestCancel(&flows[current_cancel]); - PacketPassFairQueueFlow_SetBusyHandler(&flows[current_cancel], flow_handler_busy, NULL); - return; - } - - reset_input(); -} - -int main () -{ - // initialize logging - BLog_InitStdout(); - - // init time - BTime_Init(); - - // initialize reactor - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - // initialize sink - TimerPacketSink_Init(&sink, &reactor, 500, OUTPUT_INTERVAL); - - // initialize queue - if (!PacketPassFairQueue_Init(&fq, TimerPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 1, 1)) { - DEBUG("PacketPassFairQueue_Init failed"); - return 1; - } - - // initialize inputs - for (int i = 0; i < NUM_INPUTS; i++) { - init_input(i); - } - - // init cancel timer - BTimer_Init(&timer, REMOVE_INTERVAL, timer_handler, NULL); - BReactor_SetTimer(&reactor, &timer); - - // init cancel counter - current_cancel = 0; - - // run reactor - int ret = BReactor_Exec(&reactor); - BReactor_Free(&reactor); - return ret; -} diff --git a/external/badvpn_dns/examples/fairqueue_test2.c b/external/badvpn_dns/examples/fairqueue_test2.c deleted file mode 100644 index 0fe9d34..0000000 --- a/external/badvpn_dns/examples/fairqueue_test2.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file fairqueue_test2.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/debug.h> -#include <system/BReactor.h> -#include <base/BLog.h> -#include <system/BTime.h> -#include <flow/PacketPassFairQueue.h> -#include <examples/FastPacketSource.h> -#include <examples/RandomPacketSink.h> - -#define SINK_TIMER 0 - -int main () -{ - // initialize logging - BLog_InitStdout(); - - // init time - BTime_Init(); - - // initialize reactor - BReactor reactor; - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - // initialize sink - RandomPacketSink sink; - RandomPacketSink_Init(&sink, &reactor, 500, SINK_TIMER); - - // initialize queue - PacketPassFairQueue fq; - if (!PacketPassFairQueue_Init(&fq, RandomPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 0, 1)) { - DEBUG("PacketPassFairQueue_Init failed"); - return 1; - } - - // initialize source 1 - PacketPassFairQueueFlow flow1; - PacketPassFairQueueFlow_Init(&flow1, &fq); - FastPacketSource source1; - char data1[] = "data1"; - FastPacketSource_Init(&source1, PacketPassFairQueueFlow_GetInput(&flow1), (uint8_t *)data1, strlen(data1), BReactor_PendingGroup(&reactor)); - - // initialize source 2 - PacketPassFairQueueFlow flow2; - PacketPassFairQueueFlow_Init(&flow2, &fq); - FastPacketSource source2; - char data2[] = "data2data2"; - FastPacketSource_Init(&source2, PacketPassFairQueueFlow_GetInput(&flow2), (uint8_t *)data2, strlen(data2), BReactor_PendingGroup(&reactor)); - - // initialize source 3 - PacketPassFairQueueFlow flow3; - PacketPassFairQueueFlow_Init(&flow3, &fq); - FastPacketSource source3; - char data3[] = "data3data3data3data3data3data3data3data3data3"; - FastPacketSource_Init(&source3, PacketPassFairQueueFlow_GetInput(&flow3), (uint8_t *)data3, strlen(data3), BReactor_PendingGroup(&reactor)); - - // run reactor - int ret = BReactor_Exec(&reactor); - BReactor_Free(&reactor); - return ret; -} diff --git a/external/badvpn_dns/examples/indexedlist_test.c b/external/badvpn_dns/examples/indexedlist_test.c deleted file mode 100644 index d5282c0..0000000 --- a/external/badvpn_dns/examples/indexedlist_test.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file indexedlist_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> -#include <misc/offset.h> -#include <structure/IndexedList.h> - -IndexedList il; - -struct elem { - int value; - IndexedListNode node; -}; - -static void elem_insert (struct elem *e, int value, uint64_t index) -{ - e->value = value; - IndexedList_InsertAt(&il, &e->node, index); -} - -static void remove_at (uint64_t index) -{ - IndexedListNode *n = IndexedList_GetAt(&il, index); - struct elem *e = UPPER_OBJECT(n, struct elem, node); - IndexedList_Remove(&il, &e->node); -} - -static void print_list (void) -{ - for (uint64_t i = 0; i < IndexedList_Count(&il); i++) { - IndexedListNode *n = IndexedList_GetAt(&il, i); - struct elem *e = UPPER_OBJECT(n, struct elem, node); - printf("%d ", e->value); - } - printf("\n"); -} - -int main (int argc, char *argv[]) -{ - IndexedList_Init(&il); - - struct elem arr[100]; - - print_list(); - - elem_insert(&arr[0], 1, 0); - print_list(); - elem_insert(&arr[1], 2, 0); - print_list(); - elem_insert(&arr[2], 3, 0); - print_list(); - elem_insert(&arr[3], 4, 0); - print_list(); - elem_insert(&arr[4], 5, 0); - print_list(); - elem_insert(&arr[5], 6, 0); - print_list(); - - elem_insert(&arr[6], 7, 1); - print_list(); - - remove_at(0); - print_list(); - - remove_at(5); - print_list(); - - return 0; -} diff --git a/external/badvpn_dns/examples/ipaddr6_test.c b/external/badvpn_dns/examples/ipaddr6_test.c deleted file mode 100644 index 7da486d..0000000 --- a/external/badvpn_dns/examples/ipaddr6_test.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file ipaddr6_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <inttypes.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include <misc/debug.h> -#include <misc/ipaddr6.h> - -#define PRINT_TEST(addr_bytes, string) \ - { \ - struct ipv6_addr addr = {addr_bytes}; \ - char str[IPADDR6_PRINT_MAX]; \ - ipaddr6_print_addr(addr, str); \ - ASSERT_FORCE(!strcmp(str, (string))); \ - struct ipv6_addr parsed_addr; \ - int res = ipaddr6_parse_ipv6_addr_bin(str, strlen(str), &parsed_addr); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(!memcmp(parsed_addr.bytes, addr.bytes, 16)); \ - } - -#define PARSE_TEST(string, addr_bytes) \ - { \ - struct ipv6_addr exp_addr = {addr_bytes}; \ - struct ipv6_addr addr; \ - int res = ipaddr6_parse_ipv6_addr_bin((string), strlen((string)), &addr); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(!memcmp(addr.bytes, exp_addr.bytes, 16)); \ - } - -#define PARSE_FAIL_TEST(string) \ - { \ - struct ipv6_addr addr; \ - int res = ipaddr6_parse_ipv6_addr_bin((string), strlen((string)), &addr); \ - ASSERT_FORCE(!res); \ - } - -#define MASK_TEST(mask_bytes, prefix) \ - { \ - struct ipv6_addr mask = {mask_bytes}; \ - int parsed_prefix; \ - int res = ipaddr6_ipv6_prefix_from_mask(mask, &parsed_prefix); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(parsed_prefix == (prefix)); \ - struct ipv6_addr generated_mask; \ - ipaddr6_ipv6_mask_from_prefix(parsed_prefix, &generated_mask); \ - ASSERT_FORCE(!memcmp(generated_mask.bytes, mask.bytes, 16)); \ - } - -#define PASS(...) __VA_ARGS__ - -int main () -{ - PRINT_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), "::1") - PRINT_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), "::") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),"2001:db8::1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01}), "2001:db8::2:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}), "2001:db8:0:1:1:1:1:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}), "2001:db8:0:1:1:1:1:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), "2001:db8::1:0:0:1") - - PARSE_TEST("::", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("::1", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) - PARSE_TEST("::abcd", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd})) - PARSE_TEST("::0123:abcd", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0xab, 0xcd})) - PARSE_TEST("abcd::", PASS({0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("abcd:0123::", PASS({0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("1::2", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02})) - PARSE_TEST("abcd:0123::3210:dcba", PASS({0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("4567:abcd:0123::3210:dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("4567:abcd:0123:1111:2222:3333:3210::", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0x00, 0x00})) - PARSE_TEST("::4567:abcd:0123:1111:2222:3333:3210", PASS({0x00, 0x00, 0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10})) - PARSE_TEST("4567:abcd:0123:1111:2222:3333:3210:dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("04567:000abcd:00000123:01111:2222:03333:0003210:0dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("::1.2.3.4", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ff::1.2.3.4", PASS({0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ff::0.2.3.4", PASS({0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04})) - PARSE_TEST("1:2:3:4:5:6:1.2.3.4", PASS({0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255", PASS({0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})) - PARSE_TEST("1::fffa:1.2.3.4", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfa, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("1::fffa:0.0.0.0", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00})) - - PARSE_FAIL_TEST("") - PARSE_FAIL_TEST(":") - PARSE_FAIL_TEST("a") - PARSE_FAIL_TEST("a:b") - PARSE_FAIL_TEST(":b") - PARSE_FAIL_TEST("b:") - PARSE_FAIL_TEST("1:2:3:4:5:6:7") - PARSE_FAIL_TEST(":1:2:3:4:5:6:7") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:") - PARSE_FAIL_TEST(":::") - PARSE_FAIL_TEST("::a::") - PARSE_FAIL_TEST("::a::b") - PARSE_FAIL_TEST("c::a::b") - PARSE_FAIL_TEST("c::a::") - PARSE_FAIL_TEST("10000::") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:8:9") - PARSE_FAIL_TEST("1:2:3:4::5:6:7:8:9") - PARSE_FAIL_TEST("::1:2:3:4:5:6:7:8:9") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:8:9::") - PARSE_FAIL_TEST("a::b:") - PARSE_FAIL_TEST(":a::b") - PARSE_FAIL_TEST("::g") - PARSE_FAIL_TEST("::1.2") - PARSE_FAIL_TEST("::1.2.3.4.5") - PARSE_FAIL_TEST("::01.2.3.4") - PARSE_FAIL_TEST("::1.2.3.04") - PARSE_FAIL_TEST("::1.2.3.256") - PARSE_FAIL_TEST("1.2.3.4") - PARSE_FAIL_TEST("::8259.2.473.256") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:1.2.3.4") - PARSE_FAIL_TEST("1:2:3:4:5:1.2.3.4") - PARSE_FAIL_TEST("::1.2.3.4::") - PARSE_FAIL_TEST("::1.2.3.4:1") - PARSE_FAIL_TEST("localhost6") - - MASK_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 0) - MASK_TEST(PASS({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 1) - MASK_TEST(PASS({0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 2) - MASK_TEST(PASS({0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 3) - MASK_TEST(PASS({0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 4) - MASK_TEST(PASS({0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 5) - MASK_TEST(PASS({0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 6) - MASK_TEST(PASS({0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 7) - MASK_TEST(PASS({0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 8) - - MASK_TEST(PASS({0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 9) - MASK_TEST(PASS({0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 10) - MASK_TEST(PASS({0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 11) - MASK_TEST(PASS({0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 12) - MASK_TEST(PASS({0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 13) - MASK_TEST(PASS({0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 14) - MASK_TEST(PASS({0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 15) - MASK_TEST(PASS({0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 16) - - MASK_TEST(PASS({0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}), 127) - MASK_TEST(PASS({0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}), 128) - - return 0; -} diff --git a/external/badvpn_dns/examples/ncd_parser_test.c b/external/badvpn_dns/examples/ncd_parser_test.c deleted file mode 100644 index ac913b5..0000000 --- a/external/badvpn_dns/examples/ncd_parser_test.c +++ /dev/null @@ -1,294 +0,0 @@ -/** - * @file ncd_parser_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <inttypes.h> - -#include <misc/debug.h> -#include <misc/expstring.h> -#include <base/BLog.h> -#include <ncd/NCDConfigParser.h> -#include <ncd/NCDValGenerator.h> -#include <ncd/NCDSugar.h> - -static int generate_val (NCDValue *value, ExpString *out_str) -{ - switch (NCDValue_Type(value)) { - case NCDVALUE_STRING: { - const char *str = NCDValue_StringValue(value); - size_t len = NCDValue_StringLength(value); - - if (!ExpString_AppendChar(out_str, '"')) { - goto fail; - } - - for (size_t i = 0; i < len; i++) { - if (str[i] == '\0') { - char buf[5]; - snprintf(buf, sizeof(buf), "\\x%02"PRIx8, (uint8_t)str[i]); - - if (!ExpString_Append(out_str, buf)) { - goto fail; - } - - continue; - } - - if (str[i] == '"' || str[i] == '\\') { - if (!ExpString_AppendChar(out_str, '\\')) { - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, str[i])) { - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, '"')) { - goto fail; - } - } break; - - case NCDVALUE_LIST: { - if (!ExpString_AppendChar(out_str, '{')) { - goto fail; - } - - int is_first = 1; - - for (NCDValue *e = NCDValue_ListFirst(value); e; e = NCDValue_ListNext(value, e)) { - if (!is_first) { - if (!ExpString_Append(out_str, ", ")) { - goto fail; - } - } - - if (!generate_val(e, out_str)) { - goto fail; - } - - is_first = 0; - } - - if (!ExpString_AppendChar(out_str, '}')) { - goto fail; - } - } break; - - case NCDVALUE_MAP: { - if (!ExpString_AppendChar(out_str, '[')) { - goto fail; - } - - int is_first = 1; - - for (NCDValue *ekey = NCDValue_MapFirstKey(value); ekey; ekey = NCDValue_MapNextKey(value, ekey)) { - NCDValue *eval = NCDValue_MapKeyValue(value, ekey); - - if (!is_first) { - if (!ExpString_Append(out_str, ", ")) { - goto fail; - } - } - - if (!generate_val(ekey, out_str)) { - goto fail; - } - - if (!ExpString_AppendChar(out_str, ':')) { - goto fail; - } - - if (!generate_val(eval, out_str)) { - goto fail; - } - - is_first = 0; - } - - if (!ExpString_AppendChar(out_str, ']')) { - goto fail; - } - } break; - - default: ASSERT(0); - } - - return 1; - -fail: - return 0; -} - -static void print_indent (unsigned int indent) -{ - while (indent > 0) { - printf(" "); - indent--; - } -} - -static void print_value (NCDValue *v, unsigned int indent) -{ - ExpString estr; - if (!ExpString_Init(&estr)) { - DEBUG("ExpString_Init failed"); - exit(1); - } - - if (!generate_val(v, &estr)) { - DEBUG("generate_val failed"); - exit(1); - } - - print_indent(indent); - printf("%s\n", ExpString_Get(&estr)); - - ExpString_Free(&estr); -} - -static void print_block (NCDBlock *block, unsigned int indent) -{ - for (NCDStatement *st = NCDBlock_FirstStatement(block); st; st = NCDBlock_NextStatement(block, st)) { - const char *name = NCDStatement_Name(st) ? NCDStatement_Name(st) : ""; - - switch (NCDStatement_Type(st)) { - case NCDSTATEMENT_REG: { - const char *objname = NCDStatement_RegObjName(st) ? NCDStatement_RegObjName(st) : ""; - const char *cmdname = NCDStatement_RegCmdName(st); - - print_indent(indent); - printf("reg name=%s objname=%s cmdname=%s args:\n", name, objname, cmdname); - - print_value(NCDStatement_RegArgs(st), indent + 2); - } break; - - case NCDSTATEMENT_IF: { - print_indent(indent); - printf("if name=%s\n", name); - - NCDIfBlock *ifb = NCDStatement_IfBlock(st); - - for (NCDIf *ifc = NCDIfBlock_FirstIf(ifb); ifc; ifc = NCDIfBlock_NextIf(ifb, ifc)) { - print_indent(indent + 2); - printf("if\n"); - - print_value(NCDIf_Cond(ifc), indent + 4); - - print_indent(indent + 2); - printf("then\n"); - - print_block(NCDIf_Block(ifc), indent + 4); - } - - if (NCDStatement_IfElse(st)) { - print_indent(indent + 2); - printf("else\n"); - - print_block(NCDStatement_IfElse(st), indent + 4); - } - } break; - - case NCDSTATEMENT_FOREACH: { - const char *name1 = NCDStatement_ForeachName1(st); - const char *name2 = NCDStatement_ForeachName2(st) ? NCDStatement_ForeachName2(st) : ""; - - print_indent(indent); - printf("foreach name=%s name1=%s name2=%s\n", name, name1, name2); - - print_block(NCDStatement_ForeachBlock(st), indent + 2); - } break; - - default: ASSERT(0); - } - } -} - -int main (int argc, char **argv) -{ - int res = 1; - - if (argc != 3) { - printf("Usage: %s <desugar=0/1> <string>\n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - int desugar = atoi(argv[1]); - char *text = argv[2]; - - BLog_InitStdout(); - - // parse - NCDProgram prog; - if (!NCDConfigParser_Parse(text, strlen(text), &prog)) { - DEBUG("NCDConfigParser_Parse failed"); - goto fail1; - } - - // desugar - if (desugar) { - if (!NCDSugar_Desugar(&prog)) { - DEBUG("NCDSugar_Desugar failed"); - goto fail2; - } - } - - // print - for (NCDProgramElem *elem = NCDProgram_FirstElem(&prog); elem; elem = NCDProgram_NextElem(&prog, elem)) { - switch (NCDProgramElem_Type(elem)) { - case NCDPROGRAMELEM_PROCESS: { - NCDProcess *p = NCDProgramElem_Process(elem); - printf("process name=%s is_template=%d\n", NCDProcess_Name(p), NCDProcess_IsTemplate(p)); - print_block(NCDProcess_Block(p), 2); - } break; - - case NCDPROGRAMELEM_INCLUDE: { - printf("include path=%s\n", NCDProgramElem_IncludePathData(elem)); - } break; - - case NCDPROGRAMELEM_INCLUDE_GUARD: { - printf("include_guard id=%s\n", NCDProgramElem_IncludeGuardIdData(elem)); - } break; - - default: ASSERT(0); - } - } - - res = 0; -fail2: - NCDProgram_Free(&prog); -fail1: - BLog_Free(); -fail0: - return res; -} diff --git a/external/badvpn_dns/examples/ncd_tokenizer_test.c b/external/badvpn_dns/examples/ncd_tokenizer_test.c deleted file mode 100644 index 84f90eb..0000000 --- a/external/badvpn_dns/examples/ncd_tokenizer_test.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file ncd_tokenizer_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdio.h> -#include <string.h> - -#include <misc/debug.h> -#include <base/BLog.h> -#include <ncd/NCDConfigTokenizer.h> - -int error; - -static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char) -{ - if (token == NCD_ERROR) { - printf("line %zu, character %zu: tokenizer error\n", line, line_char); - error = 1; - return 0; - } - - switch (token) { - case NCD_EOF: - printf("eof\n"); - break; - case NCD_TOKEN_CURLY_OPEN: - printf("curly_open\n"); - break; - case NCD_TOKEN_CURLY_CLOSE: - printf("curly_close\n"); - break; - case NCD_TOKEN_ROUND_OPEN: - printf("round_open\n"); - break; - case NCD_TOKEN_ROUND_CLOSE: - printf("round_close\n"); - break; - case NCD_TOKEN_SEMICOLON: - printf("semicolon\n"); - break; - case NCD_TOKEN_DOT: - printf("dot\n"); - break; - case NCD_TOKEN_COMMA: - printf("comma\n"); - break; - case NCD_TOKEN_PROCESS: - printf("process\n"); - break; - case NCD_TOKEN_NAME: - printf("name %s\n", value); - free(value); - break; - case NCD_TOKEN_STRING: - printf("string %s\n", value); - free(value); - break; - case NCD_TOKEN_ARROW: - printf("arrow\n"); - break; - case NCD_TOKEN_TEMPLATE: - printf("template\n"); - break; - case NCD_TOKEN_COLON: - printf("colon\n"); - break; - case NCD_TOKEN_BRACKET_OPEN: - printf("bracket open\n"); - break; - case NCD_TOKEN_BRACKET_CLOSE: - printf("bracket close\n"); - break; - case NCD_TOKEN_IF: - printf("if\n"); - break; - case NCD_TOKEN_ELIF: - printf("elif\n"); - break; - case NCD_TOKEN_ELSE: - printf("else\n"); - break; - case NCD_TOKEN_FOREACH: - printf("foreach\n"); - break; - case NCD_TOKEN_AS: - printf("as\n"); - break; - case NCD_TOKEN_INCLUDE: - printf("include\n"); - break; - case NCD_TOKEN_INCLUDE_GUARD: - printf("include_guard\n"); - break; - default: - ASSERT(0); - } - - return 1; -} - -int main (int argc, char **argv) -{ - if (argc < 1) { - return 1; - } - - if (argc != 2) { - printf("Usage: %s <string>\n", argv[0]); - return 1; - } - - BLog_InitStdout(); - - error = 0; - - NCDConfigTokenizer_Tokenize(argv[1], strlen(argv[1]), tokenizer_output, NULL); - - if (error) { - return 1; - } - - return 0; -} diff --git a/external/badvpn_dns/examples/ncd_value_parser_test.c b/external/badvpn_dns/examples/ncd_value_parser_test.c deleted file mode 100644 index cf1915d..0000000 --- a/external/badvpn_dns/examples/ncd_value_parser_test.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file ncd_value_parser_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdio.h> -#include <string.h> - -#include <misc/debug.h> -#include <base/BLog.h> -#include <ncd/NCDValParser.h> -#include <ncd/NCDValGenerator.h> - -int main (int argc, char *argv[]) -{ - int res = 1; - - if (argc != 2) { - printf("Usage: %s <string>\n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - BLog_InitStdout(); - - NCDValMem mem; - NCDValMem_Init(&mem); - - // parse - NCDValRef val; - if (!NCDValParser_Parse(argv[1], strlen(argv[1]), &mem, &val)) { - DEBUG("NCDValParser_Parse failed"); - goto fail1; - } - - // generate value string - char *str = NCDValGenerator_Generate(val); - if (!str) { - DEBUG("NCDValGenerator_Generate failed"); - goto fail1; - } - - // print value string - printf("%s\n", str); - - res = 0; - - free(str); -fail1: - NCDValMem_Free(&mem); - BLog_Free(); -fail0: - return res; -} diff --git a/external/badvpn_dns/examples/ncdinterfacemonitor_test.c b/external/badvpn_dns/examples/ncdinterfacemonitor_test.c deleted file mode 100644 index 167f1bd..0000000 --- a/external/badvpn_dns/examples/ncdinterfacemonitor_test.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file ncdinterfacemonitor_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <inttypes.h> -#include <stdio.h> - -#include <misc/get_iface_info.h> -#include <misc/ipaddr6.h> -#include <misc/debug.h> -#include <base/BLog.h> -#include <system/BTime.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <ncd/extra/NCDInterfaceMonitor.h> - -BReactor reactor; -NCDInterfaceMonitor monitor; - -static void signal_handler (void *user); -static void monitor_handler (void *unused, struct NCDInterfaceMonitor_event event); -static void monitor_handler_error (void *unused); - -int main (int argc, char **argv) -{ - int ret = 1; - - if (argc != 2) { - fprintf(stderr, "Usage: %s <interface>\n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - int ifindex; - if (!badvpn_get_iface_info(argv[1], NULL, NULL, &ifindex)) { - DEBUG("get_iface_info failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - int watch_flags = NCDIFMONITOR_WATCH_LINK|NCDIFMONITOR_WATCH_IPV4_ADDR|NCDIFMONITOR_WATCH_IPV6_ADDR; - - if (!NCDInterfaceMonitor_Init(&monitor, ifindex, watch_flags, &reactor, NULL, monitor_handler, monitor_handler_error)) { - DEBUG("NCDInterfaceMonitor_Init failed"); - goto fail3; - } - - ret = BReactor_Exec(&reactor); - - NCDInterfaceMonitor_Free(&monitor); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 1); -} - -void monitor_handler (void *unused, struct NCDInterfaceMonitor_event event) -{ - switch (event.event) { - case NCDIFMONITOR_EVENT_LINK_UP: - case NCDIFMONITOR_EVENT_LINK_DOWN: { - const char *type = (event.event == NCDIFMONITOR_EVENT_LINK_UP) ? "up" : "down"; - printf("link %s\n", type); - } break; - - case NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED: - case NCDIFMONITOR_EVENT_IPV4_ADDR_REMOVED: { - const char *type = (event.event == NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED) ? "added" : "removed"; - uint8_t *addr = (uint8_t *)&event.u.ipv4_addr.addr; - printf("ipv4 addr %s %d.%d.%d.%d/%d\n", type, (int)addr[0], (int)addr[1], (int)addr[2], (int)addr[3], event.u.ipv4_addr.addr.prefix); - } break; - - case NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED: - case NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED: { - const char *type = (event.event == NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED) ? "added" : "removed"; - - char str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(event.u.ipv6_addr.addr.addr, str); - - int dynamic = !!(event.u.ipv6_addr.addr_flags & NCDIFMONITOR_ADDR_FLAG_DYNAMIC); - - printf("ipv6 addr %s %s/%d scope=%"PRIu8" dynamic=%d\n", type, str, event.u.ipv6_addr.addr.prefix, event.u.ipv6_addr.scope, dynamic); - } break; - - default: ASSERT(0); - } -} - -void monitor_handler_error (void *unused) -{ - DEBUG("monitor error"); - - BReactor_Quit(&reactor, 1); -} diff --git a/external/badvpn_dns/examples/ncdudevmanager_test.c b/external/badvpn_dns/examples/ncdudevmanager_test.c deleted file mode 100644 index 9bbb3fe..0000000 --- a/external/badvpn_dns/examples/ncdudevmanager_test.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file ncdudevmanager_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <system/BTime.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BUnixSignal.h> -#include <system/BProcess.h> -#include <system/BNetwork.h> -#include <udevmonitor/NCDUdevManager.h> - -BReactor reactor; -BUnixSignal usignal; -BProcessManager manager; -NCDUdevManager umanager; -NCDUdevClient client; - -static void signal_handler (void *user, int signo); -static void client_handler (void *unused, char *devpath, int have_map, BStringMap map); - -int main (int argc, char **argv) -{ - if (!(argc == 1 || (argc == 2 && !strcmp(argv[1], "--no-udev")))) { - fprintf(stderr, "Usage: %s [--no-udev]\n", (argc > 0 ? argv[0] : NULL)); - goto fail0; - } - - int no_udev = (argc == 2); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - if (!BUnixSignal_Init(&usignal, &reactor, set, signal_handler, NULL)) { - fprintf(stderr, "BUnixSignal_Init failed\n"); - goto fail2; - } - - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - NCDUdevManager_Init(&umanager, no_udev, &reactor, &manager); - - NCDUdevClient_Init(&client, &umanager, NULL, client_handler); - - BReactor_Exec(&reactor); - - NCDUdevClient_Free(&client); - - NCDUdevManager_Free(&umanager); - - BProcessManager_Free(&manager); -fail3: - BUnixSignal_Free(&usignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -static void signal_handler (void *user, int signo) -{ - if (signo == SIGHUP) { - fprintf(stderr, "received SIGHUP, restarting client\n"); - - NCDUdevClient_Free(&client); - NCDUdevClient_Init(&client, &umanager, NULL, client_handler); - } else { - fprintf(stderr, "received %s, exiting\n", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // exit event loop - BReactor_Quit(&reactor, 1); - } -} - -void client_handler (void *unused, char *devpath, int have_map, BStringMap map) -{ - printf("event %s\n", devpath); - - if (!have_map) { - printf(" no map\n"); - } else { - printf(" map:\n"); - - const char *name = BStringMap_First(&map); - while (name) { - printf(" %s=%s\n", name, BStringMap_Get(&map, name)); - name = BStringMap_Next(&map, name); - } - } - - const BStringMap *cache_map = NCDUdevManager_Query(&umanager, devpath); - if (!cache_map) { - printf(" no cache\n"); - } else { - printf(" cache:\n"); - - const char *name = BStringMap_First(cache_map); - while (name) { - printf(" %s=%s\n", name, BStringMap_Get(cache_map, name)); - name = BStringMap_Next(cache_map, name); - } - } - - if (have_map) { - BStringMap_Free(&map); - } - free(devpath); -} diff --git a/external/badvpn_dns/examples/ncdudevmonitor_test.c b/external/badvpn_dns/examples/ncdudevmonitor_test.c deleted file mode 100644 index 94b4f6f..0000000 --- a/external/badvpn_dns/examples/ncdudevmonitor_test.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file ncdudevmonitor_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <system/BTime.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BProcess.h> -#include <system/BNetwork.h> -#include <udevmonitor/NCDUdevMonitor.h> - -BReactor reactor; -BProcessManager manager; -NCDUdevMonitor monitor; - -static void signal_handler (void *user); -static void monitor_handler_event (void *unused); -static void monitor_handler_error (void *unused, int is_error); - -int main (int argc, char **argv) -{ - int ret = 1; - - if (argc < 2 || (strcmp(argv[1], "monitor_udev") && strcmp(argv[1], "monitor_kernel") && strcmp(argv[1], "info"))) { - fprintf(stderr, "Usage: %s <monitor_udev/monitor_kernel/info>\n", (argc > 0 ? argv[0] : NULL)); - goto fail0; - } - - int mode; - if (!strcmp(argv[1], "monitor_udev")) { - mode = NCDUDEVMONITOR_MODE_MONITOR_UDEV; - } else if (!strcmp(argv[1], "monitor_kernel")) { - mode = NCDUDEVMONITOR_MODE_MONITOR_KERNEL; - } else { - mode = NCDUDEVMONITOR_MODE_INFO; - } - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - if (!NCDUdevMonitor_Init(&monitor, &reactor, &manager, mode, NULL, - monitor_handler_event, - monitor_handler_error - )) { - DEBUG("NCDUdevMonitor_Init failed"); - goto fail4; - } - - ret = BReactor_Exec(&reactor); - - NCDUdevMonitor_Free(&monitor); -fail4: - BProcessManager_Free(&manager); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 1); -} - -void monitor_handler_event (void *unused) -{ - // accept event - NCDUdevMonitor_Done(&monitor); - - if (NCDUdevMonitor_IsReadyEvent(&monitor)) { - printf("ready\n"); - return; - } - - printf("event\n"); - - int num_props = NCDUdevMonitor_GetNumProperties(&monitor); - for (int i = 0; i < num_props; i++) { - const char *name; - const char *value; - NCDUdevMonitor_GetProperty(&monitor, i, &name, &value); - printf(" %s=%s\n", name, value); - } -} - -void monitor_handler_error (void *unused, int is_error) -{ - if (is_error) { - DEBUG("monitor error"); - } else { - DEBUG("monitor finished"); - } - - BReactor_Quit(&reactor, (is_error ? 1 : 0)); -} diff --git a/external/badvpn_dns/examples/ncdval_test.c b/external/badvpn_dns/examples/ncdval_test.c deleted file mode 100644 index 6933ed0..0000000 --- a/external/badvpn_dns/examples/ncdval_test.c +++ /dev/null @@ -1,380 +0,0 @@ -/** - * @file ncdval_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> - -#include <ncd/NCDVal.h> -#include <ncd/NCDStringIndex.h> -#include <ncd/static_strings.h> -#include <base/BLog.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/offset.h> - -#define FORCE(cmd) if (!(cmd)) { fprintf(stderr, "failed\n"); exit(1); } - -struct composed_string { - BRefTarget ref_target; - size_t length; - size_t chunk_size; - char **chunks; -}; - -static void composed_string_ref_target_func_release (BRefTarget *ref_target) -{ - struct composed_string *cs = UPPER_OBJECT(ref_target, struct composed_string, ref_target); - - size_t num_chunks = cs->length / cs->chunk_size; - if (cs->length % cs->chunk_size) { - num_chunks++; - } - - for (size_t i = 0; i < num_chunks; i++) { - BFree(cs->chunks[i]); - } - - BFree(cs->chunks); - BFree(cs); -} - -static void composed_string_func_getptr (void *user, size_t offset, const char **out_data, size_t *out_length) -{ - struct composed_string *cs = user; - ASSERT(offset < cs->length) - - *out_data = cs->chunks[offset / cs->chunk_size] + (offset % cs->chunk_size); - *out_length = cs->chunk_size - (offset % cs->chunk_size); -} - -static NCDValRef build_composed_string (NCDValMem *mem, const char *data, size_t length, size_t chunk_size) -{ - ASSERT(chunk_size > 0) - - struct composed_string *cs = BAlloc(sizeof(*cs)); - if (!cs) { - goto fail0; - } - - cs->length = length; - cs->chunk_size = chunk_size; - - size_t num_chunks = cs->length / cs->chunk_size; - if (cs->length % cs->chunk_size) { - num_chunks++; - } - - cs->chunks = BAllocArray(num_chunks, sizeof(cs->chunks[0])); - if (!cs->chunk_size) { - goto fail1; - } - - size_t i; - for (i = 0; i < num_chunks; i++) { - cs->chunks[i] = BAlloc(cs->chunk_size); - if (!cs->chunks[i]) { - goto fail2; - } - - size_t to_copy = length; - if (to_copy > cs->chunk_size) { - to_copy = cs->chunk_size; - } - - memcpy(cs->chunks[i], data, to_copy); - data += to_copy; - length -= to_copy; - } - - BRefTarget_Init(&cs->ref_target, composed_string_ref_target_func_release); - - NCDValComposedStringResource resource; - resource.func_getptr = composed_string_func_getptr; - resource.user = cs; - resource.ref_target = &cs->ref_target; - - NCDValRef val = NCDVal_NewComposedString(mem, resource, 0, cs->length); - BRefTarget_Deref(&cs->ref_target); - return val; - -fail2: - while (i-- > 0) { - BFree(cs->chunks[i]); - } - BFree(cs->chunks); -fail1: - BFree(cs); -fail0: - return NCDVal_NewInvalid(); -} - -static void test_string (NCDValRef str, const char *data, size_t length) -{ - FORCE( !NCDVal_IsInvalid(str) ) - FORCE( NCDVal_IsString(str) ) - FORCE( NCDVal_StringLength(str) == length ) - FORCE( NCDVal_StringHasNulls(str) == !!memchr(data, '\0', length) ) - FORCE( NCDVal_IsStringNoNulls(str) == !memchr(data, '\0', length) ) - FORCE( NCDVal_StringRegionEquals(str, 0, length, data) ) - - b_cstring cstr = NCDVal_StringCstring(str); - - for (size_t i = 0; i < length; i++) { - size_t chunk_length; - const char *chunk_data = b_cstring_get(cstr, i, length - i, &chunk_length); - - FORCE( chunk_length > 0 ) - FORCE( chunk_length <= length - i ) - FORCE( !memcmp(chunk_data, data + i, chunk_length) ) - FORCE( NCDVal_StringRegionEquals(str, i, chunk_length, data + i) ) - FORCE( b_cstring_memcmp(cstr, b_cstring_make_buf(data, length), i, i, chunk_length) == 0 ) - FORCE( b_cstring_memcmp(cstr, b_cstring_make_buf(data + i, length - i), i, 0, chunk_length) == 0 ) - } -} - -static void print_indent (int indent) -{ - for (int i = 0; i < indent; i++) { - printf(" "); - } -} - -static void print_value (NCDValRef val, unsigned int indent) -{ - switch (NCDVal_Type(val)) { - case NCDVAL_STRING: { - NCDValNullTermString nts; - FORCE( NCDVal_StringNullTerminate(val, &nts) ) - - print_indent(indent); - printf("string(%zu) %s\n", NCDVal_StringLength(val), nts.data); - - NCDValNullTermString_Free(&nts); - } break; - - case NCDVAL_LIST: { - size_t count = NCDVal_ListCount(val); - - print_indent(indent); - printf("list(%zu)\n", NCDVal_ListCount(val)); - - for (size_t i = 0; i < count; i++) { - NCDValRef elem_val = NCDVal_ListGet(val, i); - print_value(elem_val, indent + 1); - } - } break; - - case NCDVAL_MAP: { - print_indent(indent); - printf("map(%zu)\n", NCDVal_MapCount(val)); - - for (NCDValMapElem e = NCDVal_MapOrderedFirst(val); !NCDVal_MapElemInvalid(e); e = NCDVal_MapOrderedNext(val, e)) { - NCDValRef ekey = NCDVal_MapElemKey(val, e); - NCDValRef eval = NCDVal_MapElemVal(val, e); - - print_indent(indent + 1); - printf("key=\n"); - print_value(ekey, indent + 2); - - print_indent(indent + 1); - printf("val=\n"); - print_value(eval, indent + 2); - } - } break; - } -} - -int main () -{ - int res; - - BLog_InitStdout(); - - NCDStringIndex string_index; - FORCE( NCDStringIndex_Init(&string_index) ) - - // Some basic usage of values. - - NCDValMem mem; - NCDValMem_Init(&mem); - - NCDValRef s1 = NCDVal_NewString(&mem, "Hello World"); - test_string(s1, "Hello World", 11); - ASSERT( NCDVal_IsString(s1) ) - ASSERT( !NCDVal_IsIdString(s1) ) - ASSERT( NCDVal_Type(s1) == NCDVAL_STRING ) - - NCDValRef s2 = NCDVal_NewString(&mem, "This is reeeeeeeeeeeeeallllllllyyyyy fun!"); - FORCE( !NCDVal_IsInvalid(s2) ) - - NCDValRef l1 = NCDVal_NewList(&mem, 10); - FORCE( !NCDVal_IsInvalid(l1) ) - - FORCE( NCDVal_ListAppend(l1, s1) ) - FORCE( NCDVal_ListAppend(l1, s2) ) - - print_value(s1, 0); - print_value(s2, 0); - print_value(l1, 0); - - NCDValRef k1 = NCDVal_NewString(&mem, "K1"); - FORCE( !NCDVal_IsInvalid(k1) ) - NCDValRef v1 = NCDVal_NewString(&mem, "V1"); - FORCE( !NCDVal_IsInvalid(v1) ) - - NCDValRef k2 = NCDVal_NewString(&mem, "K2"); - FORCE( !NCDVal_IsInvalid(k2) ) - NCDValRef v2 = NCDVal_NewString(&mem, "V2"); - FORCE( !NCDVal_IsInvalid(v2) ) - - NCDValRef m1 = NCDVal_NewMap(&mem, 3); - FORCE( !NCDVal_IsInvalid(m1) ) - - FORCE( NCDVal_MapInsert(m1, k1, v1, &res) && res ) - FORCE( NCDVal_MapInsert(m1, k2, v2, &res) && res ) - - ASSERT( NCDVal_MapGetValue(m1, "K1").idx == v1.idx ) - ASSERT( NCDVal_MapGetValue(m1, "K2").idx == v2.idx ) - ASSERT( NCDVal_IsInvalid(NCDVal_MapGetValue(m1, "K3")) ) - - NCDValRef ids1 = NCDVal_NewIdString(&mem, NCD_STRING_ARG1, &string_index); - test_string(ids1, "_arg1", 5); - ASSERT( !memcmp(NCDVal_StringData(ids1), "_arg1", 5) ) - ASSERT( NCDVal_StringLength(ids1) == 5 ) - ASSERT( !NCDVal_StringHasNulls(ids1) ) - ASSERT( NCDVal_StringEquals(ids1, "_arg1") ) - ASSERT( NCDVal_Type(ids1) == NCDVAL_STRING ) - ASSERT( NCDVal_IsIdString(ids1) ) - - NCDValRef ids2 = NCDVal_NewIdString(&mem, NCD_STRING_ARG2, &string_index); - test_string(ids2, "_arg2", 5); - ASSERT( !memcmp(NCDVal_StringData(ids2), "_arg2", 5) ) - ASSERT( NCDVal_StringLength(ids2) == 5 ) - ASSERT( !NCDVal_StringHasNulls(ids2) ) - ASSERT( NCDVal_StringEquals(ids2, "_arg2") ) - ASSERT( NCDVal_Type(ids2) == NCDVAL_STRING ) - ASSERT( NCDVal_IsIdString(ids2) ) - - FORCE( NCDVal_MapInsert(m1, ids1, ids2, &res) && res ) - - ASSERT( NCDVal_MapGetValue(m1, "_arg1").idx == ids2.idx ) - - print_value(m1, 0); - - NCDValRef copy = NCDVal_NewCopy(&mem, m1); - FORCE( !NCDVal_IsInvalid(copy) ) - ASSERT( NCDVal_Compare(copy, m1) == 0 ) - - NCDValMem_Free(&mem); - - // Try to make copies of a string within the same memory object. - // This is an evil test because we cannot simply copy a string using e.g. - // NCDVal_NewStringBin() - it requires that the buffer passed - // be outside the memory object of the new string. - // We use NCDVal_NewCopy(), which takes care of this by creating - // an uninitialized string using NCDVal_NewStringUninitialized() and - // then copyng the data. - - NCDValMem_Init(&mem); - - NCDValRef s[100]; - - s[0] = NCDVal_NewString(&mem, "Eeeeeeeeeeeevil."); - FORCE( !NCDVal_IsInvalid(s[0]) ) - - for (int i = 1; i < 100; i++) { - s[i] = NCDVal_NewCopy(&mem, s[i - 1]); - FORCE( !NCDVal_IsInvalid(s[i]) ) - ASSERT( NCDVal_StringEquals(s[i - 1], "Eeeeeeeeeeeevil.") ) - ASSERT( NCDVal_StringEquals(s[i], "Eeeeeeeeeeeevil.") ) - } - - for (int i = 0; i < 100; i++) { - ASSERT( NCDVal_StringEquals(s[i], "Eeeeeeeeeeeevil.") ) - } - - NCDValMem_Free(&mem); - - NCDValMem_Init(&mem); - - NCDValRef cstr1 = build_composed_string(&mem, "Hello World", 11, 3); - test_string(cstr1, "Hello World", 11); - FORCE( NCDVal_IsComposedString(cstr1) ) - FORCE( !NCDVal_IsContinuousString(cstr1) ) - FORCE( NCDVal_StringEquals(cstr1, "Hello World") ) - FORCE( !NCDVal_StringEquals(cstr1, "Hello World ") ) - FORCE( !NCDVal_StringEquals(cstr1, "Hello WorlD") ) - - NCDValRef cstr2 = build_composed_string(&mem, "GoodBye", 7, 1); - test_string(cstr2, "GoodBye", 7); - FORCE( NCDVal_IsComposedString(cstr2) ) - FORCE( !NCDVal_IsContinuousString(cstr2) ) - FORCE( NCDVal_StringEquals(cstr2, "GoodBye") ) - FORCE( !NCDVal_StringEquals(cstr2, " GoodBye") ) - FORCE( !NCDVal_StringEquals(cstr2, "goodBye") ) - - NCDValRef cstr3 = build_composed_string(&mem, "Bad\x00String", 10, 4); - test_string(cstr3, "Bad\x00String", 10); - FORCE( NCDVal_IsComposedString(cstr3) ) - FORCE( !NCDVal_IsContinuousString(cstr3) ) - - FORCE( NCDVal_StringMemCmp(cstr1, cstr2, 1, 2, 3) < 0 ) - FORCE( NCDVal_StringMemCmp(cstr1, cstr2, 7, 1, 4) > 0 ) - - char buf[10]; - NCDVal_StringCopyOut(cstr1, 1, 10, buf); - FORCE( !memcmp(buf, "ello World", 10) ) - - NCDValRef clist1 = NCDVal_NewList(&mem, 3); - FORCE( !NCDVal_IsInvalid(clist1) ) - FORCE( NCDVal_ListAppend(clist1, cstr1) ) - FORCE( NCDVal_ListAppend(clist1, cstr2) ) - FORCE( NCDVal_ListAppend(clist1, cstr3) ) - FORCE( NCDVal_ListCount(clist1) == 3 ) - - FORCE( NCDValMem_ConvertNonContinuousStrings(&mem, &clist1) ) - FORCE( NCDVal_ListCount(clist1) == 3 ) - - NCDValRef fixed_str1 = NCDVal_ListGet(clist1, 0); - NCDValRef fixed_str2 = NCDVal_ListGet(clist1, 1); - NCDValRef fixed_str3 = NCDVal_ListGet(clist1, 2); - - FORCE( NCDVal_IsContinuousString(fixed_str1) ) - FORCE( NCDVal_IsContinuousString(fixed_str2) ) - FORCE( NCDVal_IsContinuousString(fixed_str3) ) - - test_string(fixed_str1, "Hello World", 11); - test_string(fixed_str2, "GoodBye", 7); - test_string(fixed_str3, "Bad\x00String", 10); - - NCDValMem_Free(&mem); - - NCDStringIndex_Free(&string_index); - - return 0; -} diff --git a/external/badvpn_dns/examples/ncdvalcons_test.c b/external/badvpn_dns/examples/ncdvalcons_test.c deleted file mode 100644 index 7a876ed..0000000 --- a/external/badvpn_dns/examples/ncdvalcons_test.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file ncdvalcons_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <ncd/NCDValCons.h> -#include <ncd/NCDValGenerator.h> - -static NCDValMem mem; -static NCDValCons cons; - -static NCDValConsVal make_string (const char *data) -{ - NCDValConsVal val; - int error; - int res = NCDValCons_NewString(&cons, (const uint8_t *)data, strlen(data), &val, &error); - ASSERT_FORCE(res) - return val; -} - -static NCDValConsVal make_list (void) -{ - NCDValConsVal val; - NCDValCons_NewList(&cons, &val); - return val; -} - -static NCDValConsVal make_map (void) -{ - NCDValConsVal val; - NCDValCons_NewMap(&cons, &val); - return val; -} - -static NCDValConsVal list_prepend (NCDValConsVal list, NCDValConsVal elem) -{ - int error; - int res = NCDValCons_ListPrepend(&cons, &list, elem, &error); - ASSERT_FORCE(res) - return list; -} - -static NCDValConsVal map_insert (NCDValConsVal map, NCDValConsVal key, NCDValConsVal value) -{ - int error; - int res = NCDValCons_MapInsert(&cons, &map, key, value, &error); - ASSERT_FORCE(res) - return map; -} - -static NCDValRef complete (NCDValConsVal cval) -{ - int error; - NCDValRef val; - int res = NCDValCons_Complete(&cons, cval, &val, &error); - ASSERT_FORCE(res) - return val; -} - -int main () -{ - NCDValMem_Init(&mem); - - int res = NCDValCons_Init(&cons, &mem); - ASSERT_FORCE(res) - - NCDValRef val1 = complete(list_prepend(list_prepend(list_prepend(make_list(), make_string("hello")), make_string("world")), make_list())); - char *str1 = NCDValGenerator_Generate(val1); - ASSERT_FORCE(str1) - ASSERT_FORCE(!strcmp(str1, "{{}, \"world\", \"hello\"}")) - free(str1); - - NCDValRef val2 = complete(map_insert(map_insert(map_insert(make_map(), make_list(), make_list()), make_string("A"), make_list()), make_string("B"), make_list())); - char *str2 = NCDValGenerator_Generate(val2); - ASSERT_FORCE(str2) - printf("%s\n", str2); - ASSERT_FORCE(!strcmp(str2, "[\"A\":{}, \"B\":{}, {}:{}]")) - free(str2); - - NCDValCons_Free(&cons); - NCDValMem_Free(&mem); - return 0; -} diff --git a/external/badvpn_dns/examples/parse_number_test.c b/external/badvpn_dns/examples/parse_number_test.c deleted file mode 100644 index d393c3f..0000000 --- a/external/badvpn_dns/examples/parse_number_test.c +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file parse_number_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <inttypes.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <time.h> - -#include <misc/parse_number.h> -#include <misc/debug.h> - -static void test_random (int num_digits, int digit_modulo) -{ - ASSERT(num_digits > 0); - ASSERT(digit_modulo > 0); - - uint8_t digits[40]; - - for (int i = 0; i < num_digits; i++) { - digits[i] = '0' + (rand() % digit_modulo); - } - digits[num_digits] = '\0'; - - char *endptr; - uintmax_t std_num = strtoumax((const char *)digits, &endptr, 10); - int std_res = !*endptr && !(std_num == UINTMAX_MAX && errno == ERANGE); - - uintmax_t num = 0; - int res = parse_unsigned_integer_bin((const char *)digits, num_digits, &num); - - if (res != std_res) { - printf("fail1 %s\n", (const char *)digits); - ASSERT_FORCE(0); - } - - if (res && num != std_num) { - printf("fail2 %s\n", (const char *)digits); - ASSERT_FORCE(0); - } - - if (res) { - uint8_t *nozero_digits = digits; - while (*nozero_digits == '0' && nozero_digits != &digits[num_digits - 1]) { - nozero_digits++; - } - - char buf[40]; - int size = compute_decimal_repr_size(num); - generate_decimal_repr(num, buf, size); - buf[size] = '\0'; - ASSERT_FORCE(!strcmp(buf, (const char *)nozero_digits)); - } -} - -static void test_value (uintmax_t x) -{ - char str[40]; - sprintf(str, "%" PRIuMAX, x); - uintmax_t y; - int res = parse_unsigned_integer_bin(str, strlen(str), &y); - ASSERT_FORCE(res); - ASSERT_FORCE(y == x); - - char str2[40]; - int size = compute_decimal_repr_size(x); - generate_decimal_repr(x, str2, size); - str2[size] = '\0'; - - ASSERT_FORCE(!strcmp(str2, str)); -} - -static void test_value_range (uintmax_t start, uintmax_t count) -{ - uintmax_t i = start; - do { - test_value(i); - i++; - } while (i != start + count); -} - -int main () -{ - srand(time(NULL)); - - for (int num_digits = 1; num_digits <= 22; num_digits++) { - for (int i = 0; i < 1000000; i++) { - test_random(num_digits, 10); - } - for (int i = 0; i < 1000000; i++) { - test_random(num_digits, 11); - } - } - - test_value_range(UINTMAX_C(0), 5000000); - test_value_range(UINTMAX_C(100000000), 5000000); - test_value_range(UINTMAX_C(258239003), 5000000); - test_value_range(UINTMAX_C(8241096180752634), 5000000); - test_value_range(UINTMAX_C(9127982390882308083), 5000000); - test_value_range(UINTMAX_C(18446744073700000000), 20000000); - - return 0; -} diff --git a/external/badvpn_dns/examples/predicate_test.c b/external/badvpn_dns/examples/predicate_test.c deleted file mode 100644 index 324a960..0000000 --- a/external/badvpn_dns/examples/predicate_test.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file predicate_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> - -#include <predicate/BPredicate.h> -#include <base/BLog.h> - -static int func_hello (void *user, void **args) -{ - return 1; -} - -static int func_neg (void *user, void **args) -{ - int arg = *((int *)args[0]); - - return !arg; -} - -static int func_conj (void *user, void **args) -{ - int arg1 = *((int *)args[0]); - int arg2 = *((int *)args[1]); - - return (arg1 && arg2); -} - -static int func_strcmp (void *user, void **args) -{ - char *arg1 = (char *)args[0]; - char *arg2 = (char *)args[1]; - - return (!strcmp(arg1, arg2)); -} - -static int func_error (void *user, void **args) -{ - return -1; -} - -int main (int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: %s <predicate>\n", argv[0]); - return 1; - } - - // init logger - BLog_InitStdout(); - - // init predicate - BPredicate pr; - if (!BPredicate_Init(&pr, argv[1])) { - fprintf(stderr, "BPredicate_Init failed\n"); - return 1; - } - - // init functions - BPredicateFunction f_hello; - BPredicateFunction_Init(&f_hello, &pr, "hello", NULL, 0, func_hello, NULL); - int arr1[] = {PREDICATE_TYPE_BOOL}; - BPredicateFunction f_neg; - BPredicateFunction_Init(&f_neg, &pr, "neg", arr1, 1, func_neg, NULL); - int arr2[] = {PREDICATE_TYPE_BOOL, PREDICATE_TYPE_BOOL}; - BPredicateFunction f_conj; - BPredicateFunction_Init(&f_conj, &pr, "conj", arr2, 2, func_conj, NULL); - int arr3[] = {PREDICATE_TYPE_STRING, PREDICATE_TYPE_STRING}; - BPredicateFunction f_strcmp; - BPredicateFunction_Init(&f_strcmp, &pr, "strcmp", arr3, 2, func_strcmp, NULL); - BPredicateFunction f_error; - BPredicateFunction_Init(&f_error, &pr, "error", NULL, 0, func_error, NULL); - - // evaluate - int result = BPredicate_Eval(&pr); - printf("%d\n", result); - - // free functions - BPredicateFunction_Free(&f_hello); - BPredicateFunction_Free(&f_neg); - BPredicateFunction_Free(&f_conj); - BPredicateFunction_Free(&f_strcmp); - BPredicateFunction_Free(&f_error); - - // free predicate - BPredicate_Free(&pr); - - return 0; -} diff --git a/external/badvpn_dns/examples/savl_test.c b/external/badvpn_dns/examples/savl_test.c deleted file mode 100644 index 18cf191..0000000 --- a/external/badvpn_dns/examples/savl_test.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file savl_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <structure/SAvl.h> -#include <security/BRandom.h> - -struct mynode; - -#include "savl_test_tree.h" -#include <structure/SAvl_decl.h> - -struct mynode { - int used; - int num; - MyTreeNode tree_node; -}; - -#include "savl_test_tree.h" -#include <structure/SAvl_impl.h> - -static void verify (MyTree *tree) -{ - printf("Verifying...\n"); - MyTree_Verify(tree, 0); -} - -int main (int argc, char **argv) -{ - int num_nodes; - int num_random_delete; - - if (argc != 3 || (num_nodes = atoi(argv[1])) <= 0 || (num_random_delete = atoi(argv[2])) < 0) { - fprintf(stderr, "Usage: %s <num> <numrandomdelete>\n", (argc > 0 ? argv[0] : NULL)); - return 1; - } - - struct mynode *nodes = (struct mynode *)BAllocArray(num_nodes, sizeof(*nodes)); - ASSERT_FORCE(nodes) - - int *values_ins = (int *)BAllocArray(num_nodes, sizeof(int)); - ASSERT_FORCE(values_ins) - - int *values = (int *)BAllocArray(num_random_delete, sizeof(int)); - ASSERT_FORCE(values) - - MyTree tree; - MyTree_Init(&tree); - verify(&tree); - - printf("Inserting random values...\n"); - int inserted = 0; - BRandom_randomize((uint8_t *)values_ins, num_nodes * sizeof(int)); - for (int i = 0; i < num_nodes; i++) { - nodes[i].num = values_ins[i]; - if (MyTree_Insert(&tree, 0, &nodes[i], NULL)) { - nodes[i].used = 1; - inserted++; - } else { - nodes[i].used = 0; - printf("Insert collision!\n"); - } - } - printf("Inserted %d entries\n", inserted); - ASSERT_FORCE(MyTree_Count(&tree, 0) == inserted) - verify(&tree); - - printf("Removing random entries...\n"); - int removed1 = 0; - BRandom_randomize((uint8_t *)values, num_random_delete * sizeof(int)); - for (int i = 0; i < num_random_delete; i++) { - int index = (((unsigned int *)values)[i] % num_nodes); - struct mynode *node = nodes + index; - if (node->used) { - MyTree_Remove(&tree, 0, node); - node->used = 0; - removed1++; - } - } - printf("Removed %d entries\n", removed1); - ASSERT_FORCE(MyTree_Count(&tree, 0) == inserted - removed1) - verify(&tree); - - printf("Removing remaining...\n"); - int removed2 = 0; - while (!MyTree_IsEmpty(&tree)) { - struct mynode *node = MyTree_GetFirst(&tree, 0); - ASSERT_FORCE(node->used) - MyTree_Remove(&tree, 0, node); - node->used = 0; - removed2++; - } - printf("Removed %d entries\n", removed2); - ASSERT_FORCE(MyTree_IsEmpty(&tree)) - ASSERT_FORCE(removed1 + removed2 == inserted) - ASSERT_FORCE(MyTree_Count(&tree, 0) == 0) - verify(&tree); - - BFree(nodes); - BFree(values_ins); - BFree(values); - - return 0; -} diff --git a/external/badvpn_dns/examples/savl_test_tree.h b/external/badvpn_dns/examples/savl_test_tree.h deleted file mode 100644 index 41964e9..0000000 --- a/external/badvpn_dns/examples/savl_test_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME MyTree -#define SAVL_PARAM_FEATURE_COUNTS 1 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct mynode -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_TYPE_COUNT int -#define SAVL_PARAM_VALUE_COUNT_MAX INT_MAX -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->num, (entry2)->num) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/external/badvpn_dns/examples/stdin_input.c b/external/badvpn_dns/examples/stdin_input.c deleted file mode 100644 index 8ff752c..0000000 --- a/external/badvpn_dns/examples/stdin_input.c +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @file stdin_input.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Example program which reads stdin and waits for SIGINT and SIGTERM. - */ - -#include <stdio.h> -#include <stddef.h> - -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> -#include <system/BConnection.h> -#include <system/BUnixSignal.h> - -#define BUF_SIZE 64 - -BReactor reactor; -BConnection pipe_con; -BUnixSignal usignal; -StreamRecvInterface *source_if; -uint8_t buf[BUF_SIZE + 1]; - -static void signal_handler (void *user, int signo) -{ - fprintf(stderr, "received %s, exiting\n", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // exit event loop - BReactor_Quit(&reactor, 1); -} - -static void connection_handler (void *user, int event) -{ - if (event == BCONNECTION_EVENT_RECVCLOSED) { - fprintf(stderr, "pipe closed\n"); - } else { - fprintf(stderr, "pipe error\n"); - } - - // exit event loop - BReactor_Quit(&reactor, (event == BCONNECTION_EVENT_RECVCLOSED ? 0 : 1)); -} - -static void input_handler_done (void *user, int data_len) -{ - // receive next chunk - StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE); - - // print this chunk - buf[data_len] = '\0'; - printf("Received: '%s'\n", buf); -} - -int main () -{ - int ret = 1; - - BLog_InitStdout(); - - // init network - if (!BNetwork_GlobalInit()) { - fprintf(stderr, "BNetwork_GlobalInit failed\n"); - goto fail1; - } - - // init reactor (event loop) - if (!BReactor_Init(&reactor)) { - fprintf(stderr, "BReactor_Init failed\n"); - goto fail1; - } - - // init signal handling - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - if (!BUnixSignal_Init(&usignal, &reactor, set, signal_handler, NULL)) { - fprintf(stderr, "BUnixSignal_Init failed\n"); - goto fail2; - } - - // init BConnection object backed by the stdin fd - if (!BConnection_Init(&pipe_con, BConnection_source_pipe(0), &reactor, NULL, connection_handler)) { - fprintf(stderr, "BConnection_Init failed\n"); - goto fail3; - } - - // init connection receive interface - BConnection_RecvAsync_Init(&pipe_con); - source_if = BConnection_RecvAsync_GetIf(&pipe_con); - - // init receive done callback - StreamRecvInterface_Receiver_Init(source_if, input_handler_done, NULL); - - // receive first chunk - StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE); - - // run event loop - ret = BReactor_Exec(&reactor); - - BConnection_RecvAsync_Free(&pipe_con); - BConnection_Free(&pipe_con); -fail3: - BUnixSignal_Free(&usignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); - DebugObjectGlobal_Finish(); - return ret; -} diff --git a/external/badvpn_dns/examples/substring_test.c b/external/badvpn_dns/examples/substring_test.c deleted file mode 100644 index 4a4b6c8..0000000 --- a/external/badvpn_dns/examples/substring_test.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - * @file substring_test.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <time.h> - -#include <misc/substring.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/print_macros.h> - -static int find_substring_slow (const char *str, size_t str_len, const char *sub, size_t sub_len, size_t *out_pos) -{ - ASSERT(sub_len > 0) - - if (str_len < sub_len) { - return 0; - } - - for (size_t i = 0; i <= str_len - sub_len; i++) { - if (!memcmp(str + i, sub, sub_len)) { - *out_pos = i; - return 1; - } - } - - return 0; -} - -static void print_data (const char *str, size_t str_len) -{ - while (str_len > 0) { - printf("%02"PRIx8" ", (uint8_t)(*str)); - str++; - str_len--; - } - printf("\n"); -} - -static void print_table (const size_t *table, size_t len) -{ - for (size_t i = 1; i < len; i++) { - printf("%zu ", table[i]); - } - printf("\n"); -} - -static void test_tables (int len, int count) -{ - ASSERT(len > 0) - ASSERT(count >= 0) - - char *word = (char *)BAllocSize(bsize_fromint(len)); - ASSERT_FORCE(word) - - size_t *table = (size_t *)BAllocSize(bsize_mul(bsize_fromint(len), bsize_fromsize(sizeof(table[0])))); - ASSERT_FORCE(table) - - for (int i = 0; i < count; i++) { - for (int j = 0; j < len; j++) { - word[j] = rand() % 2; - } - - build_substring_backtrack_table(word, len, table); - - for (int j = 1; j < len; j++) { - for (int k = j - 1; k >= 0; k--) { - if (!memcmp(word + j - k, word, k)) { - ASSERT_FORCE(table[j] == k) - break; - } - } - } - } - - BFree(table); - BFree(word); -} - -static void test_substring (int word_len, int text_len, int word_count, int text_count) -{ - assert(word_len > 0); - assert(text_len >= 0); - assert(word_count >= 0); - assert(text_count >= 0); - - char *word = (char *)BAllocSize(bsize_fromint(word_len)); - ASSERT_FORCE(word) - - size_t *table = (size_t *)BAllocSize(bsize_mul(bsize_fromint(word_len), bsize_fromsize(sizeof(table[0])))); - ASSERT_FORCE(table) - - char *text = (char *)BAllocSize(bsize_fromint(text_len)); - ASSERT_FORCE(text) - - for (int i = 0; i < word_count; i++) { - for (int j = 0; j < word_len; j++) { - word[j] = rand() % 2; - } - - build_substring_backtrack_table(word, word_len, table); - - for (int j = 0; j < text_count; j++) { - for (int k = 0; k < text_len; k++) { - text[k] = rand() % 2; - } - - size_t pos = 36; // to remove warning - int res = find_substring(text, text_len, word, word_len, table, &pos); - - size_t spos = 59; // to remove warning - int sres = find_substring_slow(text, text_len, word, word_len, &spos); - - ASSERT_FORCE(res == sres) - if (res) { - ASSERT_FORCE(pos == spos) - } - } - } - - BFree(text); - BFree(table); - BFree(word); -} - -int main (int argc, char *argv[]) -{ - if (argc != 7) { - printf("Usage: %s <tables length> <tables count> <word len> <text len> <word count> <text count>\n", (argc == 0 ? "" : argv[0])); - return 1; - } - - int tables_len = atoi(argv[1]); - int tables_count = atoi(argv[2]); - int word_len = atoi(argv[3]); - int text_len = atoi(argv[4]); - int word_count = atoi(argv[5]); - int text_count = atoi(argv[6]); - - if (tables_len <= 0 || tables_count < 0 || word_len <= 0 || text_len < 0 || word_count < 0 || text_count < 0) { - printf("Bad arguments.\n"); - return 1; - } - - srand(time(NULL)); - - test_tables(tables_len, tables_count); - - test_substring(word_len, text_len, word_count, text_count); - - { - char text[] = "aggagaa"; - char word[] = "aga"; - size_t table[sizeof(word) - 1]; - build_substring_backtrack_table(word, strlen(word), table); - - size_t pos; - int res = find_substring(text, strlen(text), word, strlen(word), table, &pos); - ASSERT_FORCE(res) - ASSERT_FORCE(pos == 3) - } - - { - char text[] = "aagagga"; - char word[] = "aga"; - size_t table[sizeof(word) - 1]; - build_substring_backtrack_table_reverse(word, strlen(word), table); - - size_t pos; - int res = find_substring_reverse(text, strlen(text), word, strlen(word), table, &pos); - ASSERT_FORCE(res) - ASSERT_FORCE(pos == 1) - } - - return 0; -} diff --git a/external/badvpn_dns/fix_flex.php b/external/badvpn_dns/fix_flex.php deleted file mode 100644 index bd026d0..0000000 --- a/external/badvpn_dns/fix_flex.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -$filename = $argv[1]; -$contents = file_get_contents($filename); -if ($contents === FALSE) exit(1); -$search = array("<inttypes.h>", "#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L"); -$replace = array("<stdint.h>", "#if 1"); -$contents = str_replace($search, $replace, $contents); -$res = file_put_contents($filename, $contents); -if ($res === FALSE) exit(1); diff --git a/external/badvpn_dns/flooder/CMakeLists.txt b/external/badvpn_dns/flooder/CMakeLists.txt deleted file mode 100644 index 36253ab..0000000 --- a/external/badvpn_dns/flooder/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_executable(badvpn-flooder flooder.c) -target_link_libraries(badvpn-flooder system flow server_conection ${NSPR_LIBRARIES} ${NSS_LIBRARIES}) - -install( - TARGETS badvpn-flooder - RUNTIME DESTINATION bin -) diff --git a/external/badvpn_dns/flooder/flooder.c b/external/badvpn_dns/flooder/flooder.c deleted file mode 100644 index 1f3f05c..0000000 --- a/external/badvpn_dns/flooder/flooder.c +++ /dev/null @@ -1,671 +0,0 @@ -/** - * @file flooder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <protocol/addr.h> -#include <protocol/scproto.h> -#include <misc/loglevel.h> -#include <misc/version.h> -#include <misc/nsskey.h> -#include <misc/byteorder.h> -#include <misc/loggers_string.h> -#include <misc/open_standard_streams.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BNetwork.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketProtoEncoder.h> -#include <nspr_support/BSSLConnection.h> -#include <server_connection/ServerConnection.h> - -#ifndef BADVPN_USE_WINAPI -#include <base/BLog_syslog.h> -#endif - -#include <flooder/flooder.h> - -#include <generated/blog_channel_flooder.h> - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -// command-line options -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - int ssl; - char *nssdb; - char *client_cert_name; - char *server_name; - char *server_addr; - peerid_t floods[MAX_FLOODS]; - int num_floods; -} options; - -// server address we connect to -BAddr server_addr; - -// server name to use for SSL -char server_name[256]; - -// reactor -BReactor ss; - -// client certificate if using SSL -CERTCertificate *client_cert; - -// client private key if using SSL -SECKEYPrivateKey *client_key; - -// server connection -ServerConnection server; - -// whether server is ready -int server_ready; - -// my ID, defined only after server_ready -peerid_t my_id; - -// flooding output -PacketRecvInterface flood_source; -PacketProtoEncoder flood_encoder; -SinglePacketBuffer flood_buffer; - -// whether we were asked for a packet and blocked -int flood_blocking; - -// index of next peer to send packet too -int flood_next; - -/** - * Cleans up everything that can be cleaned up from inside the event loop. - */ -static void terminate (void); - -/** - * Prints command line help. - */ -static void print_help (const char *name); - -/** - * Prints program name, version and copyright notice. - */ -static void print_version (void); - -/** - * Parses command line options into the options strucute. - * - * @return 1 on success, 0 on failure - */ -static int parse_arguments (int argc, char *argv[]); - -/** - * Processes command line options. - * - * @return 1 on success, 0 on failure - */ -static int resolve_arguments (void); - -/** - * Handler invoked when program termination is requested. - */ -static void signal_handler (void *unused); - -static void server_handler_error (void *user); -static void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip); -static void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len); -static void server_handler_endclient (void *user, peerid_t peer_id); -static void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len); - -static void flood_source_handler_recv (void *user, uint8_t *data); - -int main (int argc, char *argv[]) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // init time - BTime_Init(); - - // resolve addresses - if (!resolve_arguments()) { - BLog(BLOG_ERROR, "Failed to resolve arguments"); - goto fail1; - } - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail1a; - } - - if (options.ssl) { - // init NSPR - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - // register local NSPR file types - if (!BSSLConnection_GlobalInit()) { - BLog(BLOG_ERROR, "BSSLConnection_GlobalInit failed"); - goto fail3; - } - - // init NSS - if (NSS_Init(options.nssdb) != SECSuccess) { - BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError()); - goto fail2; - } - - // set cipher policy - if (NSS_SetDomesticPolicy() != SECSuccess) { - BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError()); - goto fail3; - } - - // init server cache - if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError()); - goto fail3; - } - - // open server certificate and private key - if (!open_nss_cert_and_key(options.client_cert_name, &client_cert, &client_key)) { - BLog(BLOG_ERROR, "Cannot open certificate and key"); - goto fail4; - } - } - - // start connecting to server - if (!ServerConnection_Init( - &server, &ss, NULL, server_addr, SC_KEEPALIVE_INTERVAL, SERVER_BUFFER_MIN_PACKETS, options.ssl, 0, client_cert, client_key, server_name, NULL, - server_handler_error, server_handler_ready, server_handler_newclient, server_handler_endclient, server_handler_message - )) { - BLog(BLOG_ERROR, "ServerConnection_Init failed"); - goto fail5; - } - - // set server not ready - server_ready = 0; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - if (server_ready) { - ServerConnection_ReleaseBuffers(&server); - SinglePacketBuffer_Free(&flood_buffer); - PacketProtoEncoder_Free(&flood_encoder); - PacketRecvInterface_Free(&flood_source); - } - - ServerConnection_Free(&server); -fail5: - if (options.ssl) { - CERT_DestroyCertificate(client_cert); - SECKEY_DestroyPrivateKey(client_key); -fail4: - ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess) -fail3: - SSL_ClearSessionCache(); - ASSERT_FORCE(NSS_Shutdown() == SECSuccess) -fail2: - ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS) - PL_ArenaFinish(); - } - - BSignal_Finish(); -fail1a: - BReactor_Free(&ss); -fail1: - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void terminate (void) -{ - BLog(BLOG_NOTICE, "tearing down"); - - // exit event loop - BReactor_Quit(&ss, 0); -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--ssl --nssdb <string> --client-cert-name <string>]\n" - " [--server-name <string>]\n" - " --server-addr <addr>\n" - " [--flood-id <id>] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.ssl = 0; - options.nssdb = NULL; - options.client_cert_name = NULL; - options.server_name = NULL; - options.server_addr = NULL; - options.num_floods = 0; - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--ssl")) { - options.ssl = 1; - } - else if (!strcmp(arg, "--nssdb")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.nssdb = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--client-cert-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.client_cert_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--flood-id")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_floods == MAX_FLOODS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.floods[options.num_floods] = atoi(argv[i + 1]); - options.num_floods++; - i++; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (options.ssl != !!options.nssdb) { - fprintf(stderr, "False: --ssl <=> --nssdb\n"); - return 0; - } - - if (options.ssl != !!options.client_cert_name) { - fprintf(stderr, "False: --ssl <=> --client-cert-name\n"); - return 0; - } - - if (!options.server_addr) { - fprintf(stderr, "False: --server-addr\n"); - return 0; - } - - return 1; -} - -int resolve_arguments (void) -{ - // resolve server address - ASSERT(options.server_addr) - if (!BAddr_Parse(&server_addr, options.server_addr, server_name, sizeof(server_name))) { - BLog(BLOG_ERROR, "server addr: BAddr_Parse failed"); - return 0; - } - if (!addr_supported(server_addr)) { - BLog(BLOG_ERROR, "server addr: not supported"); - return 0; - } - - // override server name if requested - if (options.server_name) { - if (strlen(options.server_name) >= sizeof(server_name)) { - BLog(BLOG_ERROR, "server name: too long"); - return 0; - } - strcpy(server_name, options.server_name); - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - terminate(); -} - -void server_handler_error (void *user) -{ - BLog(BLOG_ERROR, "server connection failed, exiting"); - - terminate(); -} - -void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip) -{ - ASSERT(!server_ready) - - // remember our ID - my_id = param_my_id; - - // init flooding - - // init source - PacketRecvInterface_Init(&flood_source, SC_MAX_ENC, flood_source_handler_recv, NULL, BReactor_PendingGroup(&ss)); - - // init encoder - PacketProtoEncoder_Init(&flood_encoder, &flood_source, BReactor_PendingGroup(&ss)); - - // init buffer - if (!SinglePacketBuffer_Init(&flood_buffer, PacketProtoEncoder_GetOutput(&flood_encoder), ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed, exiting"); - goto fail1; - } - - // set not blocking - flood_blocking = 0; - - // set server ready - server_ready = 1; - - BLog(BLOG_INFO, "server: ready, my ID is %d", (int)my_id); - - return; - -fail1: - PacketProtoEncoder_Free(&flood_encoder); - PacketRecvInterface_Free(&flood_source); - terminate(); -} - -void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - - BLog(BLOG_INFO, "newclient %d", (int)peer_id); -} - -void server_handler_endclient (void *user, peerid_t peer_id) -{ - ASSERT(server_ready) - - BLog(BLOG_INFO, "endclient %d", (int)peer_id); -} - -void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len) -{ - ASSERT(server_ready) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - BLog(BLOG_INFO, "message from %d", (int)peer_id); -} - -void flood_source_handler_recv (void *user, uint8_t *data) -{ - ASSERT(server_ready) - ASSERT(!flood_blocking) - if (options.num_floods > 0) { - ASSERT(flood_next >= 0) - ASSERT(flood_next < options.num_floods) - } - - if (options.num_floods == 0) { - flood_blocking = 1; - return; - } - - peerid_t peer_id = options.floods[flood_next]; - flood_next = (flood_next + 1) % options.num_floods; - - BLog(BLOG_INFO, "message to %d", (int)peer_id); - - struct sc_header header; - header.type = SCID_OUTMSG; - memcpy(data, &header, sizeof(header)); - - struct sc_client_outmsg omsg; - omsg.clientid = htol16(peer_id); - memcpy(data + sizeof(header), &omsg, sizeof(omsg)); - - memset(data + sizeof(struct sc_header) + sizeof(struct sc_client_outmsg), 0, SC_MAX_MSGLEN); - - PacketRecvInterface_Done(&flood_source, sizeof(struct sc_header) + sizeof(struct sc_client_outmsg) + SC_MAX_MSGLEN); -} diff --git a/external/badvpn_dns/flooder/flooder.h b/external/badvpn_dns/flooder/flooder.h deleted file mode 100644 index c8b8443..0000000 --- a/external/badvpn_dns/flooder/flooder.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file flooder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// name of the program -#define PROGRAM_NAME "flooder" - -// server output buffer size -#define SERVER_BUFFER_MIN_PACKETS 200 - -// maximum number of peers to flood -#define MAX_FLOODS 64 diff --git a/external/badvpn_dns/flow/BufferWriter.c b/external/badvpn_dns/flow/BufferWriter.c deleted file mode 100644 index b0e4129..0000000 --- a/external/badvpn_dns/flow/BufferWriter.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file BufferWriter.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include <flow/BufferWriter.h> - -static void output_handler_recv (BufferWriter *o, uint8_t *data) -{ - ASSERT(!o->out_have) - - // set output packet - o->out_have = 1; - o->out = data; -} - -void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init output - PacketRecvInterface_Init(&o->recv_interface, mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no output packet - o->out_have = 0; - - DebugObject_Init(&o->d_obj); - #ifndef NDEBUG - o->d_mtu = mtu; - o->d_writing = 0; - #endif -} - -void BufferWriter_Free (BufferWriter *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->recv_interface); -} - -PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->recv_interface; -} - -int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf) -{ - ASSERT(!o->d_writing) - DebugObject_Access(&o->d_obj); - - if (!o->out_have) { - return 0; - } - - if (buf) { - *buf = o->out; - } - - #ifndef NDEBUG - o->d_writing = 1; - #endif - - return 1; -} - -void BufferWriter_EndPacket (BufferWriter *o, int len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->d_mtu) - ASSERT(o->out_have) - ASSERT(o->d_writing) - DebugObject_Access(&o->d_obj); - - // set no output packet - o->out_have = 0; - - // finish packet - PacketRecvInterface_Done(&o->recv_interface, len); - - #ifndef NDEBUG - o->d_writing = 0; - #endif -} diff --git a/external/badvpn_dns/flow/BufferWriter.h b/external/badvpn_dns/flow/BufferWriter.h deleted file mode 100644 index 6b6a9c4..0000000 --- a/external/badvpn_dns/flow/BufferWriter.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file BufferWriter.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object for writing packets to a {@link PacketRecvInterface} client - * in a best-effort fashion. - */ - -#ifndef BADVPN_FLOW_BUFFERWRITER_H -#define BADVPN_FLOW_BUFFERWRITER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * Object for writing packets to a {@link PacketRecvInterface} client - * in a best-effort fashion. - */ -typedef struct { - PacketRecvInterface recv_interface; - int out_have; - uint8_t *out; - DebugObject d_obj; - #ifndef NDEBUG - int d_mtu; - int d_writing; - #endif -} BufferWriter; - -/** - * Initializes the object. - * The object is initialized in not writing state. - * - * @param o the object - * @param mtu maximum input packet length - * @param pg pending group - */ -void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void BufferWriter_Free (BufferWriter *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o); - -/** - * Attempts to provide a memory location for writing a packet. - * The object must be in not writing state. - * On success, the object enters writing state. - * - * @param o the object - * @param buf if not NULL, on success, the memory location will be stored here. - * It will have space for MTU bytes. - * @return 1 on success, 0 on failure - */ -int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf) WARN_UNUSED; - -/** - * Submits a packet written to the buffer. - * The object must be in writing state. - * Yhe object enters not writing state. - * - * @param o the object - * @param len length of the packet that was written. Must be >=0 and - * <=MTU. - */ -void BufferWriter_EndPacket (BufferWriter *o, int len); - -#endif diff --git a/external/badvpn_dns/flow/CMakeLists.txt b/external/badvpn_dns/flow/CMakeLists.txt deleted file mode 100644 index 6cd82f6..0000000 --- a/external/badvpn_dns/flow/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -set(FLOW_SOURCES - PacketPassFairQueue.c - PacketPassPriorityQueue.c - PacketPassConnector.c - PacketRecvConnector.c - StreamRecvConnector.c - PacketRecvBlocker.c - PacketPassNotifier.c - PacketBuffer.c - SinglePacketBuffer.c - PacketCopier.c - PacketStreamSender.c - PacketProtoEncoder.c - PacketProtoDecoder.c - PacketProtoFlow.c - SinglePacketSender.c - BufferWriter.c - PacketPassInterface.c - PacketRecvInterface.c - StreamPassInterface.c - StreamRecvInterface.c - RouteBuffer.c - PacketRouter.c - LineBuffer.c - SingleStreamSender.c - SingleStreamReceiver.c - StreamPacketSender.c - StreamPassConnector.c - PacketPassFifoQueue.c -) -badvpn_add_library(flow "base" "" "${FLOW_SOURCES}") diff --git a/external/badvpn_dns/flow/LineBuffer.c b/external/badvpn_dns/flow/LineBuffer.c deleted file mode 100644 index 15c9969..0000000 --- a/external/badvpn_dns/flow/LineBuffer.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file LineBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <base/BLog.h> - -#include <flow/LineBuffer.h> - -#include <generated/blog_channel_LineBuffer.h> - -static void input_handler_done (LineBuffer *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_size - o->buf_used) - - // update buffer - o->buf_used += data_len; - - // look for newline - int i; - for (i = o->buf_used - data_len; i < o->buf_used; i++) { - if (o->buf[i] == o->nl_char) { - break; - } - } - - if (i < o->buf_used || o->buf_used == o->buf_size) { - if (i == o->buf_used) { - BLog(BLOG_WARNING, "line too long"); - } - - // pass to output - o->buf_consumed = (i < o->buf_used ? i + 1 : i); - PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed); - } else { - // receive more data - StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used); - } -} - -static void output_handler_done (LineBuffer *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->buf_consumed > 0) - ASSERT(o->buf_consumed <= o->buf_used) - - // update buffer - memmove(o->buf, o->buf + o->buf_consumed, o->buf_used - o->buf_consumed); - o->buf_used -= o->buf_consumed; - - // look for newline - int i; - for (i = 0; i < o->buf_used; i++) { - if (o->buf[i] == o->nl_char) { - break; - } - } - - if (i < o->buf_used || o->buf_used == o->buf_size) { - // pass to output - o->buf_consumed = (i < o->buf_used ? i + 1 : i); - PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed); - } else { - // receive more data - StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used); - } -} - -int LineBuffer_Init (LineBuffer *o, StreamRecvInterface *input, PacketPassInterface *output, int buf_size, uint8_t nl_char) -{ - ASSERT(buf_size > 0) - ASSERT(PacketPassInterface_GetMTU(output) >= buf_size) - - // init arguments - o->input = input; - o->output = output; - o->buf_size = buf_size; - o->nl_char = nl_char; - - // init input - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // set buffer empty - o->buf_used = 0; - - // allocate buffer - if (!(o->buf = (uint8_t *)malloc(o->buf_size))) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // start receiving - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void LineBuffer_Free (LineBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - free(o->buf); -} diff --git a/external/badvpn_dns/flow/LineBuffer.h b/external/badvpn_dns/flow/LineBuffer.h deleted file mode 100644 index 6e15e32..0000000 --- a/external/badvpn_dns/flow/LineBuffer.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file LineBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_FLOW_LINEBUFFER_H -#define BADVPN_FLOW_LINEBUFFER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> -#include <flow/PacketPassInterface.h> - -typedef struct { - StreamRecvInterface *input; - PacketPassInterface *output; - int buf_size; - uint8_t nl_char; - int buf_used; - uint8_t *buf; - int buf_consumed; - DebugObject d_obj; -} LineBuffer; - -int LineBuffer_Init (LineBuffer *o, StreamRecvInterface *input, PacketPassInterface *output, int buf_size, uint8_t nl_char) WARN_UNUSED; -void LineBuffer_Free (LineBuffer *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketBuffer.c b/external/badvpn_dns/flow/PacketBuffer.c deleted file mode 100644 index 30afef6..0000000 --- a/external/badvpn_dns/flow/PacketBuffer.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file PacketBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -#include <flow/PacketBuffer.h> - -static void input_handler_done (PacketBuffer *buf, int in_len); -static void output_handler_done (PacketBuffer *buf); - -void input_handler_done (PacketBuffer *buf, int in_len) -{ - ASSERT(in_len >= 0) - ASSERT(in_len <= buf->input_mtu) - DebugObject_Access(&buf->d_obj); - - // remember if buffer is empty - int was_empty = (buf->buf.output_avail < 0); - - // submit packet to buffer - ChunkBuffer2_SubmitPacket(&buf->buf, in_len); - - // if there is space, schedule receive - if (buf->buf.input_avail >= buf->input_mtu) { - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - } - - // if buffer was empty, schedule send - if (was_empty) { - PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail); - } -} - -void output_handler_done (PacketBuffer *buf) -{ - DebugObject_Access(&buf->d_obj); - - // remember if buffer is full - int was_full = (buf->buf.input_avail < buf->input_mtu); - - // remove packet from buffer - ChunkBuffer2_ConsumePacket(&buf->buf); - - // if buffer was full and there is space, schedule receive - if (was_full && buf->buf.input_avail >= buf->input_mtu) { - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - } - - // if there is more data, schedule send - if (buf->buf.output_avail >= 0) { - PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail); - } -} - -int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input)) - ASSERT(num_packets > 0) - - // init arguments - buf->input = input; - buf->output = output; - - // init input - PacketRecvInterface_Receiver_Init(buf->input, (PacketRecvInterface_handler_done)input_handler_done, buf); - - // set input MTU - buf->input_mtu = PacketRecvInterface_GetMTU(buf->input); - - // init output - PacketPassInterface_Sender_Init(buf->output, (PacketPassInterface_handler_done)output_handler_done, buf); - - // allocate buffer - int num_blocks = ChunkBuffer2_calc_blocks(buf->input_mtu, num_packets); - if (num_blocks < 0) { - goto fail0; - } - if (!(buf->buf_data = (struct ChunkBuffer2_block *)BAllocArray(num_blocks, sizeof(buf->buf_data[0])))) { - goto fail0; - } - - // init buffer - ChunkBuffer2_Init(&buf->buf, buf->buf_data, num_blocks, buf->input_mtu); - - // schedule receive - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - - DebugObject_Init(&buf->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketBuffer_Free (PacketBuffer *buf) -{ - DebugObject_Free(&buf->d_obj); - - // free buffer - BFree(buf->buf_data); -} diff --git a/external/badvpn_dns/flow/PacketBuffer.h b/external/badvpn_dns/flow/PacketBuffer.h deleted file mode 100644 index 6daab69..0000000 --- a/external/badvpn_dns/flow/PacketBuffer.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file PacketBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output. - */ - -#ifndef BADVPN_FLOW_PACKETBUFFER_H -#define BADVPN_FLOW_PACKETBUFFER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <structure/ChunkBuffer2.h> -#include <flow/PacketRecvInterface.h> -#include <flow/PacketPassInterface.h> - -/** - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface *input; - int input_mtu; - PacketPassInterface *output; - struct ChunkBuffer2_block *buf_data; - ChunkBuffer2 buf; -} PacketBuffer; - -/** - * Initializes the buffer. - * Output MTU must be >= input MTU. - * - * @param buf the object - * @param input input interface - * @param output output interface - * @param num_packets minimum number of packets the buffer must hold. Must be >0. - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the buffer. - * - * @param buf the object - */ -void PacketBuffer_Free (PacketBuffer *buf); - -#endif diff --git a/external/badvpn_dns/flow/PacketCopier.c b/external/badvpn_dns/flow/PacketCopier.c deleted file mode 100644 index f4c7126..0000000 --- a/external/badvpn_dns/flow/PacketCopier.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file PacketCopier.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/debug.h> - -#include <flow/PacketCopier.h> - -static void input_handler_send (PacketCopier *o, uint8_t *data, int data_len) -{ - ASSERT(o->in_len == -1) - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - if (!o->out_have) { - o->in_len = data_len; - o->in = data; - return; - } - - memcpy(o->out, data, data_len); - - // finish input packet - PacketPassInterface_Done(&o->input); - - // finish output packet - PacketRecvInterface_Done(&o->output, data_len); - - o->out_have = 0; -} - -static void input_handler_requestcancel (PacketCopier *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // finish input packet - PacketPassInterface_Done(&o->input); - - o->in_len = -1; -} - -static void output_handler_recv (PacketCopier *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - if (o->in_len < 0) { - o->out_have = 1; - o->out = data; - return; - } - - memcpy(data, o->in, o->in_len); - - // finish input packet - PacketPassInterface_Done(&o->input); - - // finish output packet - PacketRecvInterface_Done(&o->output, o->in_len); - - o->in_len = -1; -} - -void PacketCopier_Init (PacketCopier *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init input - PacketPassInterface_Init(&o->input, mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - - // init output - PacketRecvInterface_Init(&o->output, mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no input packet - o->in_len = -1; - - // set no output packet - o->out_have = 0; - - DebugObject_Init(&o->d_obj); -} - -void PacketCopier_Free (PacketCopier *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketCopier_GetInput (PacketCopier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -PacketRecvInterface * PacketCopier_GetOutput (PacketCopier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/flow/PacketCopier.h b/external/badvpn_dns/flow/PacketCopier.h deleted file mode 100644 index 9b8ba86..0000000 --- a/external/badvpn_dns/flow/PacketCopier.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file PacketCopier.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which copies packets. - */ - -#ifndef BADVPN_FLOW_PACKETCOPIER_H -#define BADVPN_FLOW_PACKETCOPIER_H - -#include <stdint.h> - -#include <flow/PacketPassInterface.h> -#include <flow/PacketRecvInterface.h> - -/** - * Object which copies packets. - * Input is via {@link PacketPassInterface}. - * Output is via {@link PacketRecvInterface}. - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface input; - PacketRecvInterface output; - int in_len; - uint8_t *in; - int out_have; - uint8_t *out; -} PacketCopier; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. - * @param pg pending group - */ -void PacketCopier_Init (PacketCopier *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketCopier_Free (PacketCopier *o); - -/** - * Returns the input interface. - * The MTU of the interface will as in {@link PacketCopier_Init}. - * The interface will support cancel functionality. - * - * @return input interface - */ -PacketPassInterface * PacketCopier_GetInput (PacketCopier *o); - -/** - * Returns the output interface. - * The MTU of the interface will be as in {@link PacketCopier_Init}. - * - * @return output interface - */ -PacketRecvInterface * PacketCopier_GetOutput (PacketCopier *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassConnector.c b/external/badvpn_dns/flow/PacketPassConnector.c deleted file mode 100644 index 1a10326..0000000 --- a/external/badvpn_dns/flow/PacketPassConnector.c +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file PacketPassConnector.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> - -#include <flow/PacketPassConnector.h> - -static void input_handler_send (PacketPassConnector *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - o->in = data; - - if (o->output) { - // schedule send - PacketPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -static void output_handler_done (PacketPassConnector *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // have no input packet - o->in_len = -1; - - // allow input to send more packets - PacketPassInterface_Done(&o->input); -} - -void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - o->input_mtu = mtu; - - // init input - PacketPassInterface_Init(&o->input, o->input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // have no input packet - o->in_len = -1; - - // have no output - o->output = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketPassConnector_Free (PacketPassConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output) -{ - ASSERT(!o->output) - ASSERT(PacketPassInterface_GetMTU(output) >= o->input_mtu) - DebugObject_Access(&o->d_obj); - - // set output - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // if we have an input packet, schedule send - if (o->in_len >= 0) { - PacketPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -void PacketPassConnector_DisconnectOutput (PacketPassConnector *o) -{ - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // set no output - o->output = NULL; -} diff --git a/external/badvpn_dns/flow/PacketPassConnector.h b/external/badvpn_dns/flow/PacketPassConnector.h deleted file mode 100644 index 1a2cc6c..0000000 --- a/external/badvpn_dns/flow/PacketPassConnector.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file PacketPassConnector.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_PACKETPASSCONNECTOR_H -#define BADVPN_FLOW_PACKETPASSCONNECTOR_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -/** - * A {@link PacketPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ -typedef struct { - PacketPassInterface input; - int input_mtu; - int in_len; - uint8_t *in; - PacketPassInterface *output; - DebugObject d_obj; -} PacketPassConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param mtu maximum input packet size. Must be >=0. - * @param pg pending group - */ -void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassConnector_Free (PacketPassConnector *o); - -/** - * Returns the input interface. - * The MTU of the interface will be as in {@link PacketPassConnector_Init}. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o); - -/** - * Connects output. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output output to connect. Its MTU must be >= MTU specified in - * {@link PacketPassConnector_Init}. - */ -void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output); - -/** - * Disconnects output. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void PacketPassConnector_DisconnectOutput (PacketPassConnector *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassFairQueue.c b/external/badvpn_dns/flow/PacketPassFairQueue.c deleted file mode 100644 index bbfafe0..0000000 --- a/external/badvpn_dns/flow/PacketPassFairQueue.c +++ /dev/null @@ -1,405 +0,0 @@ -/** - * @file PacketPassFairQueue.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/minmax.h> -#include <misc/compare.h> - -#include <flow/PacketPassFairQueue.h> - -static int compare_flows (PacketPassFairQueueFlow *f1, PacketPassFairQueueFlow *f2) -{ - int cmp = B_COMPARE(f1->time, f2->time); - if (cmp) { - return cmp; - } - - return B_COMPARE((uintptr_t)f1, (uintptr_t)f2); -} - -#include "PacketPassFairQueue_tree.h" -#include <structure/SAvl_impl.h> - -static uint64_t get_current_time (PacketPassFairQueue *m) -{ - if (m->sending_flow) { - return m->sending_flow->time; - } - - uint64_t time = 0; // to remove warning - int have = 0; - - PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - if (first_flow) { - ASSERT(first_flow->is_queued) - - time = first_flow->time; - have = 1; - } - - if (m->previous_flow) { - if (!have || m->previous_flow->time < time) { - time = m->previous_flow->time; - have = 1; - } - } - - return (have ? time : 0); -} - -static void increment_sent_flow (PacketPassFairQueueFlow *flow, uint64_t amount) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(amount <= FAIRQUEUE_MAX_TIME) - ASSERT(!flow->is_queued) - ASSERT(!m->sending_flow) - - // does time overflow? - if (amount > FAIRQUEUE_MAX_TIME - flow->time) { - // get time to subtract - uint64_t subtract; - PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - if (!first_flow) { - subtract = flow->time; - } else { - ASSERT(first_flow->is_queued) - subtract = first_flow->time; - } - - // subtract time from all flows - for (LinkedList1Node *list_node = LinkedList1_GetFirst(&m->flows_list); list_node; list_node = LinkedList1Node_Next(list_node)) { - PacketPassFairQueueFlow *someflow = UPPER_OBJECT(list_node, PacketPassFairQueueFlow, list_node); - - // don't subtract more time than there is, except for the just finished flow, - // where we allow time to underflow and then overflow to the correct value after adding to it - if (subtract > someflow->time && someflow != flow) { - ASSERT(!someflow->is_queued) - someflow->time = 0; - } else { - someflow->time -= subtract; - } - } - } - - // add time to flow - flow->time += amount; -} - -static void schedule (PacketPassFairQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->previous_flow) - ASSERT(!m->freeing) - ASSERT(!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) - - // get first queued flow - PacketPassFairQueueFlow *qflow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - ASSERT(qflow->is_queued) - - // remove flow from queue - PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, qflow); - qflow->is_queued = 0; - - // schedule send - PacketPassInterface_Sender_Send(m->output, qflow->queued.data, qflow->queued.data_len); - m->sending_flow = qflow; - m->sending_len = qflow->queued.data_len; -} - -static void schedule_job_handler (PacketPassFairQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // remove previous flow - m->previous_flow = NULL; - - if (!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) { - schedule(m); - } -} - -static void input_handler_send (PacketPassFairQueueFlow *flow, uint8_t *data, int data_len) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(flow != m->sending_flow) - ASSERT(!flow->is_queued) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - if (flow == m->previous_flow) { - // remove from previous flow - m->previous_flow = NULL; - } else { - // raise time - flow->time = bmax_uint64(flow->time, get_current_time(m)); - } - - // queue flow - flow->queued.data = data; - flow->queued.data_len = data_len; - int res = PacketPassFairQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL); - ASSERT_EXECUTE(res) - flow->is_queued = 1; - - if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) { - schedule(m); - } -} - -static void output_handler_done (PacketPassFairQueue *m) -{ - ASSERT(m->sending_flow) - ASSERT(!m->previous_flow) - ASSERT(!BPending_IsSet(&m->schedule_job)) - ASSERT(!m->freeing) - ASSERT(!m->sending_flow->is_queued) - - PacketPassFairQueueFlow *flow = m->sending_flow; - - // sending finished - m->sending_flow = NULL; - - // remember this flow so the schedule job can remove its time if it didn's send - m->previous_flow = flow; - - // update flow time by packet size - increment_sent_flow(flow, (uint64_t)m->packet_weight + m->sending_len); - - // schedule schedule - BPending_Set(&m->schedule_job); - - // finish flow packet - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassFairQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) -{ - ASSERT(packet_weight > 0) - ASSERT(use_cancel == 0 || use_cancel == 1) - ASSERT(!use_cancel || PacketPassInterface_HasCancel(output)) - - // init arguments - m->output = output; - m->pg = pg; - m->use_cancel = use_cancel; - m->packet_weight = packet_weight; - - // make sure that (output MTU + packet_weight <= FAIRQUEUE_MAX_TIME) - if (!( - (PacketPassInterface_GetMTU(output) <= FAIRQUEUE_MAX_TIME) && - (packet_weight <= FAIRQUEUE_MAX_TIME - PacketPassInterface_GetMTU(output)) - )) { - goto fail0; - } - - // init output - PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m); - - // not sending - m->sending_flow = NULL; - - // no previous flow - m->previous_flow = NULL; - - // init queued tree - PacketPassFairQueue__Tree_Init(&m->queued_tree); - - // init flows list - LinkedList1_Init(&m->flows_list); - - // not freeing - m->freeing = 0; - - // init schedule job - BPending_Init(&m->schedule_job, m->pg, (BPending_handler)schedule_job_handler, m); - - DebugObject_Init(&m->d_obj); - DebugCounter_Init(&m->d_ctr); - return 1; - -fail0: - return 0; -} - -void PacketPassFairQueue_Free (PacketPassFairQueue *m) -{ - ASSERT(LinkedList1_IsEmpty(&m->flows_list)) - ASSERT(PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) - ASSERT(!m->previous_flow) - ASSERT(!m->sending_flow) - DebugCounter_Free(&m->d_ctr); - DebugObject_Free(&m->d_obj); - - // free schedule job - BPending_Free(&m->schedule_job); -} - -void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m) -{ - DebugObject_Access(&m->d_obj); - - // set freeing - m->freeing = 1; -} - -int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m) -{ - DebugObject_Access(&m->d_obj); - - return PacketPassInterface_GetMTU(m->output); -} - -void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m) -{ - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // init arguments - flow->m = m; - - // have no canfree handler - flow->handler_busy = NULL; - - // init input - PacketPassInterface_Init(&flow->input, PacketPassInterface_GetMTU(flow->m->output), (PacketPassInterface_handler_send)input_handler_send, flow, m->pg); - - // set time - flow->time = 0; - - // add to flows list - LinkedList1_Append(&m->flows_list, &flow->list_node); - - // is not queued - flow->is_queued = 0; - - DebugObject_Init(&flow->d_obj); - DebugCounter_Increment(&m->d_ctr); -} - -void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(m->freeing || flow != m->sending_flow) - DebugCounter_Decrement(&m->d_ctr); - DebugObject_Free(&flow->d_obj); - - // remove from current flow - if (flow == m->sending_flow) { - m->sending_flow = NULL; - } - - // remove from previous flow - if (flow == m->previous_flow) { - m->previous_flow = NULL; - } - - // remove from queue - if (flow->is_queued) { - PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, flow); - } - - // remove from flows list - LinkedList1_Remove(&m->flows_list, &flow->list_node); - - // free input - PacketPassInterface_Free(&flow->input); -} - -void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - B_USE(m) - - ASSERT(m->freeing || flow != m->sending_flow) - DebugObject_Access(&flow->d_obj); -} - -int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - return (flow == m->sending_flow); -} - -void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(flow == m->sending_flow) - ASSERT(m->use_cancel) - ASSERT(!m->freeing) - ASSERT(!BPending_IsSet(&m->schedule_job)) - DebugObject_Access(&flow->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(m->output); -} - -void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user) -{ - PacketPassFairQueue *m = flow->m; - B_USE(m) - - ASSERT(flow == m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // set handler - flow->handler_busy = handler; - flow->user = user; -} - -PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow) -{ - DebugObject_Access(&flow->d_obj); - - return &flow->input; -} diff --git a/external/badvpn_dns/flow/PacketPassFairQueue.h b/external/badvpn_dns/flow/PacketPassFairQueue.h deleted file mode 100644 index f846596..0000000 --- a/external/badvpn_dns/flow/PacketPassFairQueue.h +++ /dev/null @@ -1,204 +0,0 @@ -/** - * @file PacketPassFairQueue.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Fair queue using {@link PacketPassInterface}. - */ - -#ifndef BADVPN_FLOW_PACKETPASSFAIRQUEUE_H -#define BADVPN_FLOW_PACKETPASSFAIRQUEUE_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/debugcounter.h> -#include <structure/SAvl.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <flow/PacketPassInterface.h> - -// reduce this to test time overflow handling -#define FAIRQUEUE_MAX_TIME UINT64_MAX - -typedef void (*PacketPassFairQueue_handler_busy) (void *user); - -struct PacketPassFairQueueFlow_s; - -#include "PacketPassFairQueue_tree.h" -#include <structure/SAvl_decl.h> - -typedef struct PacketPassFairQueueFlow_s { - struct PacketPassFairQueue_s *m; - PacketPassFairQueue_handler_busy handler_busy; - void *user; - PacketPassInterface input; - uint64_t time; - LinkedList1Node list_node; - int is_queued; - struct { - PacketPassFairQueue__TreeNode tree_node; - uint8_t *data; - int data_len; - } queued; - DebugObject d_obj; -} PacketPassFairQueueFlow; - -/** - * Fair queue using {@link PacketPassInterface}. - */ -typedef struct PacketPassFairQueue_s { - PacketPassInterface *output; - BPendingGroup *pg; - int use_cancel; - int packet_weight; - struct PacketPassFairQueueFlow_s *sending_flow; - int sending_len; - struct PacketPassFairQueueFlow_s *previous_flow; - PacketPassFairQueue__Tree queued_tree; - LinkedList1 flows_list; - int freeing; - BPending schedule_job; - DebugObject d_obj; - DebugCounter d_ctr; -} PacketPassFairQueue; - -/** - * Initializes the queue. - * - * @param m the object - * @param output output interface - * @param pg pending group - * @param use_cancel whether cancel functionality is required. Must be 0 or 1. - * If 1, output must support cancel functionality. - * @param packet_weight additional weight a packet bears. Must be >0, to keep - * the queue fair for zero size packets. - * @return 1 on success, 0 on failure (because output MTU is too large) - */ -int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) WARN_UNUSED; - -/** - * Frees the queue. - * All flows must have been freed. - * - * @param m the object - */ -void PacketPassFairQueue_Free (PacketPassFairQueue *m); - -/** - * Prepares for freeing the entire queue. Must be called to allow freeing - * the flows in the process of freeing the entire queue. - * After this function is called, flows and the queue must be freed - * before any further I/O. - * May be called multiple times. - * The queue enters freeing state. - * - * @param m the object - */ -void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m); - -/** - * Returns the MTU of the queue. - * - * @param m the object - */ -int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m); - -/** - * Initializes a queue flow. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param m queue to attach to - */ -void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m); - -/** - * Frees a queue flow. - * Unless the queue is in freeing state: - * - The flow must not be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * - Must not be called from queue calls to output. - * - * @param flow the object - */ -void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow); - -/** - * Does nothing. - * It must be possible to free the flow (see {@link PacketPassFairQueueFlow_Free}). - * - * @param flow the object - */ -void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow); - -/** - * Determines if the flow is busy. If the flow is considered busy, it must not - * be freed. At any given time, at most one flow will be indicated as busy. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @return 0 if not busy, 1 is busy - */ -int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow); - -/** - * Requests the output to stop processing the current packet as soon as possible. - * Cancel functionality must be enabled for the queue. - * The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * - * @param flow the object - */ -void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow); - -/** - * Sets up a callback to be called when the flow is no longer busy. - * The handler will be called as soon as the flow is no longer busy, i.e. it is not - * possible that this flow is no longer busy before the handler is called. - * The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param handler callback function. NULL to disable. - * @param user value passed to callback function. Ignored if handler is NULL. - */ -void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user); - -/** - * Returns the input interface of the flow. - * - * @param flow the object - * @return input interface - */ -PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassFairQueue_tree.h b/external/badvpn_dns/flow/PacketPassFairQueue_tree.h deleted file mode 100644 index 5dd0a7d..0000000 --- a/external/badvpn_dns/flow/PacketPassFairQueue_tree.h +++ /dev/null @@ -1,7 +0,0 @@ -#define SAVL_PARAM_NAME PacketPassFairQueue__Tree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct PacketPassFairQueueFlow_s -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2)) -#define SAVL_PARAM_MEMBER_NODE queued.tree_node diff --git a/external/badvpn_dns/flow/PacketPassFifoQueue.c b/external/badvpn_dns/flow/PacketPassFifoQueue.c deleted file mode 100644 index 0395006..0000000 --- a/external/badvpn_dns/flow/PacketPassFifoQueue.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * @file PacketPassFifoQueue.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/offset.h> - -#include "PacketPassFifoQueue.h" - -static void schedule (PacketPassFifoQueue *o) -{ - ASSERT(!o->freeing) - ASSERT(!o->sending_flow) - ASSERT(!LinkedList1_IsEmpty(&o->waiting_flows_list)) - ASSERT(!BPending_IsSet(&o->schedule_job)) - - // get first waiting flow - PacketPassFifoQueueFlow *flow = UPPER_OBJECT(LinkedList1_GetFirst(&o->waiting_flows_list), PacketPassFifoQueueFlow, waiting_flows_list_node); - ASSERT(flow->queue == o) - ASSERT(flow->is_waiting) - - // remove it from queue - LinkedList1_Remove(&o->waiting_flows_list, &flow->waiting_flows_list_node); - flow->is_waiting = 0; - - // send - PacketPassInterface_Sender_Send(o->output, flow->waiting_data, flow->waiting_len); - o->sending_flow = flow; -} - -static void schedule_job_handler (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->freeing) - ASSERT(!o->sending_flow) - - if (!LinkedList1_IsEmpty(&o->waiting_flows_list)) { - schedule(o); - } -} - -static void input_handler_send (PacketPassFifoQueueFlow *o, uint8_t *data, int data_len) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Access(&o->d_obj); - ASSERT(!o->is_waiting) - ASSERT(o != queue->sending_flow) - ASSERT(!queue->freeing) - - // queue flow - o->waiting_data = data; - o->waiting_len = data_len; - LinkedList1_Append(&queue->waiting_flows_list, &o->waiting_flows_list_node); - o->is_waiting = 1; - - // schedule - if (!queue->sending_flow && !BPending_IsSet(&queue->schedule_job)) { - schedule(queue); - } -} - -static void output_handler_done (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->sending_flow) - ASSERT(!BPending_IsSet(&o->schedule_job)) - ASSERT(!o->freeing) - ASSERT(!o->sending_flow->is_waiting) - - PacketPassFifoQueueFlow *flow = o->sending_flow; - - // set no sending flow - o->sending_flow = NULL; - - // schedule schedule job - BPending_Set(&o->schedule_job); - - // done input - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassFifoQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -void PacketPassFifoQueue_Init (PacketPassFifoQueue *o, PacketPassInterface *output, BPendingGroup *pg) -{ - // init arguments - o->output = output; - o->pg = pg; - - // init output - PacketPassInterface_Sender_Init(output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init waiting flows list - LinkedList1_Init(&o->waiting_flows_list); - - // set no sending flow - o->sending_flow = NULL; - - // init schedule job - BPending_Init(&o->schedule_job, pg, (BPending_handler)schedule_job_handler, o); - - // set not freeing - o->freeing = 0; - - DebugCounter_Init(&o->d_flows_ctr); - DebugObject_Init(&o->d_obj); -} - -void PacketPassFifoQueue_Free (PacketPassFifoQueue *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_flows_ctr); - ASSERT(LinkedList1_IsEmpty(&o->waiting_flows_list)) - ASSERT(!o->sending_flow) - - // free schedule job - BPending_Free(&o->schedule_job); -} - -void PacketPassFifoQueue_PrepareFree (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - - // set freeing - o->freeing = 1; -} - -void PacketPassFifoQueueFlow_Init (PacketPassFifoQueueFlow *o, PacketPassFifoQueue *queue) -{ - DebugObject_Access(&queue->d_obj); - ASSERT(!queue->freeing) - - // init arguments - o->queue = queue; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(queue->output), (PacketPassInterface_handler_send)input_handler_send, o, queue->pg); - - // set not waiting - o->is_waiting = 0; - - // set no busy handler - o->handler_busy = NULL; - - DebugCounter_Increment(&queue->d_flows_ctr); - DebugObject_Init(&o->d_obj); -} - -void PacketPassFifoQueueFlow_Free (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&queue->d_flows_ctr); - ASSERT(queue->freeing || o != queue->sending_flow) - - // remove from sending flow - if (o == queue->sending_flow) { - queue->sending_flow = NULL; - } - - // remove from waiting flows list - if (o->is_waiting) { - LinkedList1_Remove(&queue->waiting_flows_list, &o->waiting_flows_list_node); - } - - // free input - PacketPassInterface_Free(&o->input); -} - -void PacketPassFifoQueueFlow_AssertFree (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - B_USE(queue) - DebugObject_Access(&o->d_obj); - ASSERT(queue->freeing || o != queue->sending_flow) -} - -int PacketPassFifoQueueFlow_IsBusy (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Access(&o->d_obj); - ASSERT(!queue->freeing) - - return (o == queue->sending_flow); -} - -void PacketPassFifoQueueFlow_SetBusyHandler (PacketPassFifoQueueFlow *o, PacketPassFifoQueue_handler_busy handler_busy, void *user) -{ - PacketPassFifoQueue *queue = o->queue; - B_USE(queue) - DebugObject_Access(&o->d_obj); - ASSERT(!queue->freeing) - ASSERT(o == queue->sending_flow) - - // set (or unset) busy handler - o->handler_busy = handler_busy; - o->user = user; -} - -PacketPassInterface * PacketPassFifoQueueFlow_GetInput (PacketPassFifoQueueFlow *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/external/badvpn_dns/flow/PacketPassFifoQueue.h b/external/badvpn_dns/flow/PacketPassFifoQueue.h deleted file mode 100644 index cefe79b..0000000 --- a/external/badvpn_dns/flow/PacketPassFifoQueue.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file PacketPassFifoQueue.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_PACKETPASSFIFOQUEUE_H -#define BADVPN_PACKETPASSFIFOQUEUE_H - -#include <misc/debugcounter.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -typedef void (*PacketPassFifoQueue_handler_busy) (void *user); - -struct PacketPassFifoQueueFlow_s; - -typedef struct { - PacketPassInterface *output; - BPendingGroup *pg; - LinkedList1 waiting_flows_list; - struct PacketPassFifoQueueFlow_s *sending_flow; - BPending schedule_job; - int freeing; - DebugCounter d_flows_ctr; - DebugObject d_obj; -} PacketPassFifoQueue; - -typedef struct PacketPassFifoQueueFlow_s { - PacketPassFifoQueue *queue; - PacketPassInterface input; - int is_waiting; - LinkedList1Node waiting_flows_list_node; - uint8_t *waiting_data; - int waiting_len; - PacketPassFifoQueue_handler_busy handler_busy; - void *user; - DebugObject d_obj; -} PacketPassFifoQueueFlow; - -void PacketPassFifoQueue_Init (PacketPassFifoQueue *o, PacketPassInterface *output, BPendingGroup *pg); -void PacketPassFifoQueue_Free (PacketPassFifoQueue *o); -void PacketPassFifoQueue_PrepareFree (PacketPassFifoQueue *o); - -void PacketPassFifoQueueFlow_Init (PacketPassFifoQueueFlow *o, PacketPassFifoQueue *queue); -void PacketPassFifoQueueFlow_Free (PacketPassFifoQueueFlow *o); -void PacketPassFifoQueueFlow_AssertFree (PacketPassFifoQueueFlow *o); -int PacketPassFifoQueueFlow_IsBusy (PacketPassFifoQueueFlow *o); -void PacketPassFifoQueueFlow_SetBusyHandler (PacketPassFifoQueueFlow *o, PacketPassFifoQueue_handler_busy handler_busy, void *user); -PacketPassInterface * PacketPassFifoQueueFlow_GetInput (PacketPassFifoQueueFlow *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassInterface.c b/external/badvpn_dns/flow/PacketPassInterface.c deleted file mode 100644 index dfa6ed5..0000000 --- a/external/badvpn_dns/flow/PacketPassInterface.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file PacketPassInterface.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <flow/PacketPassInterface.h> - -void _PacketPassInterface_job_operation (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PPI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _PacketPassInterface_job_requestcancel (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_BUSY) - ASSERT(i->cancel_requested) - ASSERT(i->handler_requestcancel) - DebugObject_Access(&i->d_obj); - - // call handler - i->handler_requestcancel(i->user_provider); - return; -} - -void _PacketPassInterface_job_done (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PPI_STATE_NONE; - - // call handler - i->handler_done(i->user_user); - return; -} diff --git a/external/badvpn_dns/flow/PacketPassInterface.h b/external/badvpn_dns/flow/PacketPassInterface.h deleted file mode 100644 index 0cc2274..0000000 --- a/external/badvpn_dns/flow/PacketPassInterface.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * @file PacketPassInterface.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a packet sender to pass data packets to a packet receiver. - */ - -#ifndef BADVPN_FLOW_PACKETPASSINTERFACE_H -#define BADVPN_FLOW_PACKETPASSINTERFACE_H - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BPending.h> - -#define PPI_STATE_NONE 1 -#define PPI_STATE_OPERATION_PENDING 2 -#define PPI_STATE_BUSY 3 -#define PPI_STATE_DONE_PENDING 4 - -typedef void (*PacketPassInterface_handler_send) (void *user, uint8_t *data, int data_len); - -typedef void (*PacketPassInterface_handler_requestcancel) (void *user); - -typedef void (*PacketPassInterface_handler_done) (void *user); - -typedef struct { - // provider data - int mtu; - PacketPassInterface_handler_send handler_operation; - PacketPassInterface_handler_requestcancel handler_requestcancel; - void *user_provider; - - // user data - PacketPassInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // requestcancel job - BPending job_requestcancel; - - // done job - BPending job_done; - - // state - int state; - int cancel_requested; - - DebugObject d_obj; -} PacketPassInterface; - -static void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg); - -static void PacketPassInterface_Free (PacketPassInterface *i); - -static void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel); - -static void PacketPassInterface_Done (PacketPassInterface *i); - -static int PacketPassInterface_GetMTU (PacketPassInterface *i); - -static void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user); - -static void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len); - -static void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i); - -static int PacketPassInterface_HasCancel (PacketPassInterface *i); - -void _PacketPassInterface_job_operation (PacketPassInterface *i); -void _PacketPassInterface_job_requestcancel (PacketPassInterface *i); -void _PacketPassInterface_job_done (PacketPassInterface *i); - -void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - i->mtu = mtu; - i->handler_operation = handler_operation; - i->handler_requestcancel = NULL; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketPassInterface_job_operation, i); - BPending_Init(&i->job_requestcancel, pg, (BPending_handler)_PacketPassInterface_job_requestcancel, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_PacketPassInterface_job_done, i); - - // set state - i->state = PPI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void PacketPassInterface_Free (PacketPassInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_requestcancel); - BPending_Free(&i->job_operation); -} - -void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel) -{ - ASSERT(!i->handler_requestcancel) - ASSERT(!i->handler_done) - ASSERT(handler_requestcancel) - - i->handler_requestcancel = handler_requestcancel; -} - -void PacketPassInterface_Done (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_BUSY) - DebugObject_Access(&i->d_obj); - - // unset requestcancel job - BPending_Unset(&i->job_requestcancel); - - // schedule done - BPending_Set(&i->job_done); - - // set state - i->state = PPI_STATE_DONE_PENDING; -} - -int PacketPassInterface_GetMTU (PacketPassInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return i->mtu; -} - -void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= i->mtu) - ASSERT(!(data_len > 0) || data) - ASSERT(i->state == PPI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = PPI_STATE_OPERATION_PENDING; - i->cancel_requested = 0; -} - -void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_OPERATION_PENDING || i->state == PPI_STATE_BUSY || i->state == PPI_STATE_DONE_PENDING) - ASSERT(i->handler_requestcancel) - DebugObject_Access(&i->d_obj); - - // ignore multiple cancel requests - if (i->cancel_requested) { - return; - } - - // remember we requested cancel - i->cancel_requested = 1; - - if (i->state == PPI_STATE_OPERATION_PENDING) { - // unset operation job - BPending_Unset(&i->job_operation); - - // set done job - BPending_Set(&i->job_done); - - // set state - i->state = PPI_STATE_DONE_PENDING; - } else if (i->state == PPI_STATE_BUSY) { - // set requestcancel job - BPending_Set(&i->job_requestcancel); - } -} - -int PacketPassInterface_HasCancel (PacketPassInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return !!i->handler_requestcancel; -} - -#endif diff --git a/external/badvpn_dns/flow/PacketPassNotifier.c b/external/badvpn_dns/flow/PacketPassNotifier.c deleted file mode 100644 index 0132746..0000000 --- a/external/badvpn_dns/flow/PacketPassNotifier.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file PacketPassNotifier.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <flow/PacketPassNotifier.h> - -void input_handler_send (PacketPassNotifier *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // schedule send - PacketPassInterface_Sender_Send(o->output, data, data_len); - - // if we have a handler, call it - if (o->handler) { - o->handler(o->handler_user, data, data_len); - return; - } -} - -void input_handler_requestcancel (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Sender_RequestCancel(o->output); -} - -void output_handler_done (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Done(&o->input); -} - -void PacketPassNotifier_Init (PacketPassNotifier *o, PacketPassInterface *output, BPendingGroup *pg) -{ - // init arguments - o->output = output; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, pg); - if (PacketPassInterface_HasCancel(o->output)) { - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - } - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // set no handler - o->handler = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketPassNotifier_Free (PacketPassNotifier *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassNotifier_GetInput (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassNotifier_SetHandler (PacketPassNotifier *o, PacketPassNotifier_handler_notify handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->handler_user = user; -} diff --git a/external/badvpn_dns/flow/PacketPassNotifier.h b/external/badvpn_dns/flow/PacketPassNotifier.h deleted file mode 100644 index b2fab13..0000000 --- a/external/badvpn_dns/flow/PacketPassNotifier.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file PacketPassNotifier.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer which calles a handler function before - * passing a packet from input to output. - */ - -#ifndef BADVPN_FLOW_PACKETPASSNOTIFIER_H -#define BADVPN_FLOW_PACKETPASSNOTIFIER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -/** - * Handler function called when input calls Send, but before the call is passed on to output. - * - * @param user value specified in {@link PacketPassNotifier_SetHandler} - * @param data packet provided by input - * @param data_len size of the packet - */ -typedef void (*PacketPassNotifier_handler_notify) (void *user, uint8_t *data, int data_len); - -/** - * A {@link PacketPassInterface} layer which calles a handler function before - * passing a packet from input to output. - */ -typedef struct { - PacketPassInterface input; - PacketPassInterface *output; - PacketPassNotifier_handler_notify handler; - void *handler_user; - DebugObject d_obj; -} PacketPassNotifier; - -/** - * Initializes the object. - * - * @param o the object - * @param output output interface - * @param pg pending group - */ -void PacketPassNotifier_Init (PacketPassNotifier *o, PacketPassInterface *output, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassNotifier_Free (PacketPassNotifier *o); - -/** - * Returns the input interface. - * The MTU of the interface will be the same as of the output interface. - * The interface supports cancel functionality if the output interface supports it. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassNotifier_GetInput (PacketPassNotifier *o); - -/** - * Configures a handler function to call before passing input packets to output. - * - * @param o the object - * @param handler handler function, or NULL to disable. - * @param user value to pass to handler function. Ignored if handler is NULL. - */ -void PacketPassNotifier_SetHandler (PacketPassNotifier *o, PacketPassNotifier_handler_notify handler, void *user); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassPriorityQueue.c b/external/badvpn_dns/flow/PacketPassPriorityQueue.c deleted file mode 100644 index 9534f1b..0000000 --- a/external/badvpn_dns/flow/PacketPassPriorityQueue.c +++ /dev/null @@ -1,283 +0,0 @@ -/** - * @file PacketPassPriorityQueue.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/compare.h> - -#include <flow/PacketPassPriorityQueue.h> - -static int compare_flows (PacketPassPriorityQueueFlow *f1, PacketPassPriorityQueueFlow *f2) -{ - int cmp = B_COMPARE(f1->priority, f2->priority); - if (cmp) { - return cmp; - } - - return B_COMPARE((uintptr_t)f1, (uintptr_t)f2); -} - -#include "PacketPassPriorityQueue_tree.h" -#include <structure/SAvl_impl.h> - -static void schedule (PacketPassPriorityQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - ASSERT(!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) - - // get first queued flow - PacketPassPriorityQueueFlow *qflow = PacketPassPriorityQueue__Tree_GetFirst(&m->queued_tree, 0); - ASSERT(qflow->is_queued) - - // remove flow from queue - PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, qflow); - qflow->is_queued = 0; - - // schedule send - PacketPassInterface_Sender_Send(m->output, qflow->queued.data, qflow->queued.data_len); - m->sending_flow = qflow; -} - -static void schedule_job_handler (PacketPassPriorityQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - if (!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) { - schedule(m); - } -} - -static void input_handler_send (PacketPassPriorityQueueFlow *flow, uint8_t *data, int data_len) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(flow != m->sending_flow) - ASSERT(!flow->is_queued) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // queue flow - flow->queued.data = data; - flow->queued.data_len = data_len; - int res = PacketPassPriorityQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL); - ASSERT_EXECUTE(res) - flow->is_queued = 1; - - if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) { - schedule(m); - } -} - -static void output_handler_done (PacketPassPriorityQueue *m) -{ - ASSERT(m->sending_flow) - ASSERT(!BPending_IsSet(&m->schedule_job)) - ASSERT(!m->freeing) - ASSERT(!m->sending_flow->is_queued) - - PacketPassPriorityQueueFlow *flow = m->sending_flow; - - // sending finished - m->sending_flow = NULL; - - // schedule schedule - BPending_Set(&m->schedule_job); - - // finish flow packet - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassPriorityQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel) -{ - ASSERT(use_cancel == 0 || use_cancel == 1) - ASSERT(!use_cancel || PacketPassInterface_HasCancel(output)) - - // init arguments - m->output = output; - m->pg = pg; - m->use_cancel = use_cancel; - - // init output - PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m); - - // not sending - m->sending_flow = NULL; - - // init queued tree - PacketPassPriorityQueue__Tree_Init(&m->queued_tree); - - // not freeing - m->freeing = 0; - - // init schedule job - BPending_Init(&m->schedule_job, m->pg, (BPending_handler)schedule_job_handler, m); - - DebugObject_Init(&m->d_obj); - DebugCounter_Init(&m->d_ctr); -} - -void PacketPassPriorityQueue_Free (PacketPassPriorityQueue *m) -{ - ASSERT(PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) - ASSERT(!m->sending_flow) - DebugCounter_Free(&m->d_ctr); - DebugObject_Free(&m->d_obj); - - // free schedule job - BPending_Free(&m->schedule_job); -} - -void PacketPassPriorityQueue_PrepareFree (PacketPassPriorityQueue *m) -{ - DebugObject_Access(&m->d_obj); - - // set freeing - m->freeing = 1; -} - -int PacketPassPriorityQueue_GetMTU (PacketPassPriorityQueue *m) -{ - DebugObject_Access(&m->d_obj); - - return PacketPassInterface_GetMTU(m->output); -} - -void PacketPassPriorityQueueFlow_Init (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue *m, int priority) -{ - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // init arguments - flow->m = m; - flow->priority = priority; - - // have no canfree handler - flow->handler_busy = NULL; - - // init input - PacketPassInterface_Init(&flow->input, PacketPassInterface_GetMTU(flow->m->output), (PacketPassInterface_handler_send)input_handler_send, flow, m->pg); - - // is not queued - flow->is_queued = 0; - - DebugObject_Init(&flow->d_obj); - DebugCounter_Increment(&m->d_ctr); -} - -void PacketPassPriorityQueueFlow_Free (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(m->freeing || flow != m->sending_flow) - DebugCounter_Decrement(&m->d_ctr); - DebugObject_Free(&flow->d_obj); - - // remove from current flow - if (flow == m->sending_flow) { - m->sending_flow = NULL; - } - - // remove from queue - if (flow->is_queued) { - PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, flow); - } - - // free input - PacketPassInterface_Free(&flow->input); -} - -void PacketPassPriorityQueueFlow_AssertFree (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - B_USE(m) - - ASSERT(m->freeing || flow != m->sending_flow) - DebugObject_Access(&flow->d_obj); -} - -int PacketPassPriorityQueueFlow_IsBusy (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - return (flow == m->sending_flow); -} - -void PacketPassPriorityQueueFlow_RequestCancel (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(flow == m->sending_flow) - ASSERT(m->use_cancel) - ASSERT(!m->freeing) - ASSERT(!BPending_IsSet(&m->schedule_job)) - DebugObject_Access(&flow->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(m->output); -} - -void PacketPassPriorityQueueFlow_SetBusyHandler (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue_handler_busy handler, void *user) -{ - PacketPassPriorityQueue *m = flow->m; - B_USE(m) - - ASSERT(flow == m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // set handler - flow->handler_busy = handler; - flow->user = user; -} - -PacketPassInterface * PacketPassPriorityQueueFlow_GetInput (PacketPassPriorityQueueFlow *flow) -{ - DebugObject_Access(&flow->d_obj); - - return &flow->input; -} diff --git a/external/badvpn_dns/flow/PacketPassPriorityQueue.h b/external/badvpn_dns/flow/PacketPassPriorityQueue.h deleted file mode 100644 index 3ac78eb..0000000 --- a/external/badvpn_dns/flow/PacketPassPriorityQueue.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file PacketPassPriorityQueue.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Priority queue using {@link PacketPassInterface}. - */ - -#ifndef BADVPN_FLOW_PACKETPASSPRIORITYQUEUE_H -#define BADVPN_FLOW_PACKETPASSPRIORITYQUEUE_H - -#include <stdint.h> - -#include <misc/debugcounter.h> -#include <structure/SAvl.h> -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <flow/PacketPassInterface.h> - -typedef void (*PacketPassPriorityQueue_handler_busy) (void *user); - -struct PacketPassPriorityQueueFlow_s; - -#include "PacketPassPriorityQueue_tree.h" -#include <structure/SAvl_decl.h> - -typedef struct PacketPassPriorityQueueFlow_s { - struct PacketPassPriorityQueue_s *m; - int priority; - PacketPassPriorityQueue_handler_busy handler_busy; - void *user; - PacketPassInterface input; - int is_queued; - struct { - PacketPassPriorityQueue__TreeNode tree_node; - uint8_t *data; - int data_len; - } queued; - DebugObject d_obj; -} PacketPassPriorityQueueFlow; - -/** - * Priority queue using {@link PacketPassInterface}. - */ -typedef struct PacketPassPriorityQueue_s { - PacketPassInterface *output; - BPendingGroup *pg; - int use_cancel; - struct PacketPassPriorityQueueFlow_s *sending_flow; - PacketPassPriorityQueue__Tree queued_tree; - int freeing; - BPending schedule_job; - DebugObject d_obj; - DebugCounter d_ctr; -} PacketPassPriorityQueue; - -/** - * Initializes the queue. - * - * @param m the object - * @param output output interface - * @param pg pending group - * @param use_cancel whether cancel functionality is required. Must be 0 or 1. - * If 1, output must support cancel functionality. - */ -void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel); - -/** - * Frees the queue. - * All flows must have been freed. - * - * @param m the object - */ -void PacketPassPriorityQueue_Free (PacketPassPriorityQueue *m); - -/** - * Prepares for freeing the entire queue. Must be called to allow freeing - * the flows in the process of freeing the entire queue. - * After this function is called, flows and the queue must be freed - * before any further I/O. - * May be called multiple times. - * The queue enters freeing state. - * - * @param m the object - */ -void PacketPassPriorityQueue_PrepareFree (PacketPassPriorityQueue *m); - -/** - * Returns the MTU of the queue. - * - * @param m the object - */ -int PacketPassPriorityQueue_GetMTU (PacketPassPriorityQueue *m); - -/** - * Initializes a queue flow. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param m queue to attach to - * @param priority flow priority. Lower value means higher priority. - */ -void PacketPassPriorityQueueFlow_Init (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue *m, int priority); - -/** - * Frees a queue flow. - * Unless the queue is in freeing state: - * - The flow must not be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * - Must not be called from queue calls to output. - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_Free (PacketPassPriorityQueueFlow *flow); - -/** - * Does nothing. - * It must be possible to free the flow (see {@link PacketPassPriorityQueueFlow}). - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_AssertFree (PacketPassPriorityQueueFlow *flow); - -/** - * Determines if the flow is busy. If the flow is considered busy, it must not - * be freed. At any given time, at most one flow will be indicated as busy. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @return 0 if not busy, 1 is busy - */ -int PacketPassPriorityQueueFlow_IsBusy (PacketPassPriorityQueueFlow *flow); - -/** - * Requests the output to stop processing the current packet as soon as possible. - * Cancel functionality must be enabled for the queue. - * The flow must be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_RequestCancel (PacketPassPriorityQueueFlow *flow); - -/** - * Sets up a callback to be called when the flow is no longer busy. - * The handler will be called as soon as the flow is no longer busy, i.e. it is not - * possible that this flow is no longer busy before the handler is called. - * The flow must be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param handler callback function. NULL to disable. - * @param user value passed to callback function. Ignored if handler is NULL. - */ -void PacketPassPriorityQueueFlow_SetBusyHandler (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue_handler_busy handler, void *user); - -/** - * Returns the input interface of the flow. - * - * @param flow the object - * @return input interface - */ -PacketPassInterface * PacketPassPriorityQueueFlow_GetInput (PacketPassPriorityQueueFlow *flow); - -#endif diff --git a/external/badvpn_dns/flow/PacketPassPriorityQueue_tree.h b/external/badvpn_dns/flow/PacketPassPriorityQueue_tree.h deleted file mode 100644 index 0d8b213..0000000 --- a/external/badvpn_dns/flow/PacketPassPriorityQueue_tree.h +++ /dev/null @@ -1,7 +0,0 @@ -#define SAVL_PARAM_NAME PacketPassPriorityQueue__Tree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct PacketPassPriorityQueueFlow_s -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2)) -#define SAVL_PARAM_MEMBER_NODE queued.tree_node diff --git a/external/badvpn_dns/flow/PacketProtoDecoder.c b/external/badvpn_dns/flow/PacketProtoDecoder.c deleted file mode 100644 index 68d26c5..0000000 --- a/external/badvpn_dns/flow/PacketProtoDecoder.c +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file PacketProtoDecoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/minmax.h> -#include <base/BLog.h> - -#include <flow/PacketProtoDecoder.h> - -#include <generated/blog_channel_PacketProtoDecoder.h> - -static void process_data (PacketProtoDecoder *enc); -static void input_handler_done (PacketProtoDecoder *enc, int data_len); -static void output_handler_done (PacketProtoDecoder *enc); - -void process_data (PacketProtoDecoder *enc) -{ - int was_error = 0; - - do { - uint8_t *data = enc->buf + enc->buf_start; - int left = enc->buf_used; - - // check if header was received - if (left < sizeof(struct packetproto_header)) { - break; - } - struct packetproto_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(struct packetproto_header); - left -= sizeof(struct packetproto_header); - int data_len = ltoh16(header.len); - - // check data length - if (data_len > enc->output_mtu) { - BLog(BLOG_NOTICE, "error: packet too large"); - was_error = 1; - break; - } - - // check if whole packet was received - if (left < data_len) { - break; - } - - // update buffer - enc->buf_start += sizeof(struct packetproto_header) + data_len; - enc->buf_used -= sizeof(struct packetproto_header) + data_len; - - // submit packet - PacketPassInterface_Sender_Send(enc->output, data, data_len); - return; - } while (0); - - if (was_error) { - // reset buffer - enc->buf_start = 0; - enc->buf_used = 0; - } else { - // if we reached the end of the buffer, wrap around to allow more data to be received - if (enc->buf_start + enc->buf_used == enc->buf_size) { - memmove(enc->buf, enc->buf + enc->buf_start, enc->buf_used); - enc->buf_start = 0; - } - } - - // receive data - StreamRecvInterface_Receiver_Recv(enc->input, enc->buf + (enc->buf_start + enc->buf_used), enc->buf_size - (enc->buf_start + enc->buf_used)); - - // if we had error, report it - if (was_error) { - enc->handler_error(enc->user); - return; - } -} - -static void input_handler_done (PacketProtoDecoder *enc, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= enc->buf_size - (enc->buf_start + enc->buf_used)) - DebugObject_Access(&enc->d_obj); - - // update buffer - enc->buf_used += data_len; - - // process data - process_data(enc); - return; -} - -void output_handler_done (PacketProtoDecoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - // process data - process_data(enc); - return; -} - -int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) -{ - // init arguments - enc->input = input; - enc->output = output; - enc->user = user; - enc->handler_error = handler_error; - - // init input - StreamRecvInterface_Receiver_Init(enc->input, (StreamRecvInterface_handler_done)input_handler_done, enc); - - // init output - PacketPassInterface_Sender_Init(enc->output, (PacketPassInterface_handler_done)output_handler_done, enc); - - // set output MTU, limit by maximum payload size - enc->output_mtu = bmin_int(PacketPassInterface_GetMTU(enc->output), PACKETPROTO_MAXPAYLOAD); - - // init buffer state - enc->buf_size = PACKETPROTO_ENCLEN(enc->output_mtu); - enc->buf_start = 0; - enc->buf_used = 0; - - // allocate buffer - if (!(enc->buf = (uint8_t *)malloc(enc->buf_size))) { - goto fail0; - } - - // start receiving - StreamRecvInterface_Receiver_Recv(enc->input, enc->buf, enc->buf_size); - - DebugObject_Init(&enc->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketProtoDecoder_Free (PacketProtoDecoder *enc) -{ - DebugObject_Free(&enc->d_obj); - - // free buffer - free(enc->buf); -} - -void PacketProtoDecoder_Reset (PacketProtoDecoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - enc->buf_start += enc->buf_used; - enc->buf_used = 0; -} diff --git a/external/badvpn_dns/flow/PacketProtoDecoder.h b/external/badvpn_dns/flow/PacketProtoDecoder.h deleted file mode 100644 index 2c20694..0000000 --- a/external/badvpn_dns/flow/PacketProtoDecoder.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file PacketProtoDecoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes a stream according to PacketProto. - */ - -#ifndef BADVPN_FLOW_PACKETPROTODECODER_H -#define BADVPN_FLOW_PACKETPROTODECODER_H - -#include <stdint.h> - -#include <protocol/packetproto.h> -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> -#include <flow/PacketPassInterface.h> - -/** - * Handler called when a protocol error occurs. - * When an error occurs, the decoder is reset to the initial state. - * - * @param user as in {@link PacketProtoDecoder_Init} - */ -typedef void (*PacketProtoDecoder_handler_error) (void *user); - -typedef struct { - StreamRecvInterface *input; - PacketPassInterface *output; - void *user; - PacketProtoDecoder_handler_error handler_error; - int output_mtu; - int buf_size; - int buf_start; - int buf_used; - uint8_t *buf; - DebugObject d_obj; -} PacketProtoDecoder; - -/** - * Initializes the object. - * - * @param enc the object - * @param input input interface. The decoder will accept packets with payload size up to its MTU - * (but the payload can never be more than PACKETPROTO_MAXPAYLOAD). - * @param output output interface - * @param pg pending group - * @param user argument to handlers - * @param handler_error error handler - * @return 1 on success, 0 on failure - */ -int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) WARN_UNUSED; - -/** - * Frees the object. - * - * @param enc the object - */ -void PacketProtoDecoder_Free (PacketProtoDecoder *enc); - -/** - * Clears the internal buffer. - * The next data received from the input will be treated as a new - * PacketProto stream. - * - * @param enc the object - */ -void PacketProtoDecoder_Reset (PacketProtoDecoder *enc); - -#endif diff --git a/external/badvpn_dns/flow/PacketProtoEncoder.c b/external/badvpn_dns/flow/PacketProtoEncoder.c deleted file mode 100644 index 00aaa95..0000000 --- a/external/badvpn_dns/flow/PacketProtoEncoder.c +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file PacketProtoEncoder.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <string.h> - -#include <protocol/packetproto.h> -#include <misc/balign.h> -#include <misc/debug.h> -#include <misc/byteorder.h> - -#include <flow/PacketProtoEncoder.h> - -static void output_handler_recv (PacketProtoEncoder *enc, uint8_t *data) -{ - ASSERT(!enc->output_packet) - ASSERT(data) - DebugObject_Access(&enc->d_obj); - - // schedule receive - enc->output_packet = data; - PacketRecvInterface_Receiver_Recv(enc->input, enc->output_packet + sizeof(struct packetproto_header)); -} - -static void input_handler_done (PacketProtoEncoder *enc, int in_len) -{ - ASSERT(enc->output_packet) - DebugObject_Access(&enc->d_obj); - - // write length - struct packetproto_header pp; - pp.len = htol16(in_len); - memcpy(enc->output_packet, &pp, sizeof(pp)); - - // finish output packet - enc->output_packet = NULL; - PacketRecvInterface_Done(&enc->output, PACKETPROTO_ENCLEN(in_len)); -} - -void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= PACKETPROTO_MAXPAYLOAD) - - // init arguments - enc->input = input; - - // init input - PacketRecvInterface_Receiver_Init(enc->input, (PacketRecvInterface_handler_done)input_handler_done, enc); - - // init output - PacketRecvInterface_Init( - &enc->output, PACKETPROTO_ENCLEN(PacketRecvInterface_GetMTU(enc->input)), - (PacketRecvInterface_handler_recv)output_handler_recv, enc, pg - ); - - // set no output packet - enc->output_packet = NULL; - - DebugObject_Init(&enc->d_obj); -} - -void PacketProtoEncoder_Free (PacketProtoEncoder *enc) -{ - DebugObject_Free(&enc->d_obj); - - // free input - PacketRecvInterface_Free(&enc->output); -} - -PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - return &enc->output; -} diff --git a/external/badvpn_dns/flow/PacketProtoEncoder.h b/external/badvpn_dns/flow/PacketProtoEncoder.h deleted file mode 100644 index 022aa00..0000000 --- a/external/badvpn_dns/flow/PacketProtoEncoder.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file PacketProtoEncoder.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets according to PacketProto. - */ - -#ifndef BADVPN_FLOW_PACKETPROTOENCODER_H -#define BADVPN_FLOW_PACKETPROTOENCODER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * Object which encodes packets according to PacketProto. - * - * Input is with {@link PacketRecvInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *output_packet; - DebugObject d_obj; -} PacketProtoEncoder; - -/** - * Initializes the object. - * - * @param enc the object - * @param input input interface. Its MTU must be <=PACKETPROTO_MAXPAYLOAD. - * @param pg pending group - */ -void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param enc the object - */ -void PacketProtoEncoder_Free (PacketProtoEncoder *enc); - -/** - * Returns the output interface. - * The MTU of the output interface is PACKETPROTO_ENCLEN(MTU of input interface). - * - * @param enc the object - * @return output interface - */ -PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc); - -#endif diff --git a/external/badvpn_dns/flow/PacketProtoFlow.c b/external/badvpn_dns/flow/PacketProtoFlow.c deleted file mode 100644 index 8fad8e2..0000000 --- a/external/badvpn_dns/flow/PacketProtoFlow.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file PacketProtoFlow.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <protocol/packetproto.h> -#include <misc/debug.h> - -#include <flow/PacketProtoFlow.h> - -int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(input_mtu >= 0) - ASSERT(input_mtu <= PACKETPROTO_MAXPAYLOAD) - ASSERT(num_packets > 0) - ASSERT(PacketPassInterface_GetMTU(output) >= PACKETPROTO_ENCLEN(input_mtu)) - - // init async input - BufferWriter_Init(&o->ainput, input_mtu, pg); - - // init encoder - PacketProtoEncoder_Init(&o->encoder, BufferWriter_GetOutput(&o->ainput), pg); - - // init buffer - if (!PacketBuffer_Init(&o->buffer, PacketProtoEncoder_GetOutput(&o->encoder), output, num_packets, pg)) { - goto fail0; - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - PacketProtoEncoder_Free(&o->encoder); - BufferWriter_Free(&o->ainput); - return 0; -} - -void PacketProtoFlow_Free (PacketProtoFlow *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - PacketBuffer_Free(&o->buffer); - - // free encoder - PacketProtoEncoder_Free(&o->encoder); - - // free async input - BufferWriter_Free(&o->ainput); -} - -BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->ainput; -} diff --git a/external/badvpn_dns/flow/PacketProtoFlow.h b/external/badvpn_dns/flow/PacketProtoFlow.h deleted file mode 100644 index 05e1233..0000000 --- a/external/badvpn_dns/flow/PacketProtoFlow.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file PacketProtoFlow.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Buffer which encodes packets with PacketProto, with {@link BufferWriter} - * input and {@link PacketPassInterface} output. - */ - -#ifndef BADVPN_FLOW_PACKETPROTOFLOW_H -#define BADVPN_FLOW_PACKETPROTOFLOW_H - -#include <misc/debug.h> - -#include <base/DebugObject.h> -#include <flow/BufferWriter.h> -#include <flow/PacketProtoEncoder.h> -#include <flow/PacketBuffer.h> - -/** - * Buffer which encodes packets with PacketProto, with {@link BufferWriter} - * input and {@link PacketPassInterface} output. - */ -typedef struct { - BufferWriter ainput; - PacketProtoEncoder encoder; - PacketBuffer buffer; - DebugObject d_obj; -} PacketProtoFlow; - -/** - * Initializes the object. - * - * @param o the object - * @param input_mtu maximum input packet size. Must be >=0 and <=PACKETPROTO_MAXPAYLOAD. - * @param num_packets minimum number of packets the buffer should hold. Must be >0. - * @param output output interface. Its MTU must be >=PACKETPROTO_ENCLEN(input_mtu). - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void PacketProtoFlow_Free (PacketProtoFlow *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketRecvBlocker.c b/external/badvpn_dns/flow/PacketRecvBlocker.c deleted file mode 100644 index 7e679f8..0000000 --- a/external/badvpn_dns/flow/PacketRecvBlocker.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file PacketRecvBlocker.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include <flow/PacketRecvBlocker.h> - -static void output_handler_recv (PacketRecvBlocker *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // remember packet - o->out_have = 1; - o->out = data; - o->out_input_blocking = 0; -} - -static void input_handler_done (PacketRecvBlocker *o, int data_len) -{ - ASSERT(o->out_have) - ASSERT(o->out_input_blocking) - DebugObject_Access(&o->d_obj); - - // schedule done - o->out_have = 0; - PacketRecvInterface_Done(&o->output, data_len); -} - -void PacketRecvBlocker_Init (PacketRecvBlocker *o, PacketRecvInterface *input, BPendingGroup *pg) -{ - // init arguments - o->input = input; - - // init output - PacketRecvInterface_Init(&o->output, PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_have = 0; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - DebugObject_Init(&o->d_obj); -} - -void PacketRecvBlocker_Free (PacketRecvBlocker *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * PacketRecvBlocker_GetOutput (PacketRecvBlocker *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void PacketRecvBlocker_AllowBlockedPacket (PacketRecvBlocker *o) -{ - DebugObject_Access(&o->d_obj); - - if (!o->out_have || o->out_input_blocking) { - return; - } - - // schedule receive - o->out_input_blocking = 1; - PacketRecvInterface_Receiver_Recv(o->input, o->out); -} diff --git a/external/badvpn_dns/flow/PacketRecvBlocker.h b/external/badvpn_dns/flow/PacketRecvBlocker.h deleted file mode 100644 index ba98d06..0000000 --- a/external/badvpn_dns/flow/PacketRecvBlocker.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file PacketRecvBlocker.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link PacketRecvInterface} layer which blocks all output recv calls and only - * passes a single blocked call on to input when the user wants so. - */ - -#ifndef BADVPN_FLOW_PACKETRECVBLOCKER_H -#define BADVPN_FLOW_PACKETRECVBLOCKER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * {@link PacketRecvInterface} layer which blocks all output recv calls and only - * passes a single blocked call on to input when the user wants so. - */ -typedef struct { - PacketRecvInterface output; - int out_have; - uint8_t *out; - int out_input_blocking; - PacketRecvInterface *input; - DebugObject d_obj; -} PacketRecvBlocker; - -/** - * Initializes the object. - * - * @param o the object - * @param input input interface - */ -void PacketRecvBlocker_Init (PacketRecvBlocker *o, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRecvBlocker_Free (PacketRecvBlocker *o); - -/** - * Returns the output interface. - * The MTU of the output interface will be the same as of the input interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * PacketRecvBlocker_GetOutput (PacketRecvBlocker *o); - -/** - * Passes a blocked output recv call to input if there is one and it has not - * been passed yet. Otherwise it does nothing. - * Must not be called from input Recv calls. - * This function may invoke I/O. - * - * @param o the object - */ -void PacketRecvBlocker_AllowBlockedPacket (PacketRecvBlocker *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketRecvConnector.c b/external/badvpn_dns/flow/PacketRecvConnector.c deleted file mode 100644 index 455db23..0000000 --- a/external/badvpn_dns/flow/PacketRecvConnector.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file PacketRecvConnector.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> - -#include <flow/PacketRecvConnector.h> - -static void output_handler_recv (PacketRecvConnector *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_have = 1; - o->out = data; - - if (o->input) { - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, o->out); - } -} - -static void input_handler_done (PacketRecvConnector *o, int data_len) -{ - ASSERT(o->out_have) - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // have no output packet - o->out_have = 0; - - // allow output to receive more packets - PacketRecvInterface_Done(&o->output, data_len); -} - -void PacketRecvConnector_Init (PacketRecvConnector *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - o->output_mtu = mtu; - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_have = 0; - - // have no input - o->input = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketRecvConnector_Free (PacketRecvConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * PacketRecvConnector_GetOutput (PacketRecvConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void PacketRecvConnector_ConnectInput (PacketRecvConnector *o, PacketRecvInterface *input) -{ - ASSERT(!o->input) - ASSERT(PacketRecvInterface_GetMTU(input) <= o->output_mtu) - DebugObject_Access(&o->d_obj); - - // set input - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // if we have an output packet, schedule receive - if (o->out_have) { - PacketRecvInterface_Receiver_Recv(o->input, o->out); - } -} - -void PacketRecvConnector_DisconnectInput (PacketRecvConnector *o) -{ - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // set no input - o->input = NULL; -} diff --git a/external/badvpn_dns/flow/PacketRecvConnector.h b/external/badvpn_dns/flow/PacketRecvConnector.h deleted file mode 100644 index 25cf851..0000000 --- a/external/badvpn_dns/flow/PacketRecvConnector.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file PacketRecvConnector.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_PACKETRECVCONNECTOR_H -#define BADVPN_FLOW_PACKETRECVCONNECTOR_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * A {@link PacketRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ -typedef struct { - PacketRecvInterface output; - int output_mtu; - int out_have; - uint8_t *out; - PacketRecvInterface *input; - DebugObject d_obj; -} PacketRecvConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param mtu maximum output packet size. Must be >=0. - * @param pg pending group - */ -void PacketRecvConnector_Init (PacketRecvConnector *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRecvConnector_Free (PacketRecvConnector *o); - -/** - * Returns the output interface. - * The MTU of the interface will be as in {@link PacketRecvConnector_Init}. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * PacketRecvConnector_GetOutput (PacketRecvConnector *o); - -/** - * Connects input. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output input to connect. Its MTU must be <= MTU specified in - * {@link PacketRecvConnector_Init}. - */ -void PacketRecvConnector_ConnectInput (PacketRecvConnector *o, PacketRecvInterface *input); - -/** - * Disconnects input. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void PacketRecvConnector_DisconnectInput (PacketRecvConnector *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketRecvInterface.c b/external/badvpn_dns/flow/PacketRecvInterface.c deleted file mode 100644 index 40bb8c6..0000000 --- a/external/badvpn_dns/flow/PacketRecvInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file PacketRecvInterface.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <flow/PacketRecvInterface.h> - -void _PacketRecvInterface_job_operation (PacketRecvInterface *i) -{ - ASSERT(i->state == PRI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PRI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data); - return; -} - -void _PacketRecvInterface_job_done (PacketRecvInterface *i) -{ - ASSERT(i->state == PRI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PRI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/external/badvpn_dns/flow/PacketRecvInterface.h b/external/badvpn_dns/flow/PacketRecvInterface.h deleted file mode 100644 index 6350ed2..0000000 --- a/external/badvpn_dns/flow/PacketRecvInterface.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file PacketRecvInterface.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a packet receiver to receive data packets from a packet sender. - */ - -#ifndef BADVPN_FLOW_PACKETRECVINTERFACE_H -#define BADVPN_FLOW_PACKETRECVINTERFACE_H - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BPending.h> - -#define PRI_STATE_NONE 1 -#define PRI_STATE_OPERATION_PENDING 2 -#define PRI_STATE_BUSY 3 -#define PRI_STATE_DONE_PENDING 4 - -typedef void (*PacketRecvInterface_handler_recv) (void *user, uint8_t *data); - -typedef void (*PacketRecvInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - int mtu; - PacketRecvInterface_handler_recv handler_operation; - void *user_provider; - - // user data - PacketRecvInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} PacketRecvInterface; - -static void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg); - -static void PacketRecvInterface_Free (PacketRecvInterface *i); - -static void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len); - -static int PacketRecvInterface_GetMTU (PacketRecvInterface *i); - -static void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user); - -static void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data); - -void _PacketRecvInterface_job_operation (PacketRecvInterface *i); -void _PacketRecvInterface_job_done (PacketRecvInterface *i); - -void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - i->mtu = mtu; - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketRecvInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_PacketRecvInterface_job_done, i); - - // set state - i->state = PRI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void PacketRecvInterface_Free (PacketRecvInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= i->mtu) - ASSERT(i->state == PRI_STATE_BUSY) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = PRI_STATE_DONE_PENDING; -} - -int PacketRecvInterface_GetMTU (PacketRecvInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return i->mtu; -} - -void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data) -{ - ASSERT(!(i->mtu > 0) || data) - ASSERT(i->state == PRI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - BPending_Set(&i->job_operation); - - // set state - i->state = PRI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/external/badvpn_dns/flow/PacketRouter.c b/external/badvpn_dns/flow/PacketRouter.c deleted file mode 100644 index 7b9f5f9..0000000 --- a/external/badvpn_dns/flow/PacketRouter.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file PacketRouter.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <flow/PacketRouter.h> - -static void input_handler_done (PacketRouter *o, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->mtu - o->recv_offset) - ASSERT(!BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); - - // set next job - BPending_Set(&o->next_job); - - // call handler - o->handler(o->user, RouteBufferSource_Pointer(&o->rbs), data_len); - return; -} - -static void next_job_handler (PacketRouter *o) -{ - DebugObject_Access(&o->d_obj); - - // receive - PacketRecvInterface_Receiver_Recv(o->input, RouteBufferSource_Pointer(&o->rbs) + o->recv_offset); -} - -int PacketRouter_Init (PacketRouter *o, int mtu, int recv_offset, PacketRecvInterface *input, PacketRouter_handler handler, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - ASSERT(recv_offset >= 0) - ASSERT(recv_offset <= mtu) - ASSERT(PacketRecvInterface_GetMTU(input) <= mtu - recv_offset) - - // init arguments - o->mtu = mtu; - o->recv_offset = recv_offset; - o->input = input; - o->handler = handler; - o->user = user; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init RouteBufferSource - if (!RouteBufferSource_Init(&o->rbs, mtu)) { - goto fail0; - } - - // init next job - BPending_Init(&o->next_job, pg, (BPending_handler)next_job_handler, o); - - // receive - PacketRecvInterface_Receiver_Recv(o->input, RouteBufferSource_Pointer(&o->rbs) + o->recv_offset); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketRouter_Free (PacketRouter *o) -{ - DebugObject_Free(&o->d_obj); - - // free next job - BPending_Free(&o->next_job); - - // free RouteBufferSource - RouteBufferSource_Free(&o->rbs); -} - -int PacketRouter_Route (PacketRouter *o, int len, RouteBuffer *output, uint8_t **next_buf, int copy_offset, int copy_len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->mtu) - ASSERT(RouteBuffer_GetMTU(output) == o->mtu) - ASSERT(copy_offset >= 0) - ASSERT(copy_offset <= o->mtu) - ASSERT(copy_len >= 0) - ASSERT(copy_len <= o->mtu - copy_offset) - ASSERT(BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); - - if (!RouteBufferSource_Route(&o->rbs, len, output, copy_offset, copy_len)) { - return 0; - } - - if (next_buf) { - *next_buf = RouteBufferSource_Pointer(&o->rbs); - } - - return 1; -} - -void PacketRouter_AssertRoute (PacketRouter *o) -{ - ASSERT(BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); -} diff --git a/external/badvpn_dns/flow/PacketRouter.h b/external/badvpn_dns/flow/PacketRouter.h deleted file mode 100644 index 3226078..0000000 --- a/external/badvpn_dns/flow/PacketRouter.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file PacketRouter.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which simplifies routing packets to {@link RouteBuffer}'s from a - * {@link PacketRecvInterface} input. - */ - -#ifndef BADVPN_FLOW_PACKETROUTER_H -#define BADVPN_FLOW_PACKETROUTER_H - -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <flow/PacketRecvInterface.h> -#include <flow/RouteBuffer.h> - -/** - * Handler called when a packet is received, allowing the user to route it - * to one or more buffers using {@link PacketRouter_Route}. - * - * @param user as in {@link PacketRouter_Init} - * @param buf the buffer for the packet. May be modified by the user. - * Will have space for mtu bytes. Only valid in the job context of - * this handler, until {@link PacketRouter_Route} is called successfully. - * @param recv_len length of the input packet (located at recv_offset bytes offset) - */ -typedef void (*PacketRouter_handler) (void *user, uint8_t *buf, int recv_len); - -/** - * Object which simplifies routing packets to {@link RouteBuffer}'s from a - * {@link PacketRecvInterface} input. - * - * Packets are routed by calling {@link PacketRouter_Route} (possibly multiple times) - * from the job context of the {@link PacketRouter_handler} handler. - */ -typedef struct { - int mtu; - int recv_offset; - PacketRecvInterface *input; - PacketRouter_handler handler; - void *user; - RouteBufferSource rbs; - BPending next_job; - DebugObject d_obj; -} PacketRouter; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. It will only be possible to route packets to - * {@link RouteBuffer}'s with the same MTU. - * @param recv_offset offset from the beginning for receiving input packets. - * Must be >=0 and <=mtu. The leading space should be initialized - * by the user before routing a packet. - * @param input input interface. Its MTU must be <= mtu - recv_offset. - * @param handler handler called when a packet is received to allow the user to route it - * @param user value passed to handler - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketRouter_Init (PacketRouter *o, int mtu, int recv_offset, PacketRecvInterface *input, PacketRouter_handler handler, void *user, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRouter_Free (PacketRouter *o); - -/** - * Routes the current packet to the given buffer. - * Must be called from the job context of the {@link PacketRouter_handler} handler. - * On success, copies part of the current packet to next one (regardless if next_buf - * is provided or not; if not, copies before receiving another packet). - * - * @param o the object - * @param len total packet length (e.g. recv_offset + (recv_len from handler)). - * Must be >=0 and <=mtu. - * @param output buffer to route to. Its MTU must be the same as of this object. - * @param next_buf if not NULL, on success, will be set to the address of a new current - * packet that can be routed. The pointer will be valid in the job context of - * the calling handler, until this function is called successfully again - * (as for the original pointer provided by the handler). - * @param copy_offset Offset from the beginning for copying to the next packet. - * Must be >=0 and <=mtu. - * @param copy_len Number of bytes to copy from the old current - * packet to the next one. Must be >=0 and <= mtu - copy_offset. - * @return 1 on success, 0 on failure (buffer full) - */ -int PacketRouter_Route (PacketRouter *o, int len, RouteBuffer *output, uint8_t **next_buf, int copy_offset, int copy_len); - -/** - * Asserts that {@link PacketRouter_Route} can be called. - * - * @param o the object - */ -void PacketRouter_AssertRoute (PacketRouter *o); - -#endif diff --git a/external/badvpn_dns/flow/PacketStreamSender.c b/external/badvpn_dns/flow/PacketStreamSender.c deleted file mode 100644 index 153a72b..0000000 --- a/external/badvpn_dns/flow/PacketStreamSender.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file PacketStreamSender.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> - -#include <flow/PacketStreamSender.h> - -static void send_data (PacketStreamSender *s) -{ - ASSERT(s->in_len >= 0) - - if (s->in_used < s->in_len) { - // send more data - StreamPassInterface_Sender_Send(s->output, s->in + s->in_used, s->in_len - s->in_used); - } else { - // finish input packet - s->in_len = -1; - PacketPassInterface_Done(&s->input); - } -} - -static void input_handler_send (PacketStreamSender *s, uint8_t *data, int data_len) -{ - ASSERT(s->in_len == -1) - ASSERT(data_len >= 0) - DebugObject_Access(&s->d_obj); - - // set input packet - s->in_len = data_len; - s->in = data; - s->in_used = 0; - - // send - send_data(s); -} - -static void output_handler_done (PacketStreamSender *s, int data_len) -{ - ASSERT(s->in_len >= 0) - ASSERT(data_len > 0) - ASSERT(data_len <= s->in_len - s->in_used) - DebugObject_Access(&s->d_obj); - - // update number of bytes sent - s->in_used += data_len; - - // send - send_data(s); -} - -void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - s->output = output; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)input_handler_send, s, pg); - - // init output - StreamPassInterface_Sender_Init(s->output, (StreamPassInterface_handler_done)output_handler_done, s); - - // have no input packet - s->in_len = -1; - - DebugObject_Init(&s->d_obj); -} - -void PacketStreamSender_Free (PacketStreamSender *s) -{ - DebugObject_Free(&s->d_obj); - - // free input - PacketPassInterface_Free(&s->input); -} - -PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s) -{ - DebugObject_Access(&s->d_obj); - - return &s->input; -} diff --git a/external/badvpn_dns/flow/PacketStreamSender.h b/external/badvpn_dns/flow/PacketStreamSender.h deleted file mode 100644 index 735360c..0000000 --- a/external/badvpn_dns/flow/PacketStreamSender.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file PacketStreamSender.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which forwards packets obtained with {@link PacketPassInterface} - * as a stream with {@link StreamPassInterface} (i.e. it concatenates them). - */ - -#ifndef BADVPN_FLOW_PACKETSTREAMSENDER_H -#define BADVPN_FLOW_PACKETSTREAMSENDER_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> -#include <flow/StreamPassInterface.h> - -/** - * Object which forwards packets obtained with {@link PacketPassInterface} - * as a stream with {@link StreamPassInterface} (i.e. it concatenates them). - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface input; - StreamPassInterface *output; - int in_len; - uint8_t *in; - int in_used; -} PacketStreamSender; - -/** - * Initializes the object. - * - * @param s the object - * @param output output interface - * @param mtu input MTU. Must be >=0. - * @param pg pending group - */ -void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param s the object - */ -void PacketStreamSender_Free (PacketStreamSender *s); - -/** - * Returns the input interface. - * Its MTU will be as in {@link PacketStreamSender_Init}. - * - * @param s the object - * @return input interface - */ -PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s); - -#endif diff --git a/external/badvpn_dns/flow/RouteBuffer.c b/external/badvpn_dns/flow/RouteBuffer.c deleted file mode 100644 index dec7be4..0000000 --- a/external/badvpn_dns/flow/RouteBuffer.c +++ /dev/null @@ -1,256 +0,0 @@ -/** - * @file RouteBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> - -#include <flow/RouteBuffer.h> - -static struct RouteBuffer_packet * alloc_packet (int mtu) -{ - if (mtu > SIZE_MAX - sizeof(struct RouteBuffer_packet)) { - return NULL; - } - - // allocate memory - struct RouteBuffer_packet *p = (struct RouteBuffer_packet *)malloc(sizeof(*p) + mtu); - if (!p) { - return NULL; - } - - return p; -} - -static int alloc_free_packet (RouteBuffer *o) -{ - struct RouteBuffer_packet *p = alloc_packet(o->mtu); - if (!p) { - return 0; - } - - // add to free packets list - LinkedList1_Append(&o->packets_free, &p->node); - - return 1; -} - -static void free_free_packets (RouteBuffer *o) -{ - while (!LinkedList1_IsEmpty(&o->packets_free)) { - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetLast(&o->packets_free), struct RouteBuffer_packet, node); - - // remove from free packets list - LinkedList1_Remove(&o->packets_free, &p->node); - - // free memory - free(p); - } -} - -static void release_used_packet (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetFirst(&o->packets_used), struct RouteBuffer_packet, node); - - // remove from used packets list - LinkedList1_Remove(&o->packets_used, &p->node); - - // add to free packets list - LinkedList1_Append(&o->packets_free, &p->node); -} - -static void send_used_packet (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetFirst(&o->packets_used), struct RouteBuffer_packet, node); - - // send - PacketPassInterface_Sender_Send(o->output, (uint8_t *)(p + 1), p->len); -} - -static void output_handler_done (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - DebugObject_Access(&o->d_obj); - - // release packet - release_used_packet(o); - - // send next packet if there is one - if (!LinkedList1_IsEmpty(&o->packets_used)) { - send_used_packet(o); - } -} - -int RouteBuffer_Init (RouteBuffer *o, int mtu, PacketPassInterface *output, int buf_size) -{ - ASSERT(mtu >= 0) - ASSERT(PacketPassInterface_GetMTU(output) >= mtu) - ASSERT(buf_size > 0) - - // init arguments - o->mtu = mtu; - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init free packets list - LinkedList1_Init(&o->packets_free); - - // init used packets list - LinkedList1_Init(&o->packets_used); - - // allocate packets - for (int i = 0; i < buf_size; i++) { - if (!alloc_free_packet(o)) { - goto fail1; - } - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - free_free_packets(o); - return 0; -} - -void RouteBuffer_Free (RouteBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // release packets so they can be freed - while (!LinkedList1_IsEmpty(&o->packets_used)) { - release_used_packet(o); - } - - // free packets - free_free_packets(o); -} - -int RouteBuffer_GetMTU (RouteBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - return o->mtu; -} - -int RouteBufferSource_Init (RouteBufferSource *o, int mtu) -{ - ASSERT(mtu >= 0) - - // init arguments - o->mtu = mtu; - - // allocate current packet - if (!(o->current_packet = alloc_packet(o->mtu))) { - goto fail0; - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - return 0; -} - -void RouteBufferSource_Free (RouteBufferSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free current packet - free(o->current_packet); -} - -uint8_t * RouteBufferSource_Pointer (RouteBufferSource *o) -{ - DebugObject_Access(&o->d_obj); - - return (uint8_t *)(o->current_packet + 1); -} - -int RouteBufferSource_Route (RouteBufferSource *o, int len, RouteBuffer *b, int copy_offset, int copy_len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->mtu) - ASSERT(b->mtu == o->mtu) - ASSERT(copy_offset >= 0) - ASSERT(copy_offset <= o->mtu) - ASSERT(copy_len >= 0) - ASSERT(copy_len <= o->mtu - copy_offset) - DebugObject_Access(&b->d_obj); - DebugObject_Access(&o->d_obj); - - // check if there's space in the buffer - if (LinkedList1_IsEmpty(&b->packets_free)) { - return 0; - } - - int was_empty = LinkedList1_IsEmpty(&b->packets_used); - - struct RouteBuffer_packet *p = o->current_packet; - - // set packet length - p->len = len; - - // append packet to used packets list - LinkedList1_Append(&b->packets_used, &p->node); - - // get a free packet - struct RouteBuffer_packet *np = UPPER_OBJECT(LinkedList1_GetLast(&b->packets_free), struct RouteBuffer_packet, node); - - // remove it from free packets list - LinkedList1_Remove(&b->packets_free, &np->node); - - // make it the current packet - o->current_packet = np; - - // copy packet - if (copy_len > 0) { - memcpy((uint8_t *)(np + 1) + copy_offset, (uint8_t *)(p + 1) + copy_offset, copy_len); - } - - // start sending if required - if (was_empty) { - send_used_packet(b); - } - - return 1; -} diff --git a/external/badvpn_dns/flow/RouteBuffer.h b/external/badvpn_dns/flow/RouteBuffer.h deleted file mode 100644 index d0f7b41..0000000 --- a/external/badvpn_dns/flow/RouteBuffer.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file RouteBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer for zero-copy packet routing. - */ - -#ifndef BADVPN_FLOW_ROUTEBUFFER_H -#define BADVPN_FLOW_ROUTEBUFFER_H - -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -struct RouteBuffer_packet { - LinkedList1Node node; - int len; -}; - -/** - * Packet buffer for zero-copy packet routing. - * - * Packets are buffered using {@link RouteBufferSource} objects. - */ -typedef struct { - int mtu; - PacketPassInterface *output; - LinkedList1 packets_free; - LinkedList1 packets_used; - DebugObject d_obj; -} RouteBuffer; - -/** - * Object through which packets are buffered into {@link RouteBuffer} objects. - * - * A packet is routed by calling {@link RouteBufferSource_Pointer}, writing it to - * the returned address, then calling {@link RouteBufferSource_Route}. - */ -typedef struct { - int mtu; - struct RouteBuffer_packet *current_packet; - DebugObject d_obj; -} RouteBufferSource; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. It will only be possible to route packets to this buffer - * from {@link RouteBufferSource}.s with the same MTU. - * @param output output interface. Its MTU must be >=mtu. - * @param buf_size size of the buffer in number of packet. Must be >0. - * @return 1 on success, 0 on failure - */ -int RouteBuffer_Init (RouteBuffer *o, int mtu, PacketPassInterface *output, int buf_size) WARN_UNUSED; - -/** - * Frees the object. - */ -void RouteBuffer_Free (RouteBuffer *o); - -/** - * Retuns the buffer's MTU (mtu argument to {@link RouteBuffer_Init}). - * - * @return MTU - */ -int RouteBuffer_GetMTU (RouteBuffer *o); - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. The object will only be able to route packets - * to {@link RouteBuffer}'s with the same MTU. - * @return 1 on success, 0 on failure - */ -int RouteBufferSource_Init (RouteBufferSource *o, int mtu) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void RouteBufferSource_Free (RouteBufferSource *o); - -/** - * Returns a pointer to the current packet. - * The pointed to memory area will have space for MTU bytes. - * The pointer is only valid until {@link RouteBufferSource_Route} succeeds. - * - * @param o the object - * @return pointer to the current packet - */ -uint8_t * RouteBufferSource_Pointer (RouteBufferSource *o); - -/** - * Routes the current packet to a given buffer. - * On success, this invalidates the pointer previously returned from - * {@link RouteBufferSource_Pointer}. - * - * @param o the object - * @param len length of the packet. Must be >=0 and <=MTU. - * @param b buffer to route to. Its MTU must equal this object's MTU. - * @param copy_offset Offset from the beginning for copying. Must be >=0 and - * <=mtu. - * @param copy_len Number of bytes to copy from the old current packet to the new one. - * Must be >=0 and <= mtu - copy_offset. - * @return 1 on success, 0 on failure - */ -int RouteBufferSource_Route (RouteBufferSource *o, int len, RouteBuffer *b, int copy_offset, int copy_len); - -#endif diff --git a/external/badvpn_dns/flow/SinglePacketBuffer.c b/external/badvpn_dns/flow/SinglePacketBuffer.c deleted file mode 100644 index bbc72ae..0000000 --- a/external/badvpn_dns/flow/SinglePacketBuffer.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file SinglePacketBuffer.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -#include <flow/SinglePacketBuffer.h> - -static void input_handler_done (SinglePacketBuffer *o, int in_len) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Sender_Send(o->output, o->buf, in_len); -} - -static void output_handler_done (SinglePacketBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - PacketRecvInterface_Receiver_Recv(o->input, o->buf); -} - -int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input)) - - // init arguments - o->input = input; - o->output = output; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init buffer - if (!(o->buf = (uint8_t *)BAlloc(PacketRecvInterface_GetMTU(o->input)))) { - goto fail1; - } - - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, o->buf); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - return 0; -} - -void SinglePacketBuffer_Free (SinglePacketBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - BFree(o->buf); -} diff --git a/external/badvpn_dns/flow/SinglePacketBuffer.h b/external/badvpn_dns/flow/SinglePacketBuffer.h deleted file mode 100644 index 87314a5..0000000 --- a/external/badvpn_dns/flow/SinglePacketBuffer.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file SinglePacketBuffer.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output - * than can store only a single packet. - */ - -#ifndef BADVPN_FLOW_SINGLEPACKETBUFFER_H -#define BADVPN_FLOW_SINGLEPACKETBUFFER_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> -#include <flow/PacketPassInterface.h> - -/** - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output - * than can store only a single packet. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface *input; - PacketPassInterface *output; - uint8_t *buf; -} SinglePacketBuffer; - -/** - * Initializes the object. - * Output MTU must be >= input MTU. - * - * @param o the object - * @param input input interface - * @param output output interface - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object - * - * @param o the object - */ -void SinglePacketBuffer_Free (SinglePacketBuffer *o); - -#endif diff --git a/external/badvpn_dns/flow/SinglePacketSender.c b/external/badvpn_dns/flow/SinglePacketSender.c deleted file mode 100644 index b1f3ec7..0000000 --- a/external/badvpn_dns/flow/SinglePacketSender.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file SinglePacketSender.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include <flow/SinglePacketSender.h> - -static void call_handler (SinglePacketSender *o) -{ - DEBUGERROR(&o->d_err, o->handler(o->user)); -} - -static void output_handler_done (SinglePacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - // notify user - call_handler(o); - return; -} - -void SinglePacketSender_Init (SinglePacketSender *o, uint8_t *packet, int packet_len, PacketPassInterface *output, SinglePacketSender_handler handler, void *user, BPendingGroup *pg) -{ - ASSERT(packet_len >= 0) - ASSERT(packet_len <= PacketPassInterface_GetMTU(output)) - - // init arguments - o->output = output; - o->handler = handler; - o->user = user; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // schedule send - PacketPassInterface_Sender_Send(o->output, packet, packet_len); - - DebugObject_Init(&o->d_obj); - DebugError_Init(&o->d_err, pg); -} - -void SinglePacketSender_Free (SinglePacketSender *o) -{ - DebugError_Free(&o->d_err); - DebugObject_Free(&o->d_obj); -} diff --git a/external/badvpn_dns/flow/SinglePacketSender.h b/external/badvpn_dns/flow/SinglePacketSender.h deleted file mode 100644 index c9289d8..0000000 --- a/external/badvpn_dns/flow/SinglePacketSender.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SinglePacketSender.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} source which sends a single packet. - */ - -#ifndef BADVPN_FLOW_SINGLEPACKETSENDER_H -#define BADVPN_FLOW_SINGLEPACKETSENDER_H - -#include <stdint.h> - -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <flow/PacketPassInterface.h> - -/** - * Handler function called after the packet is sent. - * The object must be freed from within this handler. - * - * @param user as in {@link SinglePacketSender_Init}. - */ -typedef void (*SinglePacketSender_handler) (void *user); - -/** - * A {@link PacketPassInterface} source which sends a single packet. - */ -typedef struct { - PacketPassInterface *output; - SinglePacketSender_handler handler; - void *user; - DebugObject d_obj; - DebugError d_err; -} SinglePacketSender; - -/** - * Initializes the object. - * - * @param o the object - * @param packet packet to be sent. Must be available as long as the object exists. - * @param packet_len length of the packet. Must be >=0 and <=(MTU of output). - * @param output output interface - * @param handler handler to call when the packet is sent - * @param user value to pass to handler - * @param pg pending group - */ -void SinglePacketSender_Init (SinglePacketSender *o, uint8_t *packet, int packet_len, PacketPassInterface *output, SinglePacketSender_handler handler, void *user, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SinglePacketSender_Free (SinglePacketSender *o); - -#endif diff --git a/external/badvpn_dns/flow/SingleStreamReceiver.c b/external/badvpn_dns/flow/SingleStreamReceiver.c deleted file mode 100644 index b463290..0000000 --- a/external/badvpn_dns/flow/SingleStreamReceiver.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SingleStreamReceiver.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include "SingleStreamReceiver.h" - -static void input_handler_done (SingleStreamReceiver *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->packet_len - o->pos) - - // update position - o->pos += data_len; - - // if everything was received, notify user - if (o->pos == o->packet_len) { - DEBUGERROR(&o->d_err, o->handler(o->user)); - return; - } - - // receive more - StreamRecvInterface_Receiver_Recv(o->input, o->packet + o->pos, o->packet_len - o->pos); -} - -void SingleStreamReceiver_Init (SingleStreamReceiver *o, uint8_t *packet, int packet_len, StreamRecvInterface *input, BPendingGroup *pg, void *user, SingleStreamReceiver_handler handler) -{ - ASSERT(packet_len > 0) - ASSERT(handler) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - o->input = input; - o->user = user; - o->handler = handler; - - // set position zero - o->pos = 0; - - // init output - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // start receiving - StreamRecvInterface_Receiver_Recv(o->input, o->packet + o->pos, o->packet_len - o->pos); - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); -} - -void SingleStreamReceiver_Free (SingleStreamReceiver *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); -} diff --git a/external/badvpn_dns/flow/SingleStreamReceiver.h b/external/badvpn_dns/flow/SingleStreamReceiver.h deleted file mode 100644 index c9c6219..0000000 --- a/external/badvpn_dns/flow/SingleStreamReceiver.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file SingleStreamReceiver.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLESTREAMRECEIVER_H -#define BADVPN_SINGLESTREAMRECEIVER_H - -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> - -typedef void (*SingleStreamReceiver_handler) (void *user); - -typedef struct { - uint8_t *packet; - int packet_len; - StreamRecvInterface *input; - void *user; - SingleStreamReceiver_handler handler; - int pos; - DebugError d_err; - DebugObject d_obj; -} SingleStreamReceiver; - -void SingleStreamReceiver_Init (SingleStreamReceiver *o, uint8_t *packet, int packet_len, StreamRecvInterface *input, BPendingGroup *pg, void *user, SingleStreamReceiver_handler handler); -void SingleStreamReceiver_Free (SingleStreamReceiver *o); - -#endif diff --git a/external/badvpn_dns/flow/SingleStreamSender.c b/external/badvpn_dns/flow/SingleStreamSender.c deleted file mode 100644 index eb33306..0000000 --- a/external/badvpn_dns/flow/SingleStreamSender.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SingleStreamSender.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include "SingleStreamSender.h" - -static void output_handler_done (SingleStreamSender *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->packet_len - o->pos) - - // update position - o->pos += data_len; - - // if everything was sent, notify user - if (o->pos == o->packet_len) { - DEBUGERROR(&o->d_err, o->handler(o->user)); - return; - } - - // send more - StreamPassInterface_Sender_Send(o->output, o->packet + o->pos, o->packet_len - o->pos); -} - -void SingleStreamSender_Init (SingleStreamSender *o, uint8_t *packet, int packet_len, StreamPassInterface *output, BPendingGroup *pg, void *user, SingleStreamSender_handler handler) -{ - ASSERT(packet_len > 0) - ASSERT(handler) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - o->output = output; - o->user = user; - o->handler = handler; - - // set position zero - o->pos = 0; - - // init output - StreamPassInterface_Sender_Init(o->output, (StreamPassInterface_handler_done)output_handler_done, o); - - // start sending - StreamPassInterface_Sender_Send(o->output, o->packet + o->pos, o->packet_len - o->pos); - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); -} - -void SingleStreamSender_Free (SingleStreamSender *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); -} diff --git a/external/badvpn_dns/flow/SingleStreamSender.h b/external/badvpn_dns/flow/SingleStreamSender.h deleted file mode 100644 index 180a9bf..0000000 --- a/external/badvpn_dns/flow/SingleStreamSender.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file SingleStreamSender.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLESTREAMSENDER_H -#define BADVPN_SINGLESTREAMSENDER_H - -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <flow/StreamPassInterface.h> - -typedef void (*SingleStreamSender_handler) (void *user); - -typedef struct { - uint8_t *packet; - int packet_len; - StreamPassInterface *output; - void *user; - SingleStreamSender_handler handler; - int pos; - DebugError d_err; - DebugObject d_obj; -} SingleStreamSender; - -void SingleStreamSender_Init (SingleStreamSender *o, uint8_t *packet, int packet_len, StreamPassInterface *output, BPendingGroup *pg, void *user, SingleStreamSender_handler handler); -void SingleStreamSender_Free (SingleStreamSender *o); - -#endif diff --git a/external/badvpn_dns/flow/StreamPacketSender.c b/external/badvpn_dns/flow/StreamPacketSender.c deleted file mode 100644 index 1e0a949..0000000 --- a/external/badvpn_dns/flow/StreamPacketSender.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file StreamPacketSender.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include "StreamPacketSender.h" - -static void input_handler_send (StreamPacketSender *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - - // limit length to MTU and remember - if (data_len > o->output_mtu) { - o->sending_len = o->output_mtu; - } else { - o->sending_len = data_len; - } - - // send - PacketPassInterface_Sender_Send(o->output, data, o->sending_len); -} - -static void output_handler_done (StreamPacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - // done - StreamPassInterface_Done(&o->input, o->sending_len); -} - -void StreamPacketSender_Init (StreamPacketSender *o, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) > 0) - - // init arguments - o->output = output; - - // remember output MTU - o->output_mtu = PacketPassInterface_GetMTU(output); - - // init input - StreamPassInterface_Init(&o->input, (StreamPassInterface_handler_send)input_handler_send, o, pg); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - DebugObject_Init(&o->d_obj); -} - -void StreamPacketSender_Free (StreamPacketSender *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - StreamPassInterface_Free(&o->input); -} - -StreamPassInterface * StreamPacketSender_GetInput (StreamPacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/external/badvpn_dns/flow/StreamPacketSender.h b/external/badvpn_dns/flow/StreamPacketSender.h deleted file mode 100644 index 19bda5e..0000000 --- a/external/badvpn_dns/flow/StreamPacketSender.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file StreamPacketSender.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STREAMPACKETSENDER_H -#define BADVPN_STREAMPACKETSENDER_H - -#include <base/DebugObject.h> -#include <flow/StreamPassInterface.h> -#include <flow/PacketPassInterface.h> - -/** - * Object which breaks an input stream into output packets. The resulting - * packets will have positive length, and, when concatenated, will form the - * original stream. - * - * Input is with {@link StreamPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - PacketPassInterface *output; - int output_mtu; - StreamPassInterface input; - int sending_len; - DebugObject d_obj; -} StreamPacketSender; - -/** - * Initializes the object. - * - * @param o the object - * @param output output interface. Its MTU must be >0. - * @param pg pending group we live in - */ -void StreamPacketSender_Init (StreamPacketSender *o, PacketPassInterface *output, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamPacketSender_Free (StreamPacketSender *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -StreamPassInterface * StreamPacketSender_GetInput (StreamPacketSender *o); - -#endif diff --git a/external/badvpn_dns/flow/StreamPassConnector.c b/external/badvpn_dns/flow/StreamPassConnector.c deleted file mode 100644 index d3075c7..0000000 --- a/external/badvpn_dns/flow/StreamPassConnector.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file StreamPassConnector.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> - -#include <flow/StreamPassConnector.h> - -static void input_handler_send (StreamPassConnector *o, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - o->in = data; - - if (o->output) { - // schedule send - StreamPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -static void output_handler_done (StreamPassConnector *o, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= o->in_len) - ASSERT(o->in_len > 0) - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // have no input packet - o->in_len = -1; - - // allow input to send more packets - StreamPassInterface_Done(&o->input, data_len); -} - -void StreamPassConnector_Init (StreamPassConnector *o, BPendingGroup *pg) -{ - // init output - StreamPassInterface_Init(&o->input, (StreamPassInterface_handler_send)input_handler_send, o, pg); - - // have no input packet - o->in_len = -1; - - // have no output - o->output = NULL; - - DebugObject_Init(&o->d_obj); -} - -void StreamPassConnector_Free (StreamPassConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - StreamPassInterface_Free(&o->input); -} - -StreamPassInterface * StreamPassConnector_GetInput (StreamPassConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void StreamPassConnector_ConnectOutput (StreamPassConnector *o, StreamPassInterface *output) -{ - ASSERT(!o->output) - DebugObject_Access(&o->d_obj); - - // set output - o->output = output; - - // init output - StreamPassInterface_Sender_Init(o->output, (StreamPassInterface_handler_done)output_handler_done, o); - - // if we have an input packet, schedule send - if (o->in_len > 0) { - StreamPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -void StreamPassConnector_DisconnectOutput (StreamPassConnector *o) -{ - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // set no output - o->output = NULL; -} diff --git a/external/badvpn_dns/flow/StreamPassConnector.h b/external/badvpn_dns/flow/StreamPassConnector.h deleted file mode 100644 index aa79195..0000000 --- a/external/badvpn_dns/flow/StreamPassConnector.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file StreamPassConnector.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link StreamPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_STREAMPASSCONNECTOR_H -#define BADVPN_FLOW_STREAMPASSCONNECTOR_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/StreamPassInterface.h> - -/** - * A {@link StreamPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ -typedef struct { - StreamPassInterface input; - int in_len; - uint8_t *in; - StreamPassInterface *output; - DebugObject d_obj; -} StreamPassConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param pg pending group - */ -void StreamPassConnector_Init (StreamPassConnector *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamPassConnector_Free (StreamPassConnector *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -StreamPassInterface * StreamPassConnector_GetInput (StreamPassConnector *o); - -/** - * Connects output. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output output to connect - */ -void StreamPassConnector_ConnectOutput (StreamPassConnector *o, StreamPassInterface *output); - -/** - * Disconnects output. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void StreamPassConnector_DisconnectOutput (StreamPassConnector *o); - -#endif diff --git a/external/badvpn_dns/flow/StreamPassInterface.c b/external/badvpn_dns/flow/StreamPassInterface.c deleted file mode 100644 index f0dc547..0000000 --- a/external/badvpn_dns/flow/StreamPassInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StreamPassInterface.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <flow/StreamPassInterface.h> - -void _StreamPassInterface_job_operation (StreamPassInterface *i) -{ - ASSERT(i->state == SPI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SPI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _StreamPassInterface_job_done (StreamPassInterface *i) -{ - ASSERT(i->state == SPI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SPI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/external/badvpn_dns/flow/StreamPassInterface.h b/external/badvpn_dns/flow/StreamPassInterface.h deleted file mode 100644 index 1fe650e..0000000 --- a/external/badvpn_dns/flow/StreamPassInterface.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file StreamPassInterface.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a stream sender to pass stream data to a stream receiver. - * - * Note that this interface behaves exactly the same and has the same code as - * {@link StreamRecvInterface} if names and its external semantics are disregarded. - * If you modify this file, you should probably modify {@link StreamRecvInterface} - * too. - */ - -#ifndef BADVPN_FLOW_STREAMPASSINTERFACE_H -#define BADVPN_FLOW_STREAMPASSINTERFACE_H - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BPending.h> - -#define SPI_STATE_NONE 1 -#define SPI_STATE_OPERATION_PENDING 2 -#define SPI_STATE_BUSY 3 -#define SPI_STATE_DONE_PENDING 4 - -typedef void (*StreamPassInterface_handler_send) (void *user, uint8_t *data, int data_len); - -typedef void (*StreamPassInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - StreamPassInterface_handler_send handler_operation; - void *user_provider; - - // user data - StreamPassInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} StreamPassInterface; - -static void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg); - -static void StreamPassInterface_Free (StreamPassInterface *i); - -static void StreamPassInterface_Done (StreamPassInterface *i, int data_len); - -static void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user); - -static void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len); - -void _StreamPassInterface_job_operation (StreamPassInterface *i); -void _StreamPassInterface_job_done (StreamPassInterface *i); - -void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg) -{ - // init arguments - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamPassInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_StreamPassInterface_job_done, i); - - // set state - i->state = SPI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void StreamPassInterface_Free (StreamPassInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void StreamPassInterface_Done (StreamPassInterface *i, int data_len) -{ - ASSERT(i->state == SPI_STATE_BUSY) - ASSERT(data_len > 0) - ASSERT(data_len <= i->job_operation_len) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = SPI_STATE_DONE_PENDING; -} - -void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data) - ASSERT(i->state == SPI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = SPI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/external/badvpn_dns/flow/StreamRecvConnector.c b/external/badvpn_dns/flow/StreamRecvConnector.c deleted file mode 100644 index beb6a88..0000000 --- a/external/badvpn_dns/flow/StreamRecvConnector.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file StreamRecvConnector.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> - -#include <flow/StreamRecvConnector.h> - -static void output_handler_recv (StreamRecvConnector *o, uint8_t *data, int data_avail) -{ - ASSERT(data_avail > 0) - ASSERT(o->out_avail == -1) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_avail = data_avail; - o->out = data; - - if (o->input) { - // schedule receive - StreamRecvInterface_Receiver_Recv(o->input, o->out, o->out_avail); - } -} - -static void input_handler_done (StreamRecvConnector *o, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= o->out_avail) - ASSERT(o->out_avail > 0) - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // have no output packet - o->out_avail = -1; - - // allow output to receive more packets - StreamRecvInterface_Done(&o->output, data_len); -} - -void StreamRecvConnector_Init (StreamRecvConnector *o, BPendingGroup *pg) -{ - // init output - StreamRecvInterface_Init(&o->output, (StreamRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_avail = -1; - - // have no input - o->input = NULL; - - DebugObject_Init(&o->d_obj); -} - -void StreamRecvConnector_Free (StreamRecvConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - StreamRecvInterface_Free(&o->output); -} - -StreamRecvInterface * StreamRecvConnector_GetOutput (StreamRecvConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void StreamRecvConnector_ConnectInput (StreamRecvConnector *o, StreamRecvInterface *input) -{ - ASSERT(!o->input) - DebugObject_Access(&o->d_obj); - - // set input - o->input = input; - - // init input - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // if we have an output packet, schedule receive - if (o->out_avail > 0) { - StreamRecvInterface_Receiver_Recv(o->input, o->out, o->out_avail); - } -} - -void StreamRecvConnector_DisconnectInput (StreamRecvConnector *o) -{ - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // set no input - o->input = NULL; -} diff --git a/external/badvpn_dns/flow/StreamRecvConnector.h b/external/badvpn_dns/flow/StreamRecvConnector.h deleted file mode 100644 index ed111ce..0000000 --- a/external/badvpn_dns/flow/StreamRecvConnector.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file StreamRecvConnector.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link StreamRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_STREAMRECVCONNECTOR_H -#define BADVPN_FLOW_STREAMRECVCONNECTOR_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> - -/** - * A {@link StreamRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ -typedef struct { - StreamRecvInterface output; - int out_avail; - uint8_t *out; - StreamRecvInterface *input; - DebugObject d_obj; -} StreamRecvConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param pg pending group - */ -void StreamRecvConnector_Init (StreamRecvConnector *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamRecvConnector_Free (StreamRecvConnector *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -StreamRecvInterface * StreamRecvConnector_GetOutput (StreamRecvConnector *o); - -/** - * Connects input. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output input to connect - */ -void StreamRecvConnector_ConnectInput (StreamRecvConnector *o, StreamRecvInterface *input); - -/** - * Disconnects input. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void StreamRecvConnector_DisconnectInput (StreamRecvConnector *o); - -#endif diff --git a/external/badvpn_dns/flow/StreamRecvInterface.c b/external/badvpn_dns/flow/StreamRecvInterface.c deleted file mode 100644 index 697e1ae..0000000 --- a/external/badvpn_dns/flow/StreamRecvInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StreamRecvInterface.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <flow/StreamRecvInterface.h> - -void _StreamRecvInterface_job_operation (StreamRecvInterface *i) -{ - ASSERT(i->state == SRI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SRI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _StreamRecvInterface_job_done (StreamRecvInterface *i) -{ - ASSERT(i->state == SRI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SRI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/external/badvpn_dns/flow/StreamRecvInterface.h b/external/badvpn_dns/flow/StreamRecvInterface.h deleted file mode 100644 index cd4a181..0000000 --- a/external/badvpn_dns/flow/StreamRecvInterface.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file StreamRecvInterface.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a stream receiver to receive stream data from a stream sender. - * - * Note that this interface behaves exactly the same and has the same code as - * {@link StreamPassInterface} if names and its external semantics are disregarded. - * If you modify this file, you should probably modify {@link StreamPassInterface} - * too. - */ - -#ifndef BADVPN_FLOW_STREAMRECVINTERFACE_H -#define BADVPN_FLOW_STREAMRECVINTERFACE_H - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <base/BPending.h> - -#define SRI_STATE_NONE 1 -#define SRI_STATE_OPERATION_PENDING 2 -#define SRI_STATE_BUSY 3 -#define SRI_STATE_DONE_PENDING 4 - -typedef void (*StreamRecvInterface_handler_recv) (void *user, uint8_t *data, int data_len); - -typedef void (*StreamRecvInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - StreamRecvInterface_handler_recv handler_operation; - void *user_provider; - - // user data - StreamRecvInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} StreamRecvInterface; - -static void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg); - -static void StreamRecvInterface_Free (StreamRecvInterface *i); - -static void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len); - -static void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user); - -static void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len); - -void _StreamRecvInterface_job_operation (StreamRecvInterface *i); -void _StreamRecvInterface_job_done (StreamRecvInterface *i); - -void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg) -{ - // init arguments - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamRecvInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_StreamRecvInterface_job_done, i); - - // set state - i->state = SRI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void StreamRecvInterface_Free (StreamRecvInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len) -{ - ASSERT(i->state == SRI_STATE_BUSY) - ASSERT(data_len > 0) - ASSERT(data_len <= i->job_operation_len) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = SRI_STATE_DONE_PENDING; -} - -void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data) - ASSERT(i->state == SRI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = SRI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/external/badvpn_dns/flowextra/CMakeLists.txt b/external/badvpn_dns/flowextra/CMakeLists.txt deleted file mode 100644 index 6ceb1c0..0000000 --- a/external/badvpn_dns/flowextra/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(FLOWEXTRA_SOURCES - PacketPassInactivityMonitor.c - KeepaliveIO.c -) -badvpn_add_library(flowextra "flow;system" "" "${FLOWEXTRA_SOURCES}") diff --git a/external/badvpn_dns/flowextra/KeepaliveIO.c b/external/badvpn_dns/flowextra/KeepaliveIO.c deleted file mode 100644 index 4e80366..0000000 --- a/external/badvpn_dns/flowextra/KeepaliveIO.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file KeepaliveIO.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include "KeepaliveIO.h" - -static void keepalive_handler (KeepaliveIO *o) -{ - DebugObject_Access(&o->d_obj); - - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); -} - -int KeepaliveIO_Init (KeepaliveIO *o, BReactor *reactor, PacketPassInterface *output, PacketRecvInterface *keepalive_input, btime_t keepalive_interval_ms) -{ - ASSERT(PacketRecvInterface_GetMTU(keepalive_input) <= PacketPassInterface_GetMTU(output)) - ASSERT(keepalive_interval_ms > 0) - - // set arguments - o->reactor = reactor; - - // init keep-alive sender - PacketPassInactivityMonitor_Init(&o->kasender, output, o->reactor, keepalive_interval_ms, (PacketPassInactivityMonitor_handler)keepalive_handler, o); - - // init queue - PacketPassPriorityQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->kasender), BReactor_PendingGroup(o->reactor), 0); - - // init keepalive flow - PacketPassPriorityQueueFlow_Init(&o->ka_qflow, &o->queue, -1); - - // init keepalive blocker - PacketRecvBlocker_Init(&o->ka_blocker, keepalive_input, BReactor_PendingGroup(reactor)); - - // init keepalive buffer - if (!SinglePacketBuffer_Init(&o->ka_buffer, PacketRecvBlocker_GetOutput(&o->ka_blocker), PacketPassPriorityQueueFlow_GetInput(&o->ka_qflow), BReactor_PendingGroup(o->reactor))) { - goto fail1; - } - - // init user flow - PacketPassPriorityQueueFlow_Init(&o->user_qflow, &o->queue, 0); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketRecvBlocker_Free(&o->ka_blocker); - PacketPassPriorityQueueFlow_Free(&o->ka_qflow); - PacketPassPriorityQueue_Free(&o->queue); - PacketPassInactivityMonitor_Free(&o->kasender); - return 0; -} - -void KeepaliveIO_Free (KeepaliveIO *o) -{ - DebugObject_Free(&o->d_obj); - - // allow freeing queue flows - PacketPassPriorityQueue_PrepareFree(&o->queue); - - // free user flow - PacketPassPriorityQueueFlow_Free(&o->user_qflow); - - // free keepalive buffer - SinglePacketBuffer_Free(&o->ka_buffer); - - // free keepalive blocker - PacketRecvBlocker_Free(&o->ka_blocker); - - // free keepalive flow - PacketPassPriorityQueueFlow_Free(&o->ka_qflow); - - // free queue - PacketPassPriorityQueue_Free(&o->queue); - - // free keep-alive sender - PacketPassInactivityMonitor_Free(&o->kasender); -} - -PacketPassInterface * KeepaliveIO_GetInput (KeepaliveIO *o) -{ - DebugObject_Access(&o->d_obj); - - return PacketPassPriorityQueueFlow_GetInput(&o->user_qflow); -} diff --git a/external/badvpn_dns/flowextra/KeepaliveIO.h b/external/badvpn_dns/flowextra/KeepaliveIO.h deleted file mode 100644 index d89321c..0000000 --- a/external/badvpn_dns/flowextra/KeepaliveIO.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file KeepaliveIO.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer for sending keep-alive packets. - */ - -#ifndef BADVPN_KEEPALIVEIO -#define BADVPN_KEEPALIVEIO - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <flow/PacketPassInterface.h> -#include <flow/PacketRecvInterface.h> -#include <flow/PacketPassPriorityQueue.h> -#include <flow/SinglePacketBuffer.h> -#include <flow/PacketRecvBlocker.h> -#include <flowextra/PacketPassInactivityMonitor.h> - -/** - * A {@link PacketPassInterface} layer for sending keep-alive packets. - */ -typedef struct { - BReactor *reactor; - PacketPassInactivityMonitor kasender; - PacketPassPriorityQueue queue; - PacketPassPriorityQueueFlow user_qflow; - PacketPassPriorityQueueFlow ka_qflow; - SinglePacketBuffer ka_buffer; - PacketRecvBlocker ka_blocker; - DebugObject d_obj; -} KeepaliveIO; - -/** - * Initializes the object. - * - * @param o the object - * @param reactor reactor we live in - * @param output output interface - * @param keepalive_input keepalive input interface. Its MTU must be <= MTU of output. - * @param keepalive_interval_ms keepalive interval in milliseconds. Must be >0. - * @return 1 on success, 0 on failure - */ -int KeepaliveIO_Init (KeepaliveIO *o, BReactor *reactor, PacketPassInterface *output, PacketRecvInterface *keepalive_input, btime_t keepalive_interval_ms) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void KeepaliveIO_Free (KeepaliveIO *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * KeepaliveIO_GetInput (KeepaliveIO *o); - -#endif diff --git a/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.c b/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.c deleted file mode 100644 index 6531fe0..0000000 --- a/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file PacketPassInactivityMonitor.c - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "PacketPassInactivityMonitor.h" - -static void input_handler_send (PacketPassInactivityMonitor *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // schedule send - PacketPassInterface_Sender_Send(o->output, data, data_len); - - // stop timer - BReactor_RemoveTimer(o->reactor, &o->timer); -} - -static void input_handler_requestcancel (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(o->output); -} - -static void output_handler_done (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // output no longer busy, restart timer - BReactor_SetTimer(o->reactor, &o->timer); - - // call done - PacketPassInterface_Done(&o->input); -} - -static void timer_handler (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // restart timer - BReactor_SetTimer(o->reactor, &o->timer); - - // call handler - if (o->handler) { - o->handler(o->user); - return; - } -} - -void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user) -{ - // init arguments - o->output = output; - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(o->reactor)); - if (PacketPassInterface_HasCancel(o->output)) { - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - } - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init timer - BTimer_Init(&o->timer, interval, (BTimer_handler)timer_handler, o); - BReactor_SetTimer(o->reactor, &o->timer); - - DebugObject_Init(&o->d_obj); -} - -void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o) -{ - DebugObject_Free(&o->d_obj); - - // free timer - BReactor_RemoveTimer(o->reactor, &o->timer); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->user = user; -} - -void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - BReactor_SetTimerAfter(o->reactor, &o->timer, 0); -} diff --git a/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.h b/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.h deleted file mode 100644 index 5857618..0000000 --- a/external/badvpn_dns/flowextra/PacketPassInactivityMonitor.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @file PacketPassInactivityMonitor.h - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer for detecting inactivity. - */ - -#ifndef BADVPN_PACKETPASSINACTIVITYMONITOR_H -#define BADVPN_PACKETPASSINACTIVITYMONITOR_H - -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <flow/PacketPassInterface.h> - -/** - * Handler function invoked when inactivity is detected. - * It is guaranteed that the interfaces are in not sending state. - * - * @param user value given to {@link PacketPassInactivityMonitor_Init} - */ -typedef void (*PacketPassInactivityMonitor_handler) (void *user); - -/** - * A {@link PacketPassInterface} layer for detecting inactivity. - * It reports inactivity to a user provided handler function. - * - * The object behaves like that: - * ("timer set" means started with the given timeout whether if was running or not, - * "timer unset" means stopped if it was running) - * - There is a timer. - * - The timer is set when the object is initialized. - * - When the input calls Send, the call is passed on to the output. - * If the output accepted the packet, the timer is set. If the output - * blocked the packet, the timer is unset. - * - When the output calls Done, the timer is set, and the call is - * passed on to the input. - * - When the input calls Cancel, the timer is set, and the call is - * passed on to the output. - * - When the timer expires, the timer is set, ant the user's handler - * function is invoked. - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface *output; - BReactor *reactor; - PacketPassInactivityMonitor_handler handler; - void *user; - PacketPassInterface input; - BTimer timer; -} PacketPassInactivityMonitor; - -/** - * Initializes the object. - * See {@link PacketPassInactivityMonitor} for details. - * - * @param o the object - * @param output output interface - * @param reactor reactor we live in - * @param interval timer value in milliseconds - * @param handler handler function for reporting inactivity, or NULL to disable - * @param user value passed to handler functions - */ -void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o); - -/** - * Returns the input interface. - * The MTU of the interface will be the same as of the output interface. - * The interface supports cancel functionality if the output interface supports it. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o); - -/** - * Sets or removes the inactivity handler. - * - * @param o the object - * @param handler handler function for reporting inactivity, or NULL to disable - * @param user value passed to handler functions - */ -void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user); - -/** - * Sets the timer to expire immediately in order to force an inactivity report. - * - * @param o the object - */ -void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o); - -#endif diff --git a/external/badvpn_dns/generate_files b/external/badvpn_dns/generate_files deleted file mode 100755 index f473369..0000000 --- a/external/badvpn_dns/generate_files +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -e - -PHP_CMD=( php ) -FLEX_CMD=( flex ) -BISON_CMD=( bison ) - -OUT_DIR="generated/" - -function bproto() { - local input="$1" - local name="$2" - "${PHP_CMD[@]}" bproto_generator/bproto.php --input-file "${input}" --output-dir "${OUT_DIR}" --name "bproto_${name}" -} - -function do_flex() { - local input="$1" - local name="$2" - "${FLEX_CMD[@]}" -o "${OUT_DIR}/flex_${name}.c" --header-file="${OUT_DIR}/flex_${name}.h" "${input}" - "${PHP_CMD[@]}" fix_flex.php "${OUT_DIR}/flex_${name}.c" - "${PHP_CMD[@]}" fix_flex.php "${OUT_DIR}/flex_${name}.h" -} - -function do_bison() { - local input="$1" - local name="$2" - "${BISON_CMD[@]}" -d -o "${OUT_DIR}/bison_${name}.c" "${input}" -} - -function do_lemon() { - local input="$1" - local name=$(basename "${input}") - ( - cd generated && - rm -f "${name}" && - cp ../"${input}" "${name}" && - ../lemon/lemon "${name}" - ) -} - -mkdir -p generated - -bproto tests/bproto_test.bproto bproto_test -bproto protocol/msgproto.bproto msgproto -bproto protocol/addr.bproto addr -do_flex predicate/BPredicate.l BPredicate -do_bison predicate/BPredicate.y BPredicate -"${PHP_CMD[@]}" blog_generator/blog.php --input-file blog_channels.txt --output-dir "${OUT_DIR}" -do_lemon ncd/NCDConfigParser_parse.y -do_lemon ncd/NCDValParser_parse.y diff --git a/external/badvpn_dns/generated/NCDConfigParser_parse.c b/external/badvpn_dns/generated/NCDConfigParser_parse.c deleted file mode 100644 index 3ebdceb..0000000 --- a/external/badvpn_dns/generated/NCDConfigParser_parse.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include <stdio.h> -#line 30 "NCDConfigParser_parse.y" - - -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/concat_strings.h> -#include <ncd/NCDAst.h> - -struct parser_out { - int out_of_memory; - int syntax_error; - int have_ast; - NCDProgram ast; -}; - -struct token { - char *str; - size_t len; -}; - -struct program { - int have; - NCDProgram v; -}; - -struct block { - int have; - NCDBlock v; -}; - -struct statement { - int have; - NCDStatement v; -}; - -struct ifblock { - int have; - NCDIfBlock v; -}; - -struct value { - int have; - NCDValue v; -}; - -static void free_token (struct token o) { free(o.str); } -static void free_program (struct program o) { if (o.have) NCDProgram_Free(&o.v); } -static void free_block (struct block o) { if (o.have) NCDBlock_Free(&o.v); } -static void free_statement (struct statement o) { if (o.have) NCDStatement_Free(&o.v); } -static void free_ifblock (struct ifblock o) { if (o.have) NCDIfBlock_Free(&o.v); } -static void free_value (struct value o) { if (o.have) NCDValue_Free(&o.v); } - -#line 62 "NCDConfigParser_parse.c" -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 41 -#define YYACTIONTYPE unsigned char -#define ParseTOKENTYPE struct token -typedef union { - int yyinit; - ParseTOKENTYPE yy0; - int yy12; - char * yy33; - struct block yy37; - struct value yy51; - struct program yy54; - struct ifblock yy76; - struct statement yy79; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 0 -#endif -#define ParseARG_SDECL struct parser_out *parser_out ; -#define ParseARG_PDECL , struct parser_out *parser_out -#define ParseARG_FETCH struct parser_out *parser_out = yypParser->parser_out -#define ParseARG_STORE yypParser->parser_out = parser_out -#define YYNSTATE 99 -#define YYNRULE 38 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 86, 39, 80, 87, 68, 88, 42, 86, 48, 80, - /* 10 */ 87, 1, 88, 42, 24, 85, 78, 41, 3, 82, - /* 20 */ 86, 40, 43, 87, 41, 88, 42, 41, 85, 79, - /* 30 */ 41, 3, 4, 86, 50, 56, 87, 46, 88, 44, - /* 40 */ 47, 85, 49, 41, 3, 4, 89, 34, 86, 35, - /* 50 */ 81, 87, 72, 88, 42, 73, 54, 86, 4, 55, - /* 60 */ 87, 84, 88, 44, 26, 97, 36, 75, 76, 36, - /* 70 */ 86, 61, 66, 87, 86, 88, 45, 87, 86, 88, - /* 80 */ 51, 87, 86, 88, 57, 87, 33, 88, 69, 15, - /* 90 */ 59, 27, 98, 38, 31, 99, 62, 37, 18, 15, - /* 100 */ 36, 138, 15, 53, 31, 15, 67, 31, 15, 60, - /* 110 */ 31, 15, 94, 31, 15, 65, 31, 19, 71, 31, - /* 120 */ 20, 11, 77, 23, 74, 22, 5, 83, 6, 90, - /* 130 */ 2, 91, 7, 25, 8, 12, 52, 21, 36, 13, - /* 140 */ 9, 92, 58, 32, 28, 14, 93, 63, 29, 64, - /* 150 */ 16, 139, 96, 95, 10, 17, 70, 30, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 30, 31, 32, 33, 15, 35, 36, 30, 31, 32, - /* 10 */ 33, 7, 35, 36, 10, 2, 4, 4, 5, 6, - /* 20 */ 30, 37, 32, 33, 4, 35, 36, 4, 2, 30, - /* 30 */ 4, 5, 19, 30, 11, 12, 33, 34, 35, 36, - /* 40 */ 30, 2, 37, 4, 5, 19, 20, 1, 30, 3, - /* 50 */ 32, 33, 24, 35, 36, 24, 37, 30, 19, 16, - /* 60 */ 33, 34, 35, 36, 26, 27, 38, 21, 22, 38, - /* 70 */ 30, 37, 37, 33, 30, 35, 36, 33, 30, 35, - /* 80 */ 36, 33, 30, 35, 36, 33, 24, 35, 36, 25, - /* 90 */ 8, 28, 27, 29, 30, 0, 14, 4, 2, 25, - /* 100 */ 38, 39, 25, 29, 30, 25, 29, 30, 25, 29, - /* 110 */ 30, 25, 29, 30, 25, 29, 30, 2, 29, 30, - /* 120 */ 6, 5, 9, 17, 24, 8, 18, 6, 18, 20, - /* 130 */ 7, 9, 14, 8, 7, 5, 8, 6, 38, 5, - /* 140 */ 7, 9, 13, 4, 6, 5, 9, 4, 6, 8, - /* 150 */ 5, 40, 6, 9, 7, 5, 8, 6, -}; -#define YY_SHIFT_USE_DFLT (-12) -#define YY_SHIFT_MAX 71 -static const short yy_shift_ofst[] = { - /* 0 */ 46, 39, 39, 13, 26, 39, 39, 39, 39, 39, - /* 10 */ 39, 23, 23, 23, 23, 23, 23, 23, 46, 46, - /* 20 */ 46, -11, 12, 20, 20, 12, 43, 12, 12, 12, - /* 30 */ -11, 4, 82, 95, 96, 115, 93, 116, 114, 117, - /* 40 */ 113, 106, 108, 121, 118, 110, 109, 123, 125, 122, - /* 50 */ 127, 128, 130, 131, 132, 134, 133, 129, 139, 140, - /* 60 */ 138, 137, 143, 141, 145, 142, 144, 146, 147, 148, - /* 70 */ 150, 151, -}; -#define YY_REDUCE_USE_DFLT (-31) -#define YY_REDUCE_MAX 30 -static const signed char yy_reduce_ofst[] = { - /* 0 */ 62, -30, -23, -10, 3, 18, 27, 40, 44, 48, - /* 10 */ 52, 64, 74, 77, 80, 83, 86, 89, 28, 31, - /* 20 */ 100, 38, -16, -1, 10, 5, 63, 19, 34, 35, - /* 30 */ 65, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 100, 119, 119, 137, 137, 137, 137, 137, 137, 137, - /* 10 */ 137, 137, 137, 137, 137, 115, 137, 137, 100, 100, - /* 20 */ 100, 109, 133, 137, 137, 133, 113, 133, 133, 133, - /* 30 */ 111, 137, 137, 137, 137, 137, 137, 137, 137, 137, - /* 40 */ 137, 117, 121, 137, 137, 125, 137, 137, 137, 137, - /* 50 */ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - /* 60 */ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - /* 70 */ 137, 137, 101, 102, 103, 135, 136, 104, 134, 118, - /* 80 */ 120, 122, 123, 124, 126, 129, 130, 131, 132, 127, - /* 90 */ 128, 105, 106, 107, 116, 108, 114, 110, 112, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include <stdio.h> -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -** <ul> -** <li> A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -** <li> A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -** </ul> -** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "INCLUDE", "STRING", "INCLUDE_GUARD", - "NAME", "CURLY_OPEN", "CURLY_CLOSE", "ROUND_OPEN", - "ROUND_CLOSE", "SEMICOLON", "ARROW", "IF", - "FOREACH", "AS", "COLON", "ELIF", - "ELSE", "DOT", "COMMA", "BRACKET_OPEN", - "BRACKET_CLOSE", "PROCESS", "TEMPLATE", "error", - "processes", "statement", "elif_maybe", "elif", - "else_maybe", "statements", "dotted_name", "statement_args_maybe", - "list_contents", "list", "map_contents", "map", - "value", "name_maybe", "process_or_template", "input", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "input ::= processes", - /* 1 */ "processes ::=", - /* 2 */ "processes ::= INCLUDE STRING processes", - /* 3 */ "processes ::= INCLUDE_GUARD STRING processes", - /* 4 */ "processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes", - /* 5 */ "statement ::= dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON", - /* 6 */ "statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON", - /* 7 */ "statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON", - /* 8 */ "statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON", - /* 9 */ "statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON", - /* 10 */ "elif_maybe ::=", - /* 11 */ "elif_maybe ::= elif", - /* 12 */ "elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE", - /* 13 */ "elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif", - /* 14 */ "else_maybe ::=", - /* 15 */ "else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE", - /* 16 */ "statements ::= statement", - /* 17 */ "statements ::= statement statements", - /* 18 */ "dotted_name ::= NAME", - /* 19 */ "dotted_name ::= NAME DOT dotted_name", - /* 20 */ "statement_args_maybe ::=", - /* 21 */ "statement_args_maybe ::= list_contents", - /* 22 */ "list_contents ::= value", - /* 23 */ "list_contents ::= value COMMA list_contents", - /* 24 */ "list ::= CURLY_OPEN CURLY_CLOSE", - /* 25 */ "list ::= CURLY_OPEN list_contents CURLY_CLOSE", - /* 26 */ "map_contents ::= value COLON value", - /* 27 */ "map_contents ::= value COLON value COMMA map_contents", - /* 28 */ "map ::= BRACKET_OPEN BRACKET_CLOSE", - /* 29 */ "map ::= BRACKET_OPEN map_contents BRACKET_CLOSE", - /* 30 */ "value ::= STRING", - /* 31 */ "value ::= dotted_name", - /* 32 */ "value ::= list", - /* 33 */ "value ::= map", - /* 34 */ "name_maybe ::=", - /* 35 */ "name_maybe ::= NAME", - /* 36 */ "process_or_template ::= PROCESS", - /* 37 */ "process_or_template ::= TEMPLATE", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - /* TERMINAL Destructor */ - case 1: /* INCLUDE */ - case 2: /* STRING */ - case 3: /* INCLUDE_GUARD */ - case 4: /* NAME */ - case 5: /* CURLY_OPEN */ - case 6: /* CURLY_CLOSE */ - case 7: /* ROUND_OPEN */ - case 8: /* ROUND_CLOSE */ - case 9: /* SEMICOLON */ - case 10: /* ARROW */ - case 11: /* IF */ - case 12: /* FOREACH */ - case 13: /* AS */ - case 14: /* COLON */ - case 15: /* ELIF */ - case 16: /* ELSE */ - case 17: /* DOT */ - case 18: /* COMMA */ - case 19: /* BRACKET_OPEN */ - case 20: /* BRACKET_CLOSE */ - case 21: /* PROCESS */ - case 22: /* TEMPLATE */ -{ -#line 89 "NCDConfigParser_parse.y" - free_token((yypminor->yy0)); -#line 523 "NCDConfigParser_parse.c" -} - break; - case 24: /* processes */ -{ -#line 108 "NCDConfigParser_parse.y" - (void)parser_out; free_program((yypminor->yy54)); -#line 530 "NCDConfigParser_parse.c" -} - break; - case 25: /* statement */ -{ -#line 109 "NCDConfigParser_parse.y" - free_statement((yypminor->yy79)); -#line 537 "NCDConfigParser_parse.c" -} - break; - case 26: /* elif_maybe */ - case 27: /* elif */ -{ -#line 110 "NCDConfigParser_parse.y" - free_ifblock((yypminor->yy76)); -#line 545 "NCDConfigParser_parse.c" -} - break; - case 28: /* else_maybe */ - case 29: /* statements */ -{ -#line 112 "NCDConfigParser_parse.y" - free_block((yypminor->yy37)); -#line 553 "NCDConfigParser_parse.c" -} - break; - case 30: /* dotted_name */ - case 37: /* name_maybe */ -{ -#line 114 "NCDConfigParser_parse.y" - free((yypminor->yy33)); -#line 561 "NCDConfigParser_parse.c" -} - break; - case 31: /* statement_args_maybe */ - case 32: /* list_contents */ - case 33: /* list */ - case 34: /* map_contents */ - case 35: /* map */ - case 36: /* value */ -{ -#line 115 "NCDConfigParser_parse.y" - free_value((yypminor->yy51)); -#line 573 "NCDConfigParser_parse.c" -} - break; - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -** <ul> -** <li> A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -** <li> A pointer to a function used to reclaim memory obtained -** from malloc. -** </ul> -*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) - && (iFallback = yyFallback[iLookAhead])!=0 ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && i<YY_SZ_ACTTAB ); - assert( yy_lookahead[i]==iLookAhead ); -#endif - return yy_action[i]; -} - -/* -** The following routine is called if the stack overflows. -*/ -static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ - ParseARG_FETCH; - yypParser->yyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -#line 130 "NCDConfigParser_parse.y" - - if (yypMinor) { - free_token(yypMinor->yy0); - } -#line 751 "NCDConfigParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 39, 1 }, - { 24, 0 }, - { 24, 3 }, - { 24, 3 }, - { 24, 6 }, - { 25, 6 }, - { 25, 8 }, - { 25, 11 }, - { 25, 11 }, - { 25, 13 }, - { 26, 0 }, - { 26, 1 }, - { 27, 7 }, - { 27, 8 }, - { 28, 0 }, - { 28, 4 }, - { 29, 1 }, - { 29, 2 }, - { 30, 1 }, - { 30, 3 }, - { 31, 0 }, - { 31, 1 }, - { 32, 1 }, - { 32, 3 }, - { 33, 2 }, - { 33, 3 }, - { 34, 3 }, - { 34, 5 }, - { 35, 2 }, - { 35, 3 }, - { 36, 1 }, - { 36, 1 }, - { 36, 1 }, - { 36, 1 }, - { 37, 0 }, - { 37, 1 }, - { 38, 1 }, - { 38, 1 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line <lineno> <grammarfile> - ** { ... } // User supplied code - ** #line <lineno> <thisfile> - ** break; - */ - case 0: /* input ::= processes */ -#line 136 "NCDConfigParser_parse.y" -{ - ASSERT(!parser_out->have_ast) - - if (yymsp[0].minor.yy54.have) { - parser_out->have_ast = 1; - parser_out->ast = yymsp[0].minor.yy54.v; - } -} -#line 910 "NCDConfigParser_parse.c" - break; - case 1: /* processes ::= */ -#line 145 "NCDConfigParser_parse.y" -{ - NCDProgram prog; - NCDProgram_Init(&prog); - - yygotominor.yy54.have = 1; - yygotominor.yy54.v = prog; -} -#line 921 "NCDConfigParser_parse.c" - break; - case 2: /* processes ::= INCLUDE STRING processes */ -#line 153 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-1].minor.yy0.str) - if (!yymsp[0].minor.yy54.have) { - goto failA0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitInclude(&elem, yymsp[-1].minor.yy0.str, yymsp[-1].minor.yy0.len)) { - goto failA0; - } - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy54.v, elem)) { - goto failA1; - } - - yygotominor.yy54.have = 1; - yygotominor.yy54.v = yymsp[0].minor.yy54.v; - yymsp[0].minor.yy54.have = 0; - goto doneA; - -failA1: - NCDProgramElem_Free(&elem); -failA0: - yygotominor.yy54.have = 0; - parser_out->out_of_memory = 1; -doneA: - free_token(yymsp[-1].minor.yy0); - free_program(yymsp[0].minor.yy54); - yy_destructor(yypParser,1,&yymsp[-2].minor); -} -#line 955 "NCDConfigParser_parse.c" - break; - case 3: /* processes ::= INCLUDE_GUARD STRING processes */ -#line 183 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-1].minor.yy0.str) - if (!yymsp[0].minor.yy54.have) { - goto failZ0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitIncludeGuard(&elem, yymsp[-1].minor.yy0.str, yymsp[-1].minor.yy0.len)) { - goto failZ0; - } - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy54.v, elem)) { - goto failZ1; - } - - yygotominor.yy54.have = 1; - yygotominor.yy54.v = yymsp[0].minor.yy54.v; - yymsp[0].minor.yy54.have = 0; - goto doneZ; - -failZ1: - NCDProgramElem_Free(&elem); -failZ0: - yygotominor.yy54.have = 0; - parser_out->out_of_memory = 1; -doneZ: - free_token(yymsp[-1].minor.yy0); - free_program(yymsp[0].minor.yy54); - yy_destructor(yypParser,3,&yymsp[-2].minor); -} -#line 989 "NCDConfigParser_parse.c" - break; - case 4: /* processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes */ -#line 213 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-4].minor.yy0.str) - if (!yymsp[-2].minor.yy37.have || !yymsp[0].minor.yy54.have) { - goto failB0; - } - - NCDProcess proc; - if (!NCDProcess_Init(&proc, yymsp[-5].minor.yy12, yymsp[-4].minor.yy0.str, yymsp[-2].minor.yy37.v)) { - goto failB0; - } - yymsp[-2].minor.yy37.have = 0; - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc); - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy54.v, elem)) { - goto failB1; - } - - yygotominor.yy54.have = 1; - yygotominor.yy54.v = yymsp[0].minor.yy54.v; - yymsp[0].minor.yy54.have = 0; - goto doneB; - -failB1: - NCDProgramElem_Free(&elem); -failB0: - yygotominor.yy54.have = 0; - parser_out->out_of_memory = 1; -doneB: - free_token(yymsp[-4].minor.yy0); - free_block(yymsp[-2].minor.yy37); - free_program(yymsp[0].minor.yy54); - yy_destructor(yypParser,5,&yymsp[-3].minor); - yy_destructor(yypParser,6,&yymsp[-1].minor); -} -#line 1029 "NCDConfigParser_parse.c" - break; - case 5: /* statement ::= dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON */ -#line 248 "NCDConfigParser_parse.y" -{ - if (!yymsp[-5].minor.yy33 || !yymsp[-3].minor.yy51.have) { - goto failC0; - } - - if (!NCDStatement_InitReg(&yygotominor.yy79.v, yymsp[-1].minor.yy33, NULL, yymsp[-5].minor.yy33, yymsp[-3].minor.yy51.v)) { - goto failC0; - } - yymsp[-3].minor.yy51.have = 0; - - yygotominor.yy79.have = 1; - goto doneC; - -failC0: - yygotominor.yy79.have = 0; - parser_out->out_of_memory = 1; -doneC: - free(yymsp[-5].minor.yy33); - free_value(yymsp[-3].minor.yy51); - free(yymsp[-1].minor.yy33); - yy_destructor(yypParser,7,&yymsp[-4].minor); - yy_destructor(yypParser,8,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1057 "NCDConfigParser_parse.c" - break; - case 6: /* statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON */ -#line 270 "NCDConfigParser_parse.y" -{ - if (!yymsp[-7].minor.yy33 || !yymsp[-5].minor.yy33 || !yymsp[-3].minor.yy51.have) { - goto failD0; - } - - if (!NCDStatement_InitReg(&yygotominor.yy79.v, yymsp[-1].minor.yy33, yymsp[-7].minor.yy33, yymsp[-5].minor.yy33, yymsp[-3].minor.yy51.v)) { - goto failD0; - } - yymsp[-3].minor.yy51.have = 0; - - yygotominor.yy79.have = 1; - goto doneD; - -failD0: - yygotominor.yy79.have = 0; - parser_out->out_of_memory = 1; -doneD: - free(yymsp[-7].minor.yy33); - free(yymsp[-5].minor.yy33); - free_value(yymsp[-3].minor.yy51); - free(yymsp[-1].minor.yy33); - yy_destructor(yypParser,10,&yymsp[-6].minor); - yy_destructor(yypParser,7,&yymsp[-4].minor); - yy_destructor(yypParser,8,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1087 "NCDConfigParser_parse.c" - break; - case 7: /* statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON */ -#line 293 "NCDConfigParser_parse.y" -{ - if (!yymsp[-8].minor.yy51.have || !yymsp[-5].minor.yy37.have || !yymsp[-3].minor.yy76.have) { - goto failE0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-8].minor.yy51.v, yymsp[-5].minor.yy37.v); - yymsp[-8].minor.yy51.have = 0; - yymsp[-5].minor.yy37.have = 0; - - if (!NCDIfBlock_PrependIf(&yymsp[-3].minor.yy76.v, ifc)) { - NCDIf_Free(&ifc); - goto failE0; - } - - if (!NCDStatement_InitIf(&yygotominor.yy79.v, yymsp[-1].minor.yy33, yymsp[-3].minor.yy76.v)) { - goto failE0; - } - yymsp[-3].minor.yy76.have = 0; - - if (yymsp[-2].minor.yy37.have) { - NCDStatement_IfAddElse(&yygotominor.yy79.v, yymsp[-2].minor.yy37.v); - yymsp[-2].minor.yy37.have = 0; - } - - yygotominor.yy79.have = 1; - goto doneE; - -failE0: - yygotominor.yy79.have = 0; - parser_out->out_of_memory = 1; -doneE: - free_value(yymsp[-8].minor.yy51); - free_block(yymsp[-5].minor.yy37); - free_ifblock(yymsp[-3].minor.yy76); - free_block(yymsp[-2].minor.yy37); - free(yymsp[-1].minor.yy33); - yy_destructor(yypParser,11,&yymsp[-10].minor); - yy_destructor(yypParser,7,&yymsp[-9].minor); - yy_destructor(yypParser,8,&yymsp[-7].minor); - yy_destructor(yypParser,5,&yymsp[-6].minor); - yy_destructor(yypParser,6,&yymsp[-4].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1135 "NCDConfigParser_parse.c" - break; - case 8: /* statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON */ -#line 332 "NCDConfigParser_parse.y" -{ - if (!yymsp[-8].minor.yy51.have || !yymsp[-6].minor.yy0.str || !yymsp[-3].minor.yy37.have) { - goto failEA0; - } - - if (!NCDStatement_InitForeach(&yygotominor.yy79.v, yymsp[-1].minor.yy33, yymsp[-8].minor.yy51.v, yymsp[-6].minor.yy0.str, NULL, yymsp[-3].minor.yy37.v)) { - goto failEA0; - } - yymsp[-8].minor.yy51.have = 0; - yymsp[-3].minor.yy37.have = 0; - - yygotominor.yy79.have = 1; - goto doneEA0; - -failEA0: - yygotominor.yy79.have = 0; - parser_out->out_of_memory = 1; -doneEA0: - free_value(yymsp[-8].minor.yy51); - free_token(yymsp[-6].minor.yy0); - free_block(yymsp[-3].minor.yy37); - free(yymsp[-1].minor.yy33); - yy_destructor(yypParser,12,&yymsp[-10].minor); - yy_destructor(yypParser,7,&yymsp[-9].minor); - yy_destructor(yypParser,13,&yymsp[-7].minor); - yy_destructor(yypParser,8,&yymsp[-5].minor); - yy_destructor(yypParser,5,&yymsp[-4].minor); - yy_destructor(yypParser,6,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1169 "NCDConfigParser_parse.c" - break; - case 9: /* statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON */ -#line 356 "NCDConfigParser_parse.y" -{ - if (!yymsp[-10].minor.yy51.have || !yymsp[-8].minor.yy0.str || !yymsp[-6].minor.yy0.str || !yymsp[-3].minor.yy37.have) { - goto failEB0; - } - - if (!NCDStatement_InitForeach(&yygotominor.yy79.v, yymsp[-1].minor.yy33, yymsp[-10].minor.yy51.v, yymsp[-8].minor.yy0.str, yymsp[-6].minor.yy0.str, yymsp[-3].minor.yy37.v)) { - goto failEB0; - } - yymsp[-10].minor.yy51.have = 0; - yymsp[-3].minor.yy37.have = 0; - - yygotominor.yy79.have = 1; - goto doneEB0; - -failEB0: - yygotominor.yy79.have = 0; - parser_out->out_of_memory = 1; -doneEB0: - free_value(yymsp[-10].minor.yy51); - free_token(yymsp[-8].minor.yy0); - free_token(yymsp[-6].minor.yy0); - free_block(yymsp[-3].minor.yy37); - free(yymsp[-1].minor.yy33); - yy_destructor(yypParser,12,&yymsp[-12].minor); - yy_destructor(yypParser,7,&yymsp[-11].minor); - yy_destructor(yypParser,13,&yymsp[-9].minor); - yy_destructor(yypParser,14,&yymsp[-7].minor); - yy_destructor(yypParser,8,&yymsp[-5].minor); - yy_destructor(yypParser,5,&yymsp[-4].minor); - yy_destructor(yypParser,6,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1205 "NCDConfigParser_parse.c" - break; - case 10: /* elif_maybe ::= */ -#line 381 "NCDConfigParser_parse.y" -{ - NCDIfBlock_Init(&yygotominor.yy76.v); - yygotominor.yy76.have = 1; -} -#line 1213 "NCDConfigParser_parse.c" - break; - case 11: /* elif_maybe ::= elif */ -#line 386 "NCDConfigParser_parse.y" -{ - yygotominor.yy76 = yymsp[0].minor.yy76; -} -#line 1220 "NCDConfigParser_parse.c" - break; - case 12: /* elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE */ -#line 390 "NCDConfigParser_parse.y" -{ - if (!yymsp[-4].minor.yy51.have || !yymsp[-1].minor.yy37.have) { - goto failF0; - } - - NCDIfBlock_Init(&yygotominor.yy76.v); - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-4].minor.yy51.v, yymsp[-1].minor.yy37.v); - yymsp[-4].minor.yy51.have = 0; - yymsp[-1].minor.yy37.have = 0; - - if (!NCDIfBlock_PrependIf(&yygotominor.yy76.v, ifc)) { - goto failF1; - } - - yygotominor.yy76.have = 1; - goto doneF0; - -failF1: - NCDIf_Free(&ifc); - NCDIfBlock_Free(&yygotominor.yy76.v); -failF0: - yygotominor.yy76.have = 0; - parser_out->out_of_memory = 1; -doneF0: - free_value(yymsp[-4].minor.yy51); - free_block(yymsp[-1].minor.yy37); - yy_destructor(yypParser,15,&yymsp[-6].minor); - yy_destructor(yypParser,7,&yymsp[-5].minor); - yy_destructor(yypParser,8,&yymsp[-3].minor); - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1258 "NCDConfigParser_parse.c" - break; - case 13: /* elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif */ -#line 420 "NCDConfigParser_parse.y" -{ - if (!yymsp[-5].minor.yy51.have || !yymsp[-2].minor.yy37.have || !yymsp[0].minor.yy76.have) { - goto failG0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-5].minor.yy51.v, yymsp[-2].minor.yy37.v); - yymsp[-5].minor.yy51.have = 0; - yymsp[-2].minor.yy37.have = 0; - - if (!NCDIfBlock_PrependIf(&yymsp[0].minor.yy76.v, ifc)) { - goto failG1; - } - - yygotominor.yy76.have = 1; - yygotominor.yy76.v = yymsp[0].minor.yy76.v; - yymsp[0].minor.yy76.have = 0; - goto doneG0; - -failG1: - NCDIf_Free(&ifc); -failG0: - yygotominor.yy76.have = 0; - parser_out->out_of_memory = 1; -doneG0: - free_value(yymsp[-5].minor.yy51); - free_block(yymsp[-2].minor.yy37); - free_ifblock(yymsp[0].minor.yy76); - yy_destructor(yypParser,15,&yymsp[-7].minor); - yy_destructor(yypParser,7,&yymsp[-6].minor); - yy_destructor(yypParser,8,&yymsp[-4].minor); - yy_destructor(yypParser,5,&yymsp[-3].minor); - yy_destructor(yypParser,6,&yymsp[-1].minor); -} -#line 1296 "NCDConfigParser_parse.c" - break; - case 14: /* else_maybe ::= */ -#line 450 "NCDConfigParser_parse.y" -{ - yygotominor.yy37.have = 0; -} -#line 1303 "NCDConfigParser_parse.c" - break; - case 15: /* else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE */ -#line 454 "NCDConfigParser_parse.y" -{ - yygotominor.yy37 = yymsp[-1].minor.yy37; - yy_destructor(yypParser,16,&yymsp[-3].minor); - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1313 "NCDConfigParser_parse.c" - break; - case 16: /* statements ::= statement */ -#line 458 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy79.have) { - goto failH0; - } - - NCDBlock_Init(&yygotominor.yy37.v); - - if (!NCDBlock_PrependStatement(&yygotominor.yy37.v, yymsp[0].minor.yy79.v)) { - goto failH1; - } - yymsp[0].minor.yy79.have = 0; - - yygotominor.yy37.have = 1; - goto doneH; - -failH1: - NCDBlock_Free(&yygotominor.yy37.v); -failH0: - yygotominor.yy37.have = 0; - parser_out->out_of_memory = 1; -doneH: - free_statement(yymsp[0].minor.yy79); -} -#line 1340 "NCDConfigParser_parse.c" - break; - case 17: /* statements ::= statement statements */ -#line 482 "NCDConfigParser_parse.y" -{ - if (!yymsp[-1].minor.yy79.have || !yymsp[0].minor.yy37.have) { - goto failI0; - } - - if (!NCDBlock_PrependStatement(&yymsp[0].minor.yy37.v, yymsp[-1].minor.yy79.v)) { - goto failI1; - } - yymsp[-1].minor.yy79.have = 0; - - yygotominor.yy37.have = 1; - yygotominor.yy37.v = yymsp[0].minor.yy37.v; - yymsp[0].minor.yy37.have = 0; - goto doneI; - -failI1: - NCDBlock_Free(&yygotominor.yy37.v); -failI0: - yygotominor.yy37.have = 0; - parser_out->out_of_memory = 1; -doneI: - free_statement(yymsp[-1].minor.yy79); - free_block(yymsp[0].minor.yy37); -} -#line 1368 "NCDConfigParser_parse.c" - break; - case 18: /* dotted_name ::= NAME */ - case 35: /* name_maybe ::= NAME */ yytestcase(yyruleno==35); -#line 507 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - yygotominor.yy33 = yymsp[0].minor.yy0.str; -} -#line 1378 "NCDConfigParser_parse.c" - break; - case 19: /* dotted_name ::= NAME DOT dotted_name */ -#line 513 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-2].minor.yy0.str) - if (!yymsp[0].minor.yy33) { - goto failJ0; - } - - if (!(yygotominor.yy33 = concat_strings(3, yymsp[-2].minor.yy0.str, ".", yymsp[0].minor.yy33))) { - goto failJ0; - } - - goto doneJ; - -failJ0: - yygotominor.yy33 = NULL; - parser_out->out_of_memory = 1; -doneJ: - free_token(yymsp[-2].minor.yy0); - free(yymsp[0].minor.yy33); - yy_destructor(yypParser,17,&yymsp[-1].minor); -} -#line 1402 "NCDConfigParser_parse.c" - break; - case 20: /* statement_args_maybe ::= */ -#line 533 "NCDConfigParser_parse.y" -{ - yygotominor.yy51.have = 1; - NCDValue_InitList(&yygotominor.yy51.v); -} -#line 1410 "NCDConfigParser_parse.c" - break; - case 21: /* statement_args_maybe ::= list_contents */ - case 32: /* value ::= list */ yytestcase(yyruleno==32); - case 33: /* value ::= map */ yytestcase(yyruleno==33); -#line 538 "NCDConfigParser_parse.y" -{ - yygotominor.yy51 = yymsp[0].minor.yy51; -} -#line 1419 "NCDConfigParser_parse.c" - break; - case 22: /* list_contents ::= value */ -#line 542 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy51.have) { - goto failL0; - } - - NCDValue_InitList(&yygotominor.yy51.v); - - if (!NCDValue_ListPrepend(&yygotominor.yy51.v, yymsp[0].minor.yy51.v)) { - goto failL1; - } - yymsp[0].minor.yy51.have = 0; - - yygotominor.yy51.have = 1; - goto doneL; - -failL1: - NCDValue_Free(&yygotominor.yy51.v); -failL0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneL: - free_value(yymsp[0].minor.yy51); -} -#line 1446 "NCDConfigParser_parse.c" - break; - case 23: /* list_contents ::= value COMMA list_contents */ -#line 566 "NCDConfigParser_parse.y" -{ - if (!yymsp[-2].minor.yy51.have || !yymsp[0].minor.yy51.have) { - goto failM0; - } - - if (!NCDValue_ListPrepend(&yymsp[0].minor.yy51.v, yymsp[-2].minor.yy51.v)) { - goto failM0; - } - yymsp[-2].minor.yy51.have = 0; - - yygotominor.yy51.have = 1; - yygotominor.yy51.v = yymsp[0].minor.yy51.v; - yymsp[0].minor.yy51.have = 0; - goto doneM; - -failM0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneM: - free_value(yymsp[-2].minor.yy51); - free_value(yymsp[0].minor.yy51); - yy_destructor(yypParser,18,&yymsp[-1].minor); -} -#line 1473 "NCDConfigParser_parse.c" - break; - case 24: /* list ::= CURLY_OPEN CURLY_CLOSE */ -#line 589 "NCDConfigParser_parse.y" -{ - yygotominor.yy51.have = 1; - NCDValue_InitList(&yygotominor.yy51.v); - yy_destructor(yypParser,5,&yymsp[-1].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1483 "NCDConfigParser_parse.c" - break; - case 25: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */ -#line 594 "NCDConfigParser_parse.y" -{ - yygotominor.yy51 = yymsp[-1].minor.yy51; - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1492 "NCDConfigParser_parse.c" - break; - case 26: /* map_contents ::= value COLON value */ -#line 598 "NCDConfigParser_parse.y" -{ - if (!yymsp[-2].minor.yy51.have || !yymsp[0].minor.yy51.have) { - goto failS0; - } - - NCDValue_InitMap(&yygotominor.yy51.v); - - if (!NCDValue_MapPrepend(&yygotominor.yy51.v, yymsp[-2].minor.yy51.v, yymsp[0].minor.yy51.v)) { - goto failS1; - } - yymsp[-2].minor.yy51.have = 0; - yymsp[0].minor.yy51.have = 0; - - yygotominor.yy51.have = 1; - goto doneS; - -failS1: - NCDValue_Free(&yygotominor.yy51.v); -failS0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneS: - free_value(yymsp[-2].minor.yy51); - free_value(yymsp[0].minor.yy51); - yy_destructor(yypParser,14,&yymsp[-1].minor); -} -#line 1522 "NCDConfigParser_parse.c" - break; - case 27: /* map_contents ::= value COLON value COMMA map_contents */ -#line 624 "NCDConfigParser_parse.y" -{ - if (!yymsp[-4].minor.yy51.have || !yymsp[-2].minor.yy51.have || !yymsp[0].minor.yy51.have) { - goto failT0; - } - - if (!NCDValue_MapPrepend(&yymsp[0].minor.yy51.v, yymsp[-4].minor.yy51.v, yymsp[-2].minor.yy51.v)) { - goto failT0; - } - yymsp[-4].minor.yy51.have = 0; - yymsp[-2].minor.yy51.have = 0; - - yygotominor.yy51.have = 1; - yygotominor.yy51.v = yymsp[0].minor.yy51.v; - yymsp[0].minor.yy51.have = 0; - goto doneT; - -failT0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneT: - free_value(yymsp[-4].minor.yy51); - free_value(yymsp[-2].minor.yy51); - free_value(yymsp[0].minor.yy51); - yy_destructor(yypParser,14,&yymsp[-3].minor); - yy_destructor(yypParser,18,&yymsp[-1].minor); -} -#line 1552 "NCDConfigParser_parse.c" - break; - case 28: /* map ::= BRACKET_OPEN BRACKET_CLOSE */ -#line 649 "NCDConfigParser_parse.y" -{ - yygotominor.yy51.have = 1; - NCDValue_InitMap(&yygotominor.yy51.v); - yy_destructor(yypParser,19,&yymsp[-1].minor); - yy_destructor(yypParser,20,&yymsp[0].minor); -} -#line 1562 "NCDConfigParser_parse.c" - break; - case 29: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */ -#line 654 "NCDConfigParser_parse.y" -{ - yygotominor.yy51 = yymsp[-1].minor.yy51; - yy_destructor(yypParser,19,&yymsp[-2].minor); - yy_destructor(yypParser,20,&yymsp[0].minor); -} -#line 1571 "NCDConfigParser_parse.c" - break; - case 30: /* value ::= STRING */ -#line 658 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - if (!NCDValue_InitStringBin(&yygotominor.yy51.v, (uint8_t *)yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len)) { - goto failU0; - } - - yygotominor.yy51.have = 1; - goto doneU; - -failU0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneU: - free_token(yymsp[0].minor.yy0); -} -#line 1591 "NCDConfigParser_parse.c" - break; - case 31: /* value ::= dotted_name */ -#line 675 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy33) { - goto failV0; - } - - if (!NCDValue_InitVar(&yygotominor.yy51.v, yymsp[0].minor.yy33)) { - goto failV0; - } - - yygotominor.yy51.have = 1; - goto doneV; - -failV0: - yygotominor.yy51.have = 0; - parser_out->out_of_memory = 1; -doneV: - free(yymsp[0].minor.yy33); -} -#line 1613 "NCDConfigParser_parse.c" - break; - case 34: /* name_maybe ::= */ -#line 702 "NCDConfigParser_parse.y" -{ - yygotominor.yy33 = NULL; -} -#line 1620 "NCDConfigParser_parse.c" - break; - case 36: /* process_or_template ::= PROCESS */ -#line 712 "NCDConfigParser_parse.y" -{ - yygotominor.yy12 = 0; - yy_destructor(yypParser,21,&yymsp[0].minor); -} -#line 1628 "NCDConfigParser_parse.c" - break; - case 37: /* process_or_template ::= TEMPLATE */ -#line 716 "NCDConfigParser_parse.y" -{ - yygotominor.yy12 = 1; - yy_destructor(yypParser,22,&yymsp[0].minor); -} -#line 1636 "NCDConfigParser_parse.c" - break; - default: - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 125 "NCDConfigParser_parse.y" - - parser_out->syntax_error = 1; -#line 1701 "NCDConfigParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -** <ul> -** <li> A pointer to the parser (an opaque structure.) -** <li> The major token number. -** <li> The minor token number. -** <li> An option argument of a grammar-specified type. -** </ul> -** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact<YYNSTATE ){ - assert( !yyendofinput ); /* Impossible to shift the $ token */ - yy_shift(yypParser,yyact,yymajor,&yyminorunion); - yypParser->yyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/external/badvpn_dns/generated/NCDConfigParser_parse.h b/external/badvpn_dns/generated/NCDConfigParser_parse.h deleted file mode 100644 index 086a574..0000000 --- a/external/badvpn_dns/generated/NCDConfigParser_parse.h +++ /dev/null @@ -1,22 +0,0 @@ -#define INCLUDE 1 -#define STRING 2 -#define INCLUDE_GUARD 3 -#define NAME 4 -#define CURLY_OPEN 5 -#define CURLY_CLOSE 6 -#define ROUND_OPEN 7 -#define ROUND_CLOSE 8 -#define SEMICOLON 9 -#define ARROW 10 -#define IF 11 -#define FOREACH 12 -#define AS 13 -#define COLON 14 -#define ELIF 15 -#define ELSE 16 -#define DOT 17 -#define COMMA 18 -#define BRACKET_OPEN 19 -#define BRACKET_CLOSE 20 -#define PROCESS 21 -#define TEMPLATE 22 diff --git a/external/badvpn_dns/generated/NCDConfigParser_parse.out b/external/badvpn_dns/generated/NCDConfigParser_parse.out deleted file mode 100644 index bdf830b..0000000 --- a/external/badvpn_dns/generated/NCDConfigParser_parse.out +++ /dev/null @@ -1,950 +0,0 @@ -State 0: - input ::= * processes - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 34 - INCLUDE_GUARD shift 35 - PROCESS shift 75 - TEMPLATE shift 76 - processes shift 33 - process_or_template shift 36 - input accept - {default} reduce 1 - -State 1: - statement ::= dotted_name ROUND_OPEN * statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - (20) statement_args_maybe ::= * - statement_args_maybe ::= * list_contents - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - statement_args_maybe shift 39 - list_contents shift 80 - list shift 87 - map shift 88 - value shift 42 - {default} reduce 20 - -State 2: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN * statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - (20) statement_args_maybe ::= * - statement_args_maybe ::= * list_contents - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - statement_args_maybe shift 48 - list_contents shift 80 - list shift 87 - map shift 88 - value shift 42 - {default} reduce 20 - -State 3: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= CURLY_OPEN * CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - list ::= CURLY_OPEN * list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - CURLY_CLOSE shift 82 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list_contents shift 43 - list shift 87 - map shift 88 - value shift 42 - -State 4: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= BRACKET_OPEN * BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - map ::= BRACKET_OPEN * map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - BRACKET_CLOSE shift 89 - dotted_name shift 86 - list shift 87 - map_contents shift 46 - map shift 88 - value shift 44 - -State 5: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list_contents ::= value COMMA * list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list_contents shift 81 - list shift 87 - map shift 88 - value shift 42 - -State 6: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map_contents ::= value COLON value COMMA * map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list shift 87 - map_contents shift 84 - map shift 88 - value shift 44 - -State 7: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= value COLON * value - map_contents ::= value COLON * value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list shift 87 - map shift 88 - value shift 45 - -State 8: - statement ::= IF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list shift 87 - map shift 88 - value shift 51 - -State 9: - statement ::= FOREACH ROUND_OPEN * value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN * value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list shift 87 - map shift 88 - value shift 57 - -State 10: - elif ::= ELIF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * dotted_name - value ::= * list - value ::= * map - - STRING shift 85 - NAME shift 41 - CURLY_OPEN shift 3 - BRACKET_OPEN shift 4 - dotted_name shift 86 - list shift 87 - map shift 88 - value shift 69 - -State 11: - processes ::= process_or_template NAME CURLY_OPEN * statements CURLY_CLOSE processes - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 38 - dotted_name shift 31 - -State 12: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 53 - dotted_name shift 31 - -State 13: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - else_maybe ::= ELSE CURLY_OPEN * statements CURLY_CLOSE - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 67 - dotted_name shift 31 - -State 14: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 60 - dotted_name shift 31 - -State 15: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statements ::= * statement - (16) statements ::= statement * - statements ::= * statement statements - statements ::= statement * statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 94 - dotted_name shift 31 - {default} reduce 16 - -State 16: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 65 - dotted_name shift 31 - -State 17: - statement ::= * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE elif - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - IF shift 50 - FOREACH shift 56 - statement shift 15 - statements shift 71 - dotted_name shift 31 - -State 18: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= INCLUDE STRING * processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 34 - INCLUDE_GUARD shift 35 - PROCESS shift 75 - TEMPLATE shift 76 - processes shift 72 - process_or_template shift 36 - {default} reduce 1 - -State 19: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= INCLUDE_GUARD STRING * processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 34 - INCLUDE_GUARD shift 35 - PROCESS shift 75 - TEMPLATE shift 76 - processes shift 73 - process_or_template shift 36 - {default} reduce 1 - -State 20: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE * processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 34 - INCLUDE_GUARD shift 35 - PROCESS shift 75 - TEMPLATE shift 76 - processes shift 74 - process_or_template shift 36 - {default} reduce 1 - -State 21: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * elif_maybe else_maybe name_maybe SEMICOLON - (10) elif_maybe ::= * - elif_maybe ::= * elif - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - - ELIF shift 68 - elif_maybe shift 26 - elif shift 97 - {default} reduce 10 - -State 22: - statement ::= dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE * name_maybe SEMICOLON - (34) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 78 - name_maybe shift 40 - {default} reduce 34 - -State 23: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - dotted_name ::= NAME DOT * dotted_name - - NAME shift 41 - dotted_name shift 79 - -State 24: - statement ::= dotted_name ARROW * dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 41 - dotted_name shift 47 - -State 25: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE * name_maybe SEMICOLON - (34) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 78 - name_maybe shift 49 - {default} reduce 34 - -State 26: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe * else_maybe name_maybe SEMICOLON - (14) else_maybe ::= * - else_maybe ::= * ELSE CURLY_OPEN statements CURLY_CLOSE - - ELSE shift 55 - else_maybe shift 27 - {default} reduce 14 - -State 27: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe * name_maybe SEMICOLON - (34) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 78 - name_maybe shift 54 - {default} reduce 34 - -State 28: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * name_maybe SEMICOLON - (34) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 78 - name_maybe shift 61 - {default} reduce 34 - -State 29: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * name_maybe SEMICOLON - (34) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 78 - name_maybe shift 66 - {default} reduce 34 - -State 30: - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - (12) elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * elif - - ELIF shift 68 - elif shift 98 - {default} reduce 12 - -State 31: - statement ::= dotted_name * ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= dotted_name * ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 1 - ARROW shift 24 - -State 32: - statement ::= FOREACH ROUND_OPEN value AS NAME * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME * COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 59 - COLON shift 62 - -State 33: - (0) input ::= processes * - - $ reduce 0 - -State 34: - processes ::= INCLUDE * STRING processes - - STRING shift 18 - -State 35: - processes ::= INCLUDE_GUARD * STRING processes - - STRING shift 19 - -State 36: - processes ::= process_or_template * NAME CURLY_OPEN statements CURLY_CLOSE processes - - NAME shift 37 - -State 37: - processes ::= process_or_template NAME * CURLY_OPEN statements CURLY_CLOSE processes - - CURLY_OPEN shift 11 - -State 38: - processes ::= process_or_template NAME CURLY_OPEN statements * CURLY_CLOSE processes - - CURLY_CLOSE shift 20 - -State 39: - statement ::= dotted_name ROUND_OPEN statement_args_maybe * ROUND_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 22 - -State 40: - statement ::= dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 77 - -State 41: - (18) dotted_name ::= NAME * - dotted_name ::= NAME * DOT dotted_name - - DOT shift 23 - {default} reduce 18 - -State 42: - (22) list_contents ::= value * - list_contents ::= value * COMMA list_contents - - COMMA shift 5 - {default} reduce 22 - -State 43: - list ::= CURLY_OPEN list_contents * CURLY_CLOSE - - CURLY_CLOSE shift 83 - -State 44: - map_contents ::= value * COLON value - map_contents ::= value * COLON value COMMA map_contents - - COLON shift 7 - -State 45: - (26) map_contents ::= value COLON value * - map_contents ::= value COLON value * COMMA map_contents - - COMMA shift 6 - {default} reduce 26 - -State 46: - map ::= BRACKET_OPEN map_contents * BRACKET_CLOSE - - BRACKET_CLOSE shift 90 - -State 47: - statement ::= dotted_name ARROW dotted_name * ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 2 - -State 48: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe * ROUND_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 25 - -State 49: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 91 - -State 50: - statement ::= IF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - ROUND_OPEN shift 8 - -State 51: - statement ::= IF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - ROUND_CLOSE shift 52 - -State 52: - statement ::= IF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - CURLY_OPEN shift 12 - -State 53: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - CURLY_CLOSE shift 21 - -State 54: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe * SEMICOLON - - SEMICOLON shift 92 - -State 55: - else_maybe ::= ELSE * CURLY_OPEN statements CURLY_CLOSE - - CURLY_OPEN shift 13 - -State 56: - statement ::= FOREACH * ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH * ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 9 - -State 57: - statement ::= FOREACH ROUND_OPEN value * AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value * AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - AS shift 58 - -State 58: - statement ::= FOREACH ROUND_OPEN value AS * NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS * NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - NAME shift 32 - -State 59: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - CURLY_OPEN shift 14 - -State 60: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE name_maybe SEMICOLON - - CURLY_CLOSE shift 28 - -State 61: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 93 - -State 62: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON * NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - NAME shift 63 - -State 63: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 64 - -State 64: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - CURLY_OPEN shift 16 - -State 65: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE name_maybe SEMICOLON - - CURLY_CLOSE shift 29 - -State 66: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 95 - -State 67: - else_maybe ::= ELSE CURLY_OPEN statements * CURLY_CLOSE - - CURLY_CLOSE shift 96 - -State 68: - elif ::= ELIF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - - ROUND_OPEN shift 10 - -State 69: - elif ::= ELIF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - - ROUND_CLOSE shift 70 - -State 70: - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE elif - - CURLY_OPEN shift 17 - -State 71: - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE elif - - CURLY_CLOSE shift 30 - -State 72: - (2) processes ::= INCLUDE STRING processes * - - {default} reduce 2 - -State 73: - (3) processes ::= INCLUDE_GUARD STRING processes * - - {default} reduce 3 - -State 74: - (4) processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes * - - {default} reduce 4 - -State 75: - (36) process_or_template ::= PROCESS * - - {default} reduce 36 - -State 76: - (37) process_or_template ::= TEMPLATE * - - {default} reduce 37 - -State 77: - (5) statement ::= dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON * - - {default} reduce 5 - -State 78: - (35) name_maybe ::= NAME * - - {default} reduce 35 - -State 79: - (19) dotted_name ::= NAME DOT dotted_name * - - {default} reduce 19 - -State 80: - (21) statement_args_maybe ::= list_contents * - - {default} reduce 21 - -State 81: - (23) list_contents ::= value COMMA list_contents * - - {default} reduce 23 - -State 82: - (24) list ::= CURLY_OPEN CURLY_CLOSE * - - {default} reduce 24 - -State 83: - (25) list ::= CURLY_OPEN list_contents CURLY_CLOSE * - - {default} reduce 25 - -State 84: - (27) map_contents ::= value COLON value COMMA map_contents * - - {default} reduce 27 - -State 85: - (30) value ::= STRING * - - {default} reduce 30 - -State 86: - (31) value ::= dotted_name * - - {default} reduce 31 - -State 87: - (32) value ::= list * - - {default} reduce 32 - -State 88: - (33) value ::= map * - - {default} reduce 33 - -State 89: - (28) map ::= BRACKET_OPEN BRACKET_CLOSE * - - {default} reduce 28 - -State 90: - (29) map ::= BRACKET_OPEN map_contents BRACKET_CLOSE * - - {default} reduce 29 - -State 91: - (6) statement ::= dotted_name ARROW dotted_name ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON * - - {default} reduce 6 - -State 92: - (7) statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON * - - {default} reduce 7 - -State 93: - (8) statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON * - - {default} reduce 8 - -State 94: - (17) statements ::= statement statements * - - {default} reduce 17 - -State 95: - (9) statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON * - - {default} reduce 9 - -State 96: - (15) else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE * - - {default} reduce 15 - -State 97: - (11) elif_maybe ::= elif * - - {default} reduce 11 - -State 98: - (13) elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif * - - {default} reduce 13 - ----------------------------------------------------- -Symbols: - 0: $: - 1: INCLUDE - 2: STRING - 3: INCLUDE_GUARD - 4: NAME - 5: CURLY_OPEN - 6: CURLY_CLOSE - 7: ROUND_OPEN - 8: ROUND_CLOSE - 9: SEMICOLON - 10: ARROW - 11: IF - 12: FOREACH - 13: AS - 14: COLON - 15: ELIF - 16: ELSE - 17: DOT - 18: COMMA - 19: BRACKET_OPEN - 20: BRACKET_CLOSE - 21: PROCESS - 22: TEMPLATE - 23: error: - 24: processes: <lambda> INCLUDE INCLUDE_GUARD PROCESS TEMPLATE - 25: statement: NAME IF FOREACH - 26: elif_maybe: <lambda> ELIF - 27: elif: ELIF - 28: else_maybe: <lambda> ELSE - 29: statements: NAME IF FOREACH - 30: dotted_name: NAME - 31: statement_args_maybe: <lambda> STRING NAME CURLY_OPEN BRACKET_OPEN - 32: list_contents: STRING NAME CURLY_OPEN BRACKET_OPEN - 33: list: CURLY_OPEN - 34: map_contents: STRING NAME CURLY_OPEN BRACKET_OPEN - 35: map: BRACKET_OPEN - 36: value: STRING NAME CURLY_OPEN BRACKET_OPEN - 37: name_maybe: <lambda> NAME - 38: process_or_template: PROCESS TEMPLATE - 39: input: INCLUDE INCLUDE_GUARD PROCESS TEMPLATE diff --git a/external/badvpn_dns/generated/NCDConfigParser_parse.y b/external/badvpn_dns/generated/NCDConfigParser_parse.y deleted file mode 100644 index fdf89f6..0000000 --- a/external/badvpn_dns/generated/NCDConfigParser_parse.y +++ /dev/null @@ -1,718 +0,0 @@ -/** - * @file NCDConfigParser.y - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -%include { - -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/concat_strings.h> -#include <ncd/NCDAst.h> - -struct parser_out { - int out_of_memory; - int syntax_error; - int have_ast; - NCDProgram ast; -}; - -struct token { - char *str; - size_t len; -}; - -struct program { - int have; - NCDProgram v; -}; - -struct block { - int have; - NCDBlock v; -}; - -struct statement { - int have; - NCDStatement v; -}; - -struct ifblock { - int have; - NCDIfBlock v; -}; - -struct value { - int have; - NCDValue v; -}; - -static void free_token (struct token o) { free(o.str); } -static void free_program (struct program o) { if (o.have) NCDProgram_Free(&o.v); } -static void free_block (struct block o) { if (o.have) NCDBlock_Free(&o.v); } -static void free_statement (struct statement o) { if (o.have) NCDStatement_Free(&o.v); } -static void free_ifblock (struct ifblock o) { if (o.have) NCDIfBlock_Free(&o.v); } -static void free_value (struct value o) { if (o.have) NCDValue_Free(&o.v); } - -} - -%extra_argument { struct parser_out *parser_out } - -%token_type { struct token } - -%token_destructor { free_token($$); } - -%type processes { struct program } -%type statement { struct statement } -%type elif_maybe { struct ifblock } -%type elif { struct ifblock } -%type else_maybe { struct block } -%type statements { struct block } -%type dotted_name { char * } -%type statement_args_maybe { struct value } -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type value { struct value } -%type name_maybe { char * } -%type process_or_template { int } - -// mention parser_out in some destructor to a void unused variable warning -%destructor processes { (void)parser_out; free_program($$); } -%destructor statement { free_statement($$); } -%destructor elif_maybe { free_ifblock($$); } -%destructor elif { free_ifblock($$); } -%destructor else_maybe { free_block($$); } -%destructor statements { free_block($$); } -%destructor dotted_name { free($$); } -%destructor statement_args_maybe { free_value($$); } -%destructor list_contents { free_value($$); } -%destructor list { free_value($$); } -%destructor map_contents { free_value($$); } -%destructor map { free_value($$); } -%destructor value { free_value($$); } -%destructor name_maybe { free($$); } - -%stack_size 0 - -%syntax_error { - parser_out->syntax_error = 1; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= processes(A). { - ASSERT(!parser_out->have_ast) - - if (A.have) { - parser_out->have_ast = 1; - parser_out->ast = A.v; - } -} - -processes(R) ::= . { - NCDProgram prog; - NCDProgram_Init(&prog); - - R.have = 1; - R.v = prog; -} - -processes(R) ::= INCLUDE STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failA0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitInclude(&elem, A.str, A.len)) { - goto failA0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failA1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneA; - -failA1: - NCDProgramElem_Free(&elem); -failA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneA: - free_token(A); - free_program(N); -} - -processes(R) ::= INCLUDE_GUARD STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failZ0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitIncludeGuard(&elem, A.str, A.len)) { - goto failZ0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failZ1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneZ; - -failZ1: - NCDProgramElem_Free(&elem); -failZ0: - R.have = 0; - parser_out->out_of_memory = 1; -doneZ: - free_token(A); - free_program(N); -} - -processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE processes(N). { - ASSERT(A.str) - if (!B.have || !N.have) { - goto failB0; - } - - NCDProcess proc; - if (!NCDProcess_Init(&proc, T, A.str, B.v)) { - goto failB0; - } - B.have = 0; - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc); - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failB1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneB; - -failB1: - NCDProgramElem_Free(&elem); -failB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneB: - free_token(A); - free_block(B); - free_program(N); -} - -statement(R) ::= dotted_name(A) ROUND_OPEN statement_args_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!A || !B.have) { - goto failC0; - } - - if (!NCDStatement_InitReg(&R.v, C, NULL, A, B.v)) { - goto failC0; - } - B.have = 0; - - R.have = 1; - goto doneC; - -failC0: - R.have = 0; - parser_out->out_of_memory = 1; -doneC: - free(A); - free_value(B); - free(C); -} - -statement(R) ::= dotted_name(M) ARROW dotted_name(A) ROUND_OPEN statement_args_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!M || !A || !B.have) { - goto failD0; - } - - if (!NCDStatement_InitReg(&R.v, C, M, A, B.v)) { - goto failD0; - } - B.have = 0; - - R.have = 1; - goto doneD; - -failD0: - R.have = 0; - parser_out->out_of_memory = 1; -doneD: - free(M); - free(A); - free_value(B); - free(C); -} - -statement(R) ::= IF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif_maybe(I) else_maybe(E) name_maybe(C) SEMICOLON. { - if (!A.have || !B.have || !I.have) { - goto failE0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&I.v, ifc)) { - NCDIf_Free(&ifc); - goto failE0; - } - - if (!NCDStatement_InitIf(&R.v, C, I.v)) { - goto failE0; - } - I.have = 0; - - if (E.have) { - NCDStatement_IfAddElse(&R.v, E.v); - E.have = 0; - } - - R.have = 1; - goto doneE; - -failE0: - R.have = 0; - parser_out->out_of_memory = 1; -doneE: - free_value(A); - free_block(B); - free_ifblock(I); - free_block(E); - free(C); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !S.have) { - goto failEA0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, NULL, S.v)) { - goto failEA0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEA0; - -failEA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEA0: - free_value(A); - free_token(B); - free_block(S); - free(N); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) COLON NAME(C) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !C.str || !S.have) { - goto failEB0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, C.str, S.v)) { - goto failEB0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEB0; - -failEB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEB0: - free_value(A); - free_token(B); - free_token(C); - free_block(S); - free(N); -} - -elif_maybe(R) ::= . { - NCDIfBlock_Init(&R.v); - R.have = 1; -} - -elif_maybe(R) ::= elif(A). { - R = A; -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE. { - if (!A.have || !B.have) { - goto failF0; - } - - NCDIfBlock_Init(&R.v); - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&R.v, ifc)) { - goto failF1; - } - - R.have = 1; - goto doneF0; - -failF1: - NCDIf_Free(&ifc); - NCDIfBlock_Free(&R.v); -failF0: - R.have = 0; - parser_out->out_of_memory = 1; -doneF0: - free_value(A); - free_block(B); -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif(N). { - if (!A.have || !B.have || !N.have) { - goto failG0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&N.v, ifc)) { - goto failG1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneG0; - -failG1: - NCDIf_Free(&ifc); -failG0: - R.have = 0; - parser_out->out_of_memory = 1; -doneG0: - free_value(A); - free_block(B); - free_ifblock(N); -} - -else_maybe(R) ::= . { - R.have = 0; -} - -else_maybe(R) ::= ELSE CURLY_OPEN statements(B) CURLY_CLOSE. { - R = B; -} - -statements(R) ::= statement(A). { - if (!A.have) { - goto failH0; - } - - NCDBlock_Init(&R.v); - - if (!NCDBlock_PrependStatement(&R.v, A.v)) { - goto failH1; - } - A.have = 0; - - R.have = 1; - goto doneH; - -failH1: - NCDBlock_Free(&R.v); -failH0: - R.have = 0; - parser_out->out_of_memory = 1; -doneH: - free_statement(A); -} - -statements(R) ::= statement(A) statements(N). { - if (!A.have || !N.have) { - goto failI0; - } - - if (!NCDBlock_PrependStatement(&N.v, A.v)) { - goto failI1; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneI; - -failI1: - NCDBlock_Free(&R.v); -failI0: - R.have = 0; - parser_out->out_of_memory = 1; -doneI: - free_statement(A); - free_block(N); -} - -dotted_name(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -dotted_name(R) ::= NAME(A) DOT dotted_name(N). { - ASSERT(A.str) - if (!N) { - goto failJ0; - } - - if (!(R = concat_strings(3, A.str, ".", N))) { - goto failJ0; - } - - goto doneJ; - -failJ0: - R = NULL; - parser_out->out_of_memory = 1; -doneJ: - free_token(A); - free(N); -} - -statement_args_maybe(R) ::= . { - R.have = 1; - NCDValue_InitList(&R.v); -} - -statement_args_maybe(R) ::= list_contents(A). { - R = A; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValue_InitList(&R.v); - - if (!NCDValue_ListPrepend(&R.v, A.v)) { - goto failL1; - } - A.have = 0; - - R.have = 1; - goto doneL; - -failL1: - NCDValue_Free(&R.v); -failL0: - R.have = 0; - parser_out->out_of_memory = 1; -doneL: - free_value(A); -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValue_ListPrepend(&N.v, A.v)) { - goto failM0; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneM; - -failM0: - R.have = 0; - parser_out->out_of_memory = 1; -doneM: - free_value(A); - free_value(N); -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - R.have = 1; - NCDValue_InitList(&R.v); -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValue_InitMap(&R.v); - - if (!NCDValue_MapPrepend(&R.v, A.v, B.v)) { - goto failS1; - } - A.have = 0; - B.have = 0; - - R.have = 1; - goto doneS; - -failS1: - NCDValue_Free(&R.v); -failS0: - R.have = 0; - parser_out->out_of_memory = 1; -doneS: - free_value(A); - free_value(B); -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValue_MapPrepend(&N.v, A.v, B.v)) { - goto failT0; - } - A.have = 0; - B.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneT; - -failT0: - R.have = 0; - parser_out->out_of_memory = 1; -doneT: - free_value(A); - free_value(B); - free_value(N); -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - R.have = 1; - NCDValue_InitMap(&R.v); -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValue_InitStringBin(&R.v, (uint8_t *)A.str, A.len)) { - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; - parser_out->out_of_memory = 1; -doneU: - free_token(A); -} - -value(R) ::= dotted_name(A). { - if (!A) { - goto failV0; - } - - if (!NCDValue_InitVar(&R.v, A)) { - goto failV0; - } - - R.have = 1; - goto doneV; - -failV0: - R.have = 0; - parser_out->out_of_memory = 1; -doneV: - free(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} - -name_maybe(R) ::= . { - R = NULL; -} - -name_maybe(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -process_or_template(R) ::= PROCESS. { - R = 0; -} - -process_or_template(R) ::= TEMPLATE. { - R = 1; -} diff --git a/external/badvpn_dns/generated/NCDValParser_parse.c b/external/badvpn_dns/generated/NCDValParser_parse.c deleted file mode 100644 index f7039cc..0000000 --- a/external/badvpn_dns/generated/NCDValParser_parse.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include <stdio.h> -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 16 -#define YYACTIONTYPE unsigned char -#define ParseTOKENTYPE struct token -typedef union { - int yyinit; - ParseTOKENTYPE yy0; - struct value yy1; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 0 -#endif -#define ParseARG_SDECL struct parser_state *parser_out ; -#define ParseARG_PDECL , struct parser_state *parser_out -#define ParseARG_FETCH struct parser_state *parser_out = yypParser->parser_out -#define ParseARG_STORE yypParser->parser_out = parser_out -#define YYNSTATE 21 -#define YYNRULE 12 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 15, 21, 16, 6, 34, 1, 19, 3, 2, 15, - /* 10 */ 14, 16, 9, 11, 15, 5, 16, 7, 18, 1, - /* 20 */ 35, 20, 2, 17, 14, 15, 10, 16, 8, 12, - /* 30 */ 15, 4, 16, 7, 15, 13, 16, 8, 1, 35, - /* 40 */ 35, 2, 35, 14, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 10, 0, 12, 13, 14, 2, 3, 1, 5, 10, - /* 10 */ 7, 12, 13, 9, 10, 4, 12, 13, 6, 2, - /* 20 */ 15, 3, 5, 6, 7, 10, 11, 12, 13, 9, - /* 30 */ 10, 1, 12, 13, 10, 11, 12, 13, 2, 15, - /* 40 */ 15, 5, 15, 7, -}; -#define YY_SHIFT_USE_DFLT (-1) -#define YY_SHIFT_MAX 11 -static const signed char yy_shift_ofst[] = { - /* 0 */ 36, 3, 17, 36, 36, 36, 1, 6, 11, 30, - /* 10 */ 12, 18, -}; -#define YY_REDUCE_USE_DFLT (-11) -#define YY_REDUCE_MAX 5 -static const signed char yy_reduce_ofst[] = { - /* 0 */ -10, 4, 15, 20, 24, -1, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 33, 33, 33, 33, 33, 33, 33, 22, 33, 26, - /* 10 */ 33, 33, 23, 27, 30, 31, 32, 28, 29, 24, - /* 20 */ 25, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include <stdio.h> -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -** <ul> -** <li> A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -** <li> A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -** </ul> -** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "COMMA", "CURLY_OPEN", "CURLY_CLOSE", - "COLON", "BRACKET_OPEN", "BRACKET_CLOSE", "STRING", - "error", "list_contents", "list", "map_contents", - "map", "value", "input", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "input ::= value", - /* 1 */ "list_contents ::= value", - /* 2 */ "list_contents ::= value COMMA list_contents", - /* 3 */ "list ::= CURLY_OPEN CURLY_CLOSE", - /* 4 */ "list ::= CURLY_OPEN list_contents CURLY_CLOSE", - /* 5 */ "map_contents ::= value COLON value", - /* 6 */ "map_contents ::= value COLON value COMMA map_contents", - /* 7 */ "map ::= BRACKET_OPEN BRACKET_CLOSE", - /* 8 */ "map ::= BRACKET_OPEN map_contents BRACKET_CLOSE", - /* 9 */ "value ::= STRING", - /* 10 */ "value ::= list", - /* 11 */ "value ::= map", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - /* TERMINAL Destructor */ - case 1: /* COMMA */ - case 2: /* CURLY_OPEN */ - case 3: /* CURLY_CLOSE */ - case 4: /* COLON */ - case 5: /* BRACKET_OPEN */ - case 6: /* BRACKET_CLOSE */ - case 7: /* STRING */ -{ -#line 37 "NCDValParser_parse.y" - free_token((yypminor->yy0)); -#line 377 "NCDValParser_parse.c" -} - break; - case 9: /* list_contents */ -{ -#line 47 "NCDValParser_parse.y" - (void)parser_out; -#line 384 "NCDValParser_parse.c" -} - break; - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -** <ul> -** <li> A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -** <li> A pointer to a function used to reclaim memory obtained -** from malloc. -** </ul> -*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) - && (iFallback = yyFallback[iLookAhead])!=0 ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && i<YY_SZ_ACTTAB ); - assert( yy_lookahead[i]==iLookAhead ); -#endif - return yy_action[i]; -} - -/* -** The following routine is called if the stack overflows. -*/ -static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ - ParseARG_FETCH; - yypParser->yyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -#line 58 "NCDValParser_parse.y" - - if (yypMinor) { - free_token(yypMinor->yy0); - } -#line 562 "NCDValParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 14, 1 }, - { 9, 1 }, - { 9, 3 }, - { 10, 2 }, - { 10, 3 }, - { 11, 3 }, - { 11, 5 }, - { 12, 2 }, - { 12, 3 }, - { 13, 1 }, - { 13, 1 }, - { 13, 1 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line <lineno> <grammarfile> - ** { ... } // User supplied code - ** #line <lineno> <thisfile> - ** break; - */ - case 0: /* input ::= value */ -#line 64 "NCDValParser_parse.y" -{ - if (!yymsp[0].minor.yy1.have) { - goto failZ0; - } - - if (!NCDVal_IsInvalid(parser_out->value)) { - // should never happen - parser_out->error_flags |= ERROR_FLAG_SYNTAX; - goto failZ0; - } - - if (!NCDValCons_Complete(&parser_out->cons, yymsp[0].minor.yy1.v, &parser_out->value, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failZ0; - } - -failZ0:; -} -#line 705 "NCDValParser_parse.c" - break; - case 1: /* list_contents ::= value */ -#line 83 "NCDValParser_parse.y" -{ - if (!yymsp[0].minor.yy1.have) { - goto failL0; - } - - NCDValCons_NewList(&parser_out->cons, &yygotominor.yy1.v); - - if (!NCDValCons_ListPrepend(&parser_out->cons, &yygotominor.yy1.v, yymsp[0].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failL0; - } - - yygotominor.yy1.have = 1; - goto doneL; - -failL0: - yygotominor.yy1.have = 0; -doneL:; -} -#line 728 "NCDValParser_parse.c" - break; - case 2: /* list_contents ::= value COMMA list_contents */ -#line 103 "NCDValParser_parse.y" -{ - if (!yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failM0; - } - - if (!NCDValCons_ListPrepend(&parser_out->cons, &yymsp[0].minor.yy1.v, yymsp[-2].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failM0; - } - - yygotominor.yy1.have = 1; - yygotominor.yy1.v = yymsp[0].minor.yy1.v; - goto doneM; - -failM0: - yygotominor.yy1.have = 0; -doneM:; - yy_destructor(yypParser,1,&yymsp[-1].minor); -} -#line 751 "NCDValParser_parse.c" - break; - case 3: /* list ::= CURLY_OPEN CURLY_CLOSE */ -#line 122 "NCDValParser_parse.y" -{ - NCDValCons_NewList(&parser_out->cons, &yygotominor.yy1.v); - yygotominor.yy1.have = 1; - yy_destructor(yypParser,2,&yymsp[-1].minor); - yy_destructor(yypParser,3,&yymsp[0].minor); -} -#line 761 "NCDValParser_parse.c" - break; - case 4: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */ -#line 127 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[-1].minor.yy1; - yy_destructor(yypParser,2,&yymsp[-2].minor); - yy_destructor(yypParser,3,&yymsp[0].minor); -} -#line 770 "NCDValParser_parse.c" - break; - case 5: /* map_contents ::= value COLON value */ -#line 131 "NCDValParser_parse.y" -{ - if (!yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failS0; - } - - NCDValCons_NewMap(&parser_out->cons, &yygotominor.yy1.v); - - if (!NCDValCons_MapInsert(&parser_out->cons, &yygotominor.yy1.v, yymsp[-2].minor.yy1.v, yymsp[0].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failS0; - } - - yygotominor.yy1.have = 1; - goto doneS; - -failS0: - yygotominor.yy1.have = 0; -doneS:; - yy_destructor(yypParser,4,&yymsp[-1].minor); -} -#line 794 "NCDValParser_parse.c" - break; - case 6: /* map_contents ::= value COLON value COMMA map_contents */ -#line 151 "NCDValParser_parse.y" -{ - if (!yymsp[-4].minor.yy1.have || !yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failT0; - } - - if (!NCDValCons_MapInsert(&parser_out->cons, &yymsp[0].minor.yy1.v, yymsp[-4].minor.yy1.v, yymsp[-2].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failT0; - } - - yygotominor.yy1.have = 1; - yygotominor.yy1.v = yymsp[0].minor.yy1.v; - goto doneT; - -failT0: - yygotominor.yy1.have = 0; -doneT:; - yy_destructor(yypParser,4,&yymsp[-3].minor); - yy_destructor(yypParser,1,&yymsp[-1].minor); -} -#line 818 "NCDValParser_parse.c" - break; - case 7: /* map ::= BRACKET_OPEN BRACKET_CLOSE */ -#line 170 "NCDValParser_parse.y" -{ - NCDValCons_NewMap(&parser_out->cons, &yygotominor.yy1.v); - yygotominor.yy1.have = 1; - yy_destructor(yypParser,5,&yymsp[-1].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 828 "NCDValParser_parse.c" - break; - case 8: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */ -#line 175 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[-1].minor.yy1; - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 837 "NCDValParser_parse.c" - break; - case 9: /* value ::= STRING */ -#line 179 "NCDValParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len, &yygotominor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failU0; - } - - yygotominor.yy1.have = 1; - goto doneU; - -failU0: - yygotominor.yy1.have = 0; -doneU:; - free_token(yymsp[0].minor.yy0); -} -#line 857 "NCDValParser_parse.c" - break; - case 10: /* value ::= list */ - case 11: /* value ::= map */ yytestcase(yyruleno==11); -#line 196 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[0].minor.yy1; -} -#line 865 "NCDValParser_parse.c" - break; - default: - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 53 "NCDValParser_parse.y" - - parser_out->error_flags |= ERROR_FLAG_SYNTAX; -#line 930 "NCDValParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -** <ul> -** <li> A pointer to the parser (an opaque structure.) -** <li> The major token number. -** <li> The minor token number. -** <li> An option argument of a grammar-specified type. -** </ul> -** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact<YYNSTATE ){ - assert( !yyendofinput ); /* Impossible to shift the $ token */ - yy_shift(yypParser,yyact,yymajor,&yyminorunion); - yypParser->yyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/external/badvpn_dns/generated/NCDValParser_parse.h b/external/badvpn_dns/generated/NCDValParser_parse.h deleted file mode 100644 index fd19b49..0000000 --- a/external/badvpn_dns/generated/NCDValParser_parse.h +++ /dev/null @@ -1,7 +0,0 @@ -#define COMMA 1 -#define CURLY_OPEN 2 -#define CURLY_CLOSE 3 -#define COLON 4 -#define BRACKET_OPEN 5 -#define BRACKET_CLOSE 6 -#define STRING 7 diff --git a/external/badvpn_dns/generated/NCDValParser_parse.out b/external/badvpn_dns/generated/NCDValParser_parse.out deleted file mode 100644 index 9f42273..0000000 --- a/external/badvpn_dns/generated/NCDValParser_parse.out +++ /dev/null @@ -1,217 +0,0 @@ -State 0: - input ::= * value - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map shift 16 - value shift 6 - input accept - -State 1: - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= CURLY_OPEN * CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - list ::= CURLY_OPEN * list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - CURLY_CLOSE shift 19 - BRACKET_OPEN shift 2 - STRING shift 14 - list_contents shift 11 - list shift 15 - map shift 16 - value shift 7 - -State 2: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= BRACKET_OPEN * BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - map ::= BRACKET_OPEN * map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - BRACKET_CLOSE shift 17 - STRING shift 14 - list shift 15 - map_contents shift 10 - map shift 16 - value shift 8 - -State 3: - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list_contents ::= value COMMA * list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list_contents shift 12 - list shift 15 - map shift 16 - value shift 7 - -State 4: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map_contents ::= value COLON value COMMA * map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map_contents shift 13 - map shift 16 - value shift 8 - -State 5: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= value COLON * value - map_contents ::= value COLON * value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map shift 16 - value shift 9 - -State 6: - (0) input ::= value * - - $ reduce 0 - -State 7: - (1) list_contents ::= value * - list_contents ::= value * COMMA list_contents - - COMMA shift 3 - {default} reduce 1 - -State 8: - map_contents ::= value * COLON value - map_contents ::= value * COLON value COMMA map_contents - - COLON shift 5 - -State 9: - (5) map_contents ::= value COLON value * - map_contents ::= value COLON value * COMMA map_contents - - COMMA shift 4 - {default} reduce 5 - -State 10: - map ::= BRACKET_OPEN map_contents * BRACKET_CLOSE - - BRACKET_CLOSE shift 18 - -State 11: - list ::= CURLY_OPEN list_contents * CURLY_CLOSE - - CURLY_CLOSE shift 20 - -State 12: - (2) list_contents ::= value COMMA list_contents * - - {default} reduce 2 - -State 13: - (6) map_contents ::= value COLON value COMMA map_contents * - - {default} reduce 6 - -State 14: - (9) value ::= STRING * - - {default} reduce 9 - -State 15: - (10) value ::= list * - - {default} reduce 10 - -State 16: - (11) value ::= map * - - {default} reduce 11 - -State 17: - (7) map ::= BRACKET_OPEN BRACKET_CLOSE * - - {default} reduce 7 - -State 18: - (8) map ::= BRACKET_OPEN map_contents BRACKET_CLOSE * - - {default} reduce 8 - -State 19: - (3) list ::= CURLY_OPEN CURLY_CLOSE * - - {default} reduce 3 - -State 20: - (4) list ::= CURLY_OPEN list_contents CURLY_CLOSE * - - {default} reduce 4 - ----------------------------------------------------- -Symbols: - 0: $: - 1: COMMA - 2: CURLY_OPEN - 3: CURLY_CLOSE - 4: COLON - 5: BRACKET_OPEN - 6: BRACKET_CLOSE - 7: STRING - 8: error: - 9: list_contents: CURLY_OPEN BRACKET_OPEN STRING - 10: list: CURLY_OPEN - 11: map_contents: CURLY_OPEN BRACKET_OPEN STRING - 12: map: BRACKET_OPEN - 13: value: CURLY_OPEN BRACKET_OPEN STRING - 14: input: CURLY_OPEN BRACKET_OPEN STRING diff --git a/external/badvpn_dns/generated/NCDValParser_parse.y b/external/badvpn_dns/generated/NCDValParser_parse.y deleted file mode 100644 index ced123d..0000000 --- a/external/badvpn_dns/generated/NCDValParser_parse.y +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file NCDConfigParser_parse.y - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// argument for passing state to parser hooks -%extra_argument { struct parser_state *parser_out } - -// type of structure representing tokens -%token_type { struct token } - -// token destructor frees extra memory allocated for tokens -%token_destructor { free_token($$); } - -// types of nonterminals -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type value { struct value } - -// mention parser_out in some destructor to and avoid unused variable warning -%destructor list_contents { (void)parser_out; } - -// try to dynamically grow the parse stack -%stack_size 0 - -// on syntax error, set the corresponding error flag -%syntax_error { - parser_out->error_flags |= ERROR_FLAG_SYNTAX; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= value(A). { - if (!A.have) { - goto failZ0; - } - - if (!NCDVal_IsInvalid(parser_out->value)) { - // should never happen - parser_out->error_flags |= ERROR_FLAG_SYNTAX; - goto failZ0; - } - - if (!NCDValCons_Complete(&parser_out->cons, A.v, &parser_out->value, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failZ0; - } - -failZ0:; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValCons_NewList(&parser_out->cons, &R.v); - - if (!NCDValCons_ListPrepend(&parser_out->cons, &R.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failL0; - } - - R.have = 1; - goto doneL; - -failL0: - R.have = 0; -doneL:; -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValCons_ListPrepend(&parser_out->cons, &N.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failM0; - } - - R.have = 1; - R.v = N.v; - goto doneM; - -failM0: - R.have = 0; -doneM:; -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - NCDValCons_NewList(&parser_out->cons, &R.v); - R.have = 1; -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValCons_NewMap(&parser_out->cons, &R.v); - - if (!NCDValCons_MapInsert(&parser_out->cons, &R.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failS0; - } - - R.have = 1; - goto doneS; - -failS0: - R.have = 0; -doneS:; -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValCons_MapInsert(&parser_out->cons, &N.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failT0; - } - - R.have = 1; - R.v = N.v; - goto doneT; - -failT0: - R.have = 0; -doneT:; -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - NCDValCons_NewMap(&parser_out->cons, &R.v); - R.have = 1; -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)A.str, A.len, &R.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; -doneU:; - free_token(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} diff --git a/external/badvpn_dns/generated/bison_BPredicate.c b/external/badvpn_dns/generated/bison_BPredicate.c deleted file mode 100644 index 5a0a605..0000000 --- a/external/badvpn_dns/generated/bison_BPredicate.c +++ /dev/null @@ -1,2168 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.7.12-4996" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* Copy the first part of user declarations. */ -/* Line 371 of yacc.c */ -#line 34 "predicate/BPredicate.y" - - -#include <stdlib.h> - -#include <predicate/BPredicate_internal.h> -#include <predicate/BPredicate_parser.h> - -#define YYLEX_PARAM scanner - -static struct predicate_node * make_constant (int val) -{ - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - return NULL; - } - - n->type = NODE_CONSTANT; - n->constant.val = val; - - return n; -} - -static struct predicate_node * make_negation (struct predicate_node *op) -{ - if (!op) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_NEG; - n->neg.op = op; - - return n; - -fail: - if (op) { - free_predicate_node(op); - } - return NULL; -} - -static struct predicate_node * make_conjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_CONJUNCT; - n->conjunct.op1 = op1; - n->conjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_disjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_DISJUNCT; - n->disjunct.op1 = op1; - n->disjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_function (char *name, struct arguments_node *args, int need_args) -{ - if (!name || (!args && need_args)) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_FUNCTION; - n->function.name = name; - n->function.args = args; - - return n; - -fail: - if (name) { - free(name); - } - if (args) { - free_arguments_node(args); - } - return NULL; -} - -static struct arguments_node * make_arguments (struct arguments_arg arg, struct arguments_node *next, int need_next) -{ - if (arg.type == ARGUMENT_INVALID || (!next && need_next)) { - goto fail; - } - - struct arguments_node *n = (struct arguments_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->arg = arg; - n->next = next; - - return n; - -fail: - free_argument(arg); - if (next) { - free_arguments_node(next); - } - return NULL; -} - -static struct arguments_arg make_argument_predicate (struct predicate_node *pr) -{ - struct arguments_arg ret; - - if (!pr) { - goto fail; - } - - ret.type = ARGUMENT_PREDICATE; - ret.predicate = pr; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - -static struct arguments_arg make_argument_string (char *string) -{ - struct arguments_arg ret; - - if (!string) { - goto fail; - } - - ret.type = ARGUMENT_STRING; - ret.string = string; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - - -/* Line 371 of yacc.c */ -#line 256 "generated//bison_BPredicate.c" - -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "bison_BPredicate.h". */ -#ifndef YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -# define YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - STRING = 258, - NAME = 259, - PEER1_NAME = 260, - PEER2_NAME = 261, - AND = 262, - OR = 263, - NOT = 264, - SPAR = 265, - EPAR = 266, - CONSTANT_TRUE = 267, - CONSTANT_FALSE = 268, - COMMA = 269 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 387 of yacc.c */ -#line 227 "predicate/BPredicate.y" - - char *text; - struct predicate_node *node; - struct arguments_node *arg_node; - struct predicate_node nfaw; - struct arguments_arg arg_arg; - - -/* Line 387 of yacc.c */ -#line 322 "generated//bison_BPredicate.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void *scanner, struct predicate_node **result); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -/* Line 390 of yacc.c */ -#line 362 "generated//bison_BPredicate.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 17 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 37 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 15 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 20 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 31 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 269 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 19, 21, 25, 28, 32, 36, 40, 45, 47, 51, - 53 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 16, 0, -1, 17, -1, 18, -1, 19, -1, 20, - -1, 21, -1, 22, -1, 23, -1, 12, -1, 13, - -1, 10, 17, 11, -1, 9, 17, -1, 17, 7, - 17, -1, 17, 8, 17, -1, 4, 10, 11, -1, - 4, 10, 24, 11, -1, 25, -1, 25, 14, 24, - -1, 17, -1, 3, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 276, 276, 281, 281, 281, 281, 281, 281, 284, - 288, 294, 300, 306, 312, 318, 322, 328, 332, 338, - 342 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "STRING", "NAME", "PEER1_NAME", - "PEER2_NAME", "AND", "OR", "NOT", "SPAR", "EPAR", "CONSTANT_TRUE", - "CONSTANT_FALSE", "COMMA", "$accept", "input", "predicate", "constant", - "parentheses", "neg", "conjunct", "disjunct", "function", "arguments", - "argument", YY_NULL -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 15, 16, 17, 17, 17, 17, 17, 17, 18, - 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, - 25 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 2, 3, 3, 3, 4, 1, 3, 1, - 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 0, 9, 10, 0, 2, 3, 4, - 5, 6, 7, 8, 0, 12, 0, 1, 0, 0, - 20, 15, 19, 0, 17, 11, 13, 14, 16, 0, - 18 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 6, 22, 8, 9, 10, 11, 12, 13, 23, - 24 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -10 -static const yytype_int8 yypact[] = -{ - 19, -9, 19, 19, -10, -10, 8, -1, -10, -10, - -10, -10, -10, -10, 1, -10, 26, -10, 19, 19, - -10, -10, -1, -2, 3, -10, -10, 13, -10, 12, - -10 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -10, -10, 0, -10, -10, -10, -10, -10, -10, -3, - -10 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 7, 14, 15, 16, 20, 1, 18, 19, 17, 28, - 2, 3, 21, 4, 5, 20, 1, 29, 26, 27, - 18, 2, 3, 1, 4, 5, 30, 0, 2, 3, - 0, 4, 5, 18, 19, 0, 0, 25 -}; - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-10))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int8 yycheck[] = -{ - 0, 10, 2, 3, 3, 4, 7, 8, 0, 11, - 9, 10, 11, 12, 13, 3, 4, 14, 18, 19, - 7, 9, 10, 4, 12, 13, 29, -1, 9, 10, - -1, 12, 13, 7, 8, -1, -1, 11 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 4, 9, 10, 12, 13, 16, 17, 18, 19, - 20, 21, 22, 23, 10, 17, 17, 0, 7, 8, - 3, 11, 17, 24, 25, 11, 17, 17, 11, 14, - 24 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, scanner, result, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -__attribute__((__unused__)) -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static unsigned -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -#else -static unsigned -yy_location_print_ (yyo, yylocp) - FILE *yyo; - YYLTYPE const * const yylocp; -#endif -{ - unsigned res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += fprintf (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += fprintf (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += fprintf (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += fprintf (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += fprintf (yyo, "-%d", end_col); - } - return res; - } - -# define YY_LOCATION_PRINT(File, Loc) \ - yy_location_print_ (File, &(Loc)) - -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, scanner, result); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (scanner); - YYUSE (result); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, void *scanner, struct predicate_node **result) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, scanner, result) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - void *scanner; - struct predicate_node **result; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , scanner, result); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, scanner, result); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, scanner, result) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (scanner); - YYUSE (result); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 3: /* STRING */ -/* Line 1393 of yacc.c */ -#line 240 "predicate/BPredicate.y" - { - free(((*yyvaluep).text)); -}; -/* Line 1393 of yacc.c */ -#line 1391 "generated//bison_BPredicate.c" - break; - case 4: /* NAME */ -/* Line 1393 of yacc.c */ -#line 240 "predicate/BPredicate.y" - { - free(((*yyvaluep).text)); -}; -/* Line 1393 of yacc.c */ -#line 1400 "generated//bison_BPredicate.c" - break; - case 17: /* predicate */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1411 "generated//bison_BPredicate.c" - break; - case 18: /* constant */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1422 "generated//bison_BPredicate.c" - break; - case 19: /* parentheses */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1433 "generated//bison_BPredicate.c" - break; - case 20: /* neg */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1444 "generated//bison_BPredicate.c" - break; - case 21: /* conjunct */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1455 "generated//bison_BPredicate.c" - break; - case 22: /* disjunct */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1466 "generated//bison_BPredicate.c" - break; - case 23: /* function */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1477 "generated//bison_BPredicate.c" - break; - case 24: /* arguments */ -/* Line 1393 of yacc.c */ -#line 257 "predicate/BPredicate.y" - { - if (((*yyvaluep).arg_node)) { - free_arguments_node(((*yyvaluep).arg_node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1488 "generated//bison_BPredicate.c" - break; - case 25: /* argument */ -/* Line 1393 of yacc.c */ -#line 264 "predicate/BPredicate.y" - { - free_argument(((*yyvaluep).arg_arg)); -}; -/* Line 1393 of yacc.c */ -#line 1497 "generated//bison_BPredicate.c" - break; - - default: - break; - } -} - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *scanner, struct predicate_node **result) -#else -int -yyparse (scanner, result) - void *scanner; - struct predicate_node **result; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -static YYSTYPE yyval_default; -# define YY_INITIAL_VALUE(Value) = Value -#endif -static YYLTYPE yyloc_default -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc = yyloc_default; - - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -/* Line 1787 of yacc.c */ -#line 276 "predicate/BPredicate.y" - { - *result = (yyvsp[(1) - (1)].node); - } - break; - - case 9: -/* Line 1787 of yacc.c */ -#line 284 "predicate/BPredicate.y" - { - (yyval.node) = make_constant(1); - } - break; - - case 10: -/* Line 1787 of yacc.c */ -#line 288 "predicate/BPredicate.y" - { - (yyval.node) = make_constant(0); - } - break; - - case 11: -/* Line 1787 of yacc.c */ -#line 294 "predicate/BPredicate.y" - { - (yyval.node) = (yyvsp[(2) - (3)].node); - } - break; - - case 12: -/* Line 1787 of yacc.c */ -#line 300 "predicate/BPredicate.y" - { - (yyval.node) = make_negation((yyvsp[(2) - (2)].node)); - } - break; - - case 13: -/* Line 1787 of yacc.c */ -#line 306 "predicate/BPredicate.y" - { - (yyval.node) = make_conjunction((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } - break; - - case 14: -/* Line 1787 of yacc.c */ -#line 312 "predicate/BPredicate.y" - { - (yyval.node) = make_disjunction((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } - break; - - case 15: -/* Line 1787 of yacc.c */ -#line 318 "predicate/BPredicate.y" - { - (yyval.node) = make_function((yyvsp[(1) - (3)].text), NULL, 0); - } - break; - - case 16: -/* Line 1787 of yacc.c */ -#line 322 "predicate/BPredicate.y" - { - (yyval.node) = make_function((yyvsp[(1) - (4)].text), (yyvsp[(3) - (4)].arg_node), 1); - } - break; - - case 17: -/* Line 1787 of yacc.c */ -#line 328 "predicate/BPredicate.y" - { - (yyval.arg_node) = make_arguments((yyvsp[(1) - (1)].arg_arg), NULL, 0); - } - break; - - case 18: -/* Line 1787 of yacc.c */ -#line 332 "predicate/BPredicate.y" - { - (yyval.arg_node) = make_arguments((yyvsp[(1) - (3)].arg_arg), (yyvsp[(3) - (3)].arg_node), 1); - } - break; - - case 19: -/* Line 1787 of yacc.c */ -#line 338 "predicate/BPredicate.y" - { - (yyval.arg_arg) = make_argument_predicate((yyvsp[(1) - (1)].node)); - } - break; - - case 20: -/* Line 1787 of yacc.c */ -#line 342 "predicate/BPredicate.y" - { - (yyval.arg_arg) = make_argument_string((yyvsp[(1) - (1)].text)); - } - break; - - -/* Line 1787 of yacc.c */ -#line 1932 "generated//bison_BPredicate.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, scanner, result, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (&yylloc, scanner, result, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, scanner, result); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, scanner, result); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, scanner, result, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, scanner, result); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, scanner, result); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - diff --git a/external/badvpn_dns/generated/bison_BPredicate.h b/external/badvpn_dns/generated/bison_BPredicate.h deleted file mode 100644 index 2bf36ce..0000000 --- a/external/badvpn_dns/generated/bison_BPredicate.h +++ /dev/null @@ -1,114 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -# define YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - STRING = 258, - NAME = 259, - PEER1_NAME = 260, - PEER2_NAME = 261, - AND = 262, - OR = 263, - NOT = 264, - SPAR = 265, - EPAR = 266, - CONSTANT_TRUE = 267, - CONSTANT_FALSE = 268, - COMMA = 269 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 2053 of yacc.c */ -#line 227 "predicate/BPredicate.y" - - char *text; - struct predicate_node *node; - struct arguments_node *arg_node; - struct predicate_node nfaw; - struct arguments_arg arg_arg; - - -/* Line 2053 of yacc.c */ -#line 80 "generated//bison_BPredicate.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void *scanner, struct predicate_node **result); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED */ diff --git a/external/badvpn_dns/generated/blog_channel_BArpProbe.h b/external/badvpn_dns/generated/blog_channel_BArpProbe.h deleted file mode 100644 index f168e63..0000000 --- a/external/badvpn_dns/generated/blog_channel_BArpProbe.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BArpProbe diff --git a/external/badvpn_dns/generated/blog_channel_BConnection.h b/external/badvpn_dns/generated/blog_channel_BConnection.h deleted file mode 100644 index 8447db0..0000000 --- a/external/badvpn_dns/generated/blog_channel_BConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BConnection diff --git a/external/badvpn_dns/generated/blog_channel_BDHCPClient.h b/external/badvpn_dns/generated/blog_channel_BDHCPClient.h deleted file mode 100644 index aacf34d..0000000 --- a/external/badvpn_dns/generated/blog_channel_BDHCPClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClient diff --git a/external/badvpn_dns/generated/blog_channel_BDHCPClientCore.h b/external/badvpn_dns/generated/blog_channel_BDHCPClientCore.h deleted file mode 100644 index 64fc74d..0000000 --- a/external/badvpn_dns/generated/blog_channel_BDHCPClientCore.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClientCore diff --git a/external/badvpn_dns/generated/blog_channel_BDatagram.h b/external/badvpn_dns/generated/blog_channel_BDatagram.h deleted file mode 100644 index d95cf24..0000000 --- a/external/badvpn_dns/generated/blog_channel_BDatagram.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDatagram diff --git a/external/badvpn_dns/generated/blog_channel_BEncryption.h b/external/badvpn_dns/generated/blog_channel_BEncryption.h deleted file mode 100644 index 6991f37..0000000 --- a/external/badvpn_dns/generated/blog_channel_BEncryption.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BEncryption diff --git a/external/badvpn_dns/generated/blog_channel_BInputProcess.h b/external/badvpn_dns/generated/blog_channel_BInputProcess.h deleted file mode 100644 index f65f715..0000000 --- a/external/badvpn_dns/generated/blog_channel_BInputProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BInputProcess diff --git a/external/badvpn_dns/generated/blog_channel_BLockReactor.h b/external/badvpn_dns/generated/blog_channel_BLockReactor.h deleted file mode 100644 index 5aab6d4..0000000 --- a/external/badvpn_dns/generated/blog_channel_BLockReactor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BLockReactor diff --git a/external/badvpn_dns/generated/blog_channel_BNetwork.h b/external/badvpn_dns/generated/blog_channel_BNetwork.h deleted file mode 100644 index c5e3bc1..0000000 --- a/external/badvpn_dns/generated/blog_channel_BNetwork.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BNetwork diff --git a/external/badvpn_dns/generated/blog_channel_BPredicate.h b/external/badvpn_dns/generated/blog_channel_BPredicate.h deleted file mode 100644 index 1a683f1..0000000 --- a/external/badvpn_dns/generated/blog_channel_BPredicate.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BPredicate diff --git a/external/badvpn_dns/generated/blog_channel_BProcess.h b/external/badvpn_dns/generated/blog_channel_BProcess.h deleted file mode 100644 index e11e5a6..0000000 --- a/external/badvpn_dns/generated/blog_channel_BProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BProcess diff --git a/external/badvpn_dns/generated/blog_channel_BReactor.h b/external/badvpn_dns/generated/blog_channel_BReactor.h deleted file mode 100644 index d111dc7..0000000 --- a/external/badvpn_dns/generated/blog_channel_BReactor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BReactor diff --git a/external/badvpn_dns/generated/blog_channel_BSSLConnection.h b/external/badvpn_dns/generated/blog_channel_BSSLConnection.h deleted file mode 100644 index bd55826..0000000 --- a/external/badvpn_dns/generated/blog_channel_BSSLConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSSLConnection diff --git a/external/badvpn_dns/generated/blog_channel_BSignal.h b/external/badvpn_dns/generated/blog_channel_BSignal.h deleted file mode 100644 index 2820ebc..0000000 --- a/external/badvpn_dns/generated/blog_channel_BSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSignal diff --git a/external/badvpn_dns/generated/blog_channel_BSocksClient.h b/external/badvpn_dns/generated/blog_channel_BSocksClient.h deleted file mode 100644 index 72086fa..0000000 --- a/external/badvpn_dns/generated/blog_channel_BSocksClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSocksClient diff --git a/external/badvpn_dns/generated/blog_channel_BTap.h b/external/badvpn_dns/generated/blog_channel_BTap.h deleted file mode 100644 index ab3e951..0000000 --- a/external/badvpn_dns/generated/blog_channel_BTap.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTap diff --git a/external/badvpn_dns/generated/blog_channel_BThreadSignal.h b/external/badvpn_dns/generated/blog_channel_BThreadSignal.h deleted file mode 100644 index f39fc36..0000000 --- a/external/badvpn_dns/generated/blog_channel_BThreadSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadSignal diff --git a/external/badvpn_dns/generated/blog_channel_BThreadWork.h b/external/badvpn_dns/generated/blog_channel_BThreadWork.h deleted file mode 100644 index f68383c..0000000 --- a/external/badvpn_dns/generated/blog_channel_BThreadWork.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadWork diff --git a/external/badvpn_dns/generated/blog_channel_BTime.h b/external/badvpn_dns/generated/blog_channel_BTime.h deleted file mode 100644 index b323ee7..0000000 --- a/external/badvpn_dns/generated/blog_channel_BTime.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTime diff --git a/external/badvpn_dns/generated/blog_channel_BUnixSignal.h b/external/badvpn_dns/generated/blog_channel_BUnixSignal.h deleted file mode 100644 index 914b21b..0000000 --- a/external/badvpn_dns/generated/blog_channel_BUnixSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BUnixSignal diff --git a/external/badvpn_dns/generated/blog_channel_DPReceive.h b/external/badvpn_dns/generated/blog_channel_DPReceive.h deleted file mode 100644 index 99889b5..0000000 --- a/external/badvpn_dns/generated/blog_channel_DPReceive.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPReceive diff --git a/external/badvpn_dns/generated/blog_channel_DPRelay.h b/external/badvpn_dns/generated/blog_channel_DPRelay.h deleted file mode 100644 index bc0153b..0000000 --- a/external/badvpn_dns/generated/blog_channel_DPRelay.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPRelay diff --git a/external/badvpn_dns/generated/blog_channel_DataProto.h b/external/badvpn_dns/generated/blog_channel_DataProto.h deleted file mode 100644 index a6f900a..0000000 --- a/external/badvpn_dns/generated/blog_channel_DataProto.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DataProto diff --git a/external/badvpn_dns/generated/blog_channel_DatagramPeerIO.h b/external/badvpn_dns/generated/blog_channel_DatagramPeerIO.h deleted file mode 100644 index 16e37b5..0000000 --- a/external/badvpn_dns/generated/blog_channel_DatagramPeerIO.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DatagramPeerIO diff --git a/external/badvpn_dns/generated/blog_channel_FragmentProtoAssembler.h b/external/badvpn_dns/generated/blog_channel_FragmentProtoAssembler.h deleted file mode 100644 index 25289ef..0000000 --- a/external/badvpn_dns/generated/blog_channel_FragmentProtoAssembler.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FragmentProtoAssembler diff --git a/external/badvpn_dns/generated/blog_channel_FrameDecider.h b/external/badvpn_dns/generated/blog_channel_FrameDecider.h deleted file mode 100644 index 5dbf3c4..0000000 --- a/external/badvpn_dns/generated/blog_channel_FrameDecider.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FrameDecider diff --git a/external/badvpn_dns/generated/blog_channel_LineBuffer.h b/external/badvpn_dns/generated/blog_channel_LineBuffer.h deleted file mode 100644 index 4286a74..0000000 --- a/external/badvpn_dns/generated/blog_channel_LineBuffer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_LineBuffer diff --git a/external/badvpn_dns/generated/blog_channel_Listener.h b/external/badvpn_dns/generated/blog_channel_Listener.h deleted file mode 100644 index f61bfb3..0000000 --- a/external/badvpn_dns/generated/blog_channel_Listener.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_Listener diff --git a/external/badvpn_dns/generated/blog_channel_NCDBuildProgram.h b/external/badvpn_dns/generated/blog_channel_NCDBuildProgram.h deleted file mode 100644 index 1a6cdf9..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDBuildProgram.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDBuildProgram diff --git a/external/badvpn_dns/generated/blog_channel_NCDConfigParser.h b/external/badvpn_dns/generated/blog_channel_NCDConfigParser.h deleted file mode 100644 index 92d98d0..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDConfigParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigParser diff --git a/external/badvpn_dns/generated/blog_channel_NCDConfigTokenizer.h b/external/badvpn_dns/generated/blog_channel_NCDConfigTokenizer.h deleted file mode 100644 index 0b3b689..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDConfigTokenizer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigTokenizer diff --git a/external/badvpn_dns/generated/blog_channel_NCDIfConfig.h b/external/badvpn_dns/generated/blog_channel_NCDIfConfig.h deleted file mode 100644 index 91bdbda..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDIfConfig.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDIfConfig diff --git a/external/badvpn_dns/generated/blog_channel_NCDInterfaceMonitor.h b/external/badvpn_dns/generated/blog_channel_NCDInterfaceMonitor.h deleted file mode 100644 index 22c0f8d..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDInterfaceMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDInterfaceMonitor diff --git a/external/badvpn_dns/generated/blog_channel_NCDModuleIndex.h b/external/badvpn_dns/generated/blog_channel_NCDModuleIndex.h deleted file mode 100644 index 3487664..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDModuleIndex.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDModuleIndex diff --git a/external/badvpn_dns/generated/blog_channel_NCDModuleProcess.h b/external/badvpn_dns/generated/blog_channel_NCDModuleProcess.h deleted file mode 100644 index db34dcc..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDModuleProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDModuleProcess diff --git a/external/badvpn_dns/generated/blog_channel_NCDPlaceholderDb.h b/external/badvpn_dns/generated/blog_channel_NCDPlaceholderDb.h deleted file mode 100644 index f1f1db2..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDPlaceholderDb.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDPlaceholderDb diff --git a/external/badvpn_dns/generated/blog_channel_NCDRequest.h b/external/badvpn_dns/generated/blog_channel_NCDRequest.h deleted file mode 100644 index 5edc18a..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDRequest.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRequest diff --git a/external/badvpn_dns/generated/blog_channel_NCDRequestClient.h b/external/badvpn_dns/generated/blog_channel_NCDRequestClient.h deleted file mode 100644 index 1e696d8..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDRequestClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRequestClient diff --git a/external/badvpn_dns/generated/blog_channel_NCDRfkillMonitor.h b/external/badvpn_dns/generated/blog_channel_NCDRfkillMonitor.h deleted file mode 100644 index 56eba88..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDRfkillMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRfkillMonitor diff --git a/external/badvpn_dns/generated/blog_channel_NCDUdevCache.h b/external/badvpn_dns/generated/blog_channel_NCDUdevCache.h deleted file mode 100644 index 088fc9b..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDUdevCache.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevCache diff --git a/external/badvpn_dns/generated/blog_channel_NCDUdevManager.h b/external/badvpn_dns/generated/blog_channel_NCDUdevManager.h deleted file mode 100644 index e9d6375..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDUdevManager.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevManager diff --git a/external/badvpn_dns/generated/blog_channel_NCDUdevMonitor.h b/external/badvpn_dns/generated/blog_channel_NCDUdevMonitor.h deleted file mode 100644 index bd93249..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDUdevMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevMonitor diff --git a/external/badvpn_dns/generated/blog_channel_NCDUdevMonitorParser.h b/external/badvpn_dns/generated/blog_channel_NCDUdevMonitorParser.h deleted file mode 100644 index a7d560f..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDUdevMonitorParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevMonitorParser diff --git a/external/badvpn_dns/generated/blog_channel_NCDVal.h b/external/badvpn_dns/generated/blog_channel_NCDVal.h deleted file mode 100644 index f2b67c2..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDVal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDVal diff --git a/external/badvpn_dns/generated/blog_channel_NCDValGenerator.h b/external/badvpn_dns/generated/blog_channel_NCDValGenerator.h deleted file mode 100644 index 193826b..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDValGenerator.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDValGenerator diff --git a/external/badvpn_dns/generated/blog_channel_NCDValParser.h b/external/badvpn_dns/generated/blog_channel_NCDValParser.h deleted file mode 100644 index 1d44acb..0000000 --- a/external/badvpn_dns/generated/blog_channel_NCDValParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDValParser diff --git a/external/badvpn_dns/generated/blog_channel_PRStreamSink.h b/external/badvpn_dns/generated/blog_channel_PRStreamSink.h deleted file mode 100644 index b70b61c..0000000 --- a/external/badvpn_dns/generated/blog_channel_PRStreamSink.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PRStreamSink diff --git a/external/badvpn_dns/generated/blog_channel_PRStreamSource.h b/external/badvpn_dns/generated/blog_channel_PRStreamSource.h deleted file mode 100644 index e16d93d..0000000 --- a/external/badvpn_dns/generated/blog_channel_PRStreamSource.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PRStreamSource diff --git a/external/badvpn_dns/generated/blog_channel_PacketProtoDecoder.h b/external/badvpn_dns/generated/blog_channel_PacketProtoDecoder.h deleted file mode 100644 index fbfa5d8..0000000 --- a/external/badvpn_dns/generated/blog_channel_PacketProtoDecoder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PacketProtoDecoder diff --git a/external/badvpn_dns/generated/blog_channel_PasswordListener.h b/external/badvpn_dns/generated/blog_channel_PasswordListener.h deleted file mode 100644 index 6ff0bb5..0000000 --- a/external/badvpn_dns/generated/blog_channel_PasswordListener.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PasswordListener diff --git a/external/badvpn_dns/generated/blog_channel_PeerChat.h b/external/badvpn_dns/generated/blog_channel_PeerChat.h deleted file mode 100644 index cadf230..0000000 --- a/external/badvpn_dns/generated/blog_channel_PeerChat.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PeerChat diff --git a/external/badvpn_dns/generated/blog_channel_SPProtoDecoder.h b/external/badvpn_dns/generated/blog_channel_SPProtoDecoder.h deleted file mode 100644 index 09bf259..0000000 --- a/external/badvpn_dns/generated/blog_channel_SPProtoDecoder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_SPProtoDecoder diff --git a/external/badvpn_dns/generated/blog_channel_ServerConnection.h b/external/badvpn_dns/generated/blog_channel_ServerConnection.h deleted file mode 100644 index faea1dd..0000000 --- a/external/badvpn_dns/generated/blog_channel_ServerConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ServerConnection diff --git a/external/badvpn_dns/generated/blog_channel_SocksUdpGwClient.h b/external/badvpn_dns/generated/blog_channel_SocksUdpGwClient.h deleted file mode 100644 index 6ba39ae..0000000 --- a/external/badvpn_dns/generated/blog_channel_SocksUdpGwClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_SocksUdpGwClient diff --git a/external/badvpn_dns/generated/blog_channel_StreamPeerIO.h b/external/badvpn_dns/generated/blog_channel_StreamPeerIO.h deleted file mode 100644 index 0359736..0000000 --- a/external/badvpn_dns/generated/blog_channel_StreamPeerIO.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_StreamPeerIO diff --git a/external/badvpn_dns/generated/blog_channel_UdpGwClient.h b/external/badvpn_dns/generated/blog_channel_UdpGwClient.h deleted file mode 100644 index 8530376..0000000 --- a/external/badvpn_dns/generated/blog_channel_UdpGwClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_UdpGwClient diff --git a/external/badvpn_dns/generated/blog_channel_addr.h b/external/badvpn_dns/generated/blog_channel_addr.h deleted file mode 100644 index 512db28..0000000 --- a/external/badvpn_dns/generated/blog_channel_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_addr diff --git a/external/badvpn_dns/generated/blog_channel_client.h b/external/badvpn_dns/generated/blog_channel_client.h deleted file mode 100644 index c851b77..0000000 --- a/external/badvpn_dns/generated/blog_channel_client.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_client diff --git a/external/badvpn_dns/generated/blog_channel_dostest_attacker.h b/external/badvpn_dns/generated/blog_channel_dostest_attacker.h deleted file mode 100644 index b267c8f..0000000 --- a/external/badvpn_dns/generated/blog_channel_dostest_attacker.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_dostest_attacker diff --git a/external/badvpn_dns/generated/blog_channel_dostest_server.h b/external/badvpn_dns/generated/blog_channel_dostest_server.h deleted file mode 100644 index 8d3988e..0000000 --- a/external/badvpn_dns/generated/blog_channel_dostest_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_dostest_server diff --git a/external/badvpn_dns/generated/blog_channel_flooder.h b/external/badvpn_dns/generated/blog_channel_flooder.h deleted file mode 100644 index 94f595e..0000000 --- a/external/badvpn_dns/generated/blog_channel_flooder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_flooder diff --git a/external/badvpn_dns/generated/blog_channel_lwip.h b/external/badvpn_dns/generated/blog_channel_lwip.h deleted file mode 100644 index fb5687d..0000000 --- a/external/badvpn_dns/generated/blog_channel_lwip.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_lwip diff --git a/external/badvpn_dns/generated/blog_channel_ncd.h b/external/badvpn_dns/generated/blog_channel_ncd.h deleted file mode 100644 index 9bf2956..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd diff --git a/external/badvpn_dns/generated/blog_channel_ncd_alias.h b/external/badvpn_dns/generated/blog_channel_ncd_alias.h deleted file mode 100644 index 5b52bf2..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_alias.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_alias diff --git a/external/badvpn_dns/generated/blog_channel_ncd_arithmetic.h b/external/badvpn_dns/generated/blog_channel_ncd_arithmetic.h deleted file mode 100644 index 66c08a8..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_arithmetic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_arithmetic diff --git a/external/badvpn_dns/generated/blog_channel_ncd_assert.h b/external/badvpn_dns/generated/blog_channel_ncd_assert.h deleted file mode 100644 index 21e4d41..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_assert.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_assert diff --git a/external/badvpn_dns/generated/blog_channel_ncd_backtrack.h b/external/badvpn_dns/generated/blog_channel_ncd_backtrack.h deleted file mode 100644 index ea669f7..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_backtrack.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_backtrack diff --git a/external/badvpn_dns/generated/blog_channel_ncd_blocker.h b/external/badvpn_dns/generated/blog_channel_ncd_blocker.h deleted file mode 100644 index a897b9f..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_blocker.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_blocker diff --git a/external/badvpn_dns/generated/blog_channel_ncd_buffer.h b/external/badvpn_dns/generated/blog_channel_ncd_buffer.h deleted file mode 100644 index 64e4433..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_buffer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_buffer diff --git a/external/badvpn_dns/generated/blog_channel_ncd_call2.h b/external/badvpn_dns/generated/blog_channel_ncd_call2.h deleted file mode 100644 index 4b64608..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_call2.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_call2 diff --git a/external/badvpn_dns/generated/blog_channel_ncd_choose.h b/external/badvpn_dns/generated/blog_channel_ncd_choose.h deleted file mode 100644 index a915036..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_choose.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_choose diff --git a/external/badvpn_dns/generated/blog_channel_ncd_concat.h b/external/badvpn_dns/generated/blog_channel_ncd_concat.h deleted file mode 100644 index 8c54ccb..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_concat.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_concat diff --git a/external/badvpn_dns/generated/blog_channel_ncd_daemon.h b/external/badvpn_dns/generated/blog_channel_ncd_daemon.h deleted file mode 100644 index 0a3ae3f..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_daemon.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_daemon diff --git a/external/badvpn_dns/generated/blog_channel_ncd_depend.h b/external/badvpn_dns/generated/blog_channel_ncd_depend.h deleted file mode 100644 index ae1ff8e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_depend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_depend diff --git a/external/badvpn_dns/generated/blog_channel_ncd_depend_scope.h b/external/badvpn_dns/generated/blog_channel_ncd_depend_scope.h deleted file mode 100644 index 1168714..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_depend_scope.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_depend_scope diff --git a/external/badvpn_dns/generated/blog_channel_ncd_dynamic_depend.h b/external/badvpn_dns/generated/blog_channel_ncd_dynamic_depend.h deleted file mode 100644 index 7ff305e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_dynamic_depend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_dynamic_depend diff --git a/external/badvpn_dns/generated/blog_channel_ncd_exit.h b/external/badvpn_dns/generated/blog_channel_ncd_exit.h deleted file mode 100644 index 2d2e3af..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_exit.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_exit diff --git a/external/badvpn_dns/generated/blog_channel_ncd_explode.h b/external/badvpn_dns/generated/blog_channel_ncd_explode.h deleted file mode 100644 index b7dc820..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_explode.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_explode diff --git a/external/badvpn_dns/generated/blog_channel_ncd_file.h b/external/badvpn_dns/generated/blog_channel_ncd_file.h deleted file mode 100644 index 6cfa5a5..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_file.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_file diff --git a/external/badvpn_dns/generated/blog_channel_ncd_file_open.h b/external/badvpn_dns/generated/blog_channel_ncd_file_open.h deleted file mode 100644 index dd4ecb5..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_file_open.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_file_open diff --git a/external/badvpn_dns/generated/blog_channel_ncd_foreach.h b/external/badvpn_dns/generated/blog_channel_ncd_foreach.h deleted file mode 100644 index 430b229..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_foreach.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_foreach diff --git a/external/badvpn_dns/generated/blog_channel_ncd_from_string.h b/external/badvpn_dns/generated/blog_channel_ncd_from_string.h deleted file mode 100644 index e409fff..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_from_string.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_from_string diff --git a/external/badvpn_dns/generated/blog_channel_ncd_getargs.h b/external/badvpn_dns/generated/blog_channel_ncd_getargs.h deleted file mode 100644 index da7631d..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_getargs.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_getargs diff --git a/external/badvpn_dns/generated/blog_channel_ncd_getenv.h b/external/badvpn_dns/generated/blog_channel_ncd_getenv.h deleted file mode 100644 index 4f29021..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_getenv.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_getenv diff --git a/external/badvpn_dns/generated/blog_channel_ncd_if.h b/external/badvpn_dns/generated/blog_channel_ncd_if.h deleted file mode 100644 index 11a09a2..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_if.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_if diff --git a/external/badvpn_dns/generated/blog_channel_ncd_imperative.h b/external/badvpn_dns/generated/blog_channel_ncd_imperative.h deleted file mode 100644 index 362df87..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_imperative.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_imperative diff --git a/external/badvpn_dns/generated/blog_channel_ncd_implode.h b/external/badvpn_dns/generated/blog_channel_ncd_implode.h deleted file mode 100644 index 5bb66d5..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_implode.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_implode diff --git a/external/badvpn_dns/generated/blog_channel_ncd_index.h b/external/badvpn_dns/generated/blog_channel_ncd_index.h deleted file mode 100644 index 666bbe9..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_index.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_index diff --git a/external/badvpn_dns/generated/blog_channel_ncd_list.h b/external/badvpn_dns/generated/blog_channel_ncd_list.h deleted file mode 100644 index f153be7..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_list.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_list diff --git a/external/badvpn_dns/generated/blog_channel_ncd_load_module.h b/external/badvpn_dns/generated/blog_channel_ncd_load_module.h deleted file mode 100644 index c27dddb..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_load_module.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_load_module diff --git a/external/badvpn_dns/generated/blog_channel_ncd_log.h b/external/badvpn_dns/generated/blog_channel_ncd_log.h deleted file mode 100644 index 9ae2dc9..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_log.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_log diff --git a/external/badvpn_dns/generated/blog_channel_ncd_log_msg.h b/external/badvpn_dns/generated/blog_channel_ncd_log_msg.h deleted file mode 100644 index 9e51b7e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_log_msg.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_log_msg diff --git a/external/badvpn_dns/generated/blog_channel_ncd_logical.h b/external/badvpn_dns/generated/blog_channel_ncd_logical.h deleted file mode 100644 index 688453d..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_logical.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_logical diff --git a/external/badvpn_dns/generated/blog_channel_ncd_multidepend.h b/external/badvpn_dns/generated/blog_channel_ncd_multidepend.h deleted file mode 100644 index a82953d..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_multidepend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_multidepend diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_badvpn.h b/external/badvpn_dns/generated/blog_channel_ncd_net_backend_badvpn.h deleted file mode 100644 index c9964c1..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_badvpn.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_badvpn diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_rfkill.h b/external/badvpn_dns/generated/blog_channel_ncd_net_backend_rfkill.h deleted file mode 100644 index e69896f..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_rfkill.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_rfkill diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitdevice.h b/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitdevice.h deleted file mode 100644 index 63c4f24..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitdevice.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_waitdevice diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitlink.h b/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitlink.h deleted file mode 100644 index 96244c0..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_waitlink.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_waitlink diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_wpa_supplicant.h b/external/badvpn_dns/generated/blog_channel_ncd_net_backend_wpa_supplicant.h deleted file mode 100644 index 22572d3..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_backend_wpa_supplicant.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_wpa_supplicant diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_dns.h b/external/badvpn_dns/generated/blog_channel_ncd_net_dns.h deleted file mode 100644 index 01c3744..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_dns.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_dns diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_iptables.h b/external/badvpn_dns/generated/blog_channel_ncd_net_iptables.h deleted file mode 100644 index 42e2382..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_iptables.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_iptables diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr.h deleted file mode 100644 index 75bcb24..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_addr diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr_in_network.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr_in_network.h deleted file mode 100644 index 41f2df2..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_addr_in_network.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_addr_in_network diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_arp_probe.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_arp_probe.h deleted file mode 100644 index 18f7c78..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_arp_probe.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_arp_probe diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_dhcp.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_dhcp.h deleted file mode 100644 index 51fa61f..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_dhcp.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_dhcp diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_route.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_route.h deleted file mode 100644 index e181a90..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv4_route.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_route diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr.h deleted file mode 100644 index bd6bd10..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_addr diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr_in_network.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr_in_network.h deleted file mode 100644 index ba33921..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_addr_in_network.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_addr_in_network diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_route.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_route.h deleted file mode 100644 index b72e4d3..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_route.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_route diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h b/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h deleted file mode 100644 index ff7d6e1..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_wait_dynamic_addr diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_up.h b/external/badvpn_dns/generated/blog_channel_ncd_net_up.h deleted file mode 100644 index 7acdede..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_up.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_up diff --git a/external/badvpn_dns/generated/blog_channel_ncd_net_watch_interfaces.h b/external/badvpn_dns/generated/blog_channel_ncd_net_watch_interfaces.h deleted file mode 100644 index 7fc078f..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_net_watch_interfaces.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_watch_interfaces diff --git a/external/badvpn_dns/generated/blog_channel_ncd_netmask.h b/external/badvpn_dns/generated/blog_channel_ncd_netmask.h deleted file mode 100644 index 10993f0..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_netmask.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_netmask diff --git a/external/badvpn_dns/generated/blog_channel_ncd_ondemand.h b/external/badvpn_dns/generated/blog_channel_ncd_ondemand.h deleted file mode 100644 index c7a0578..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_ondemand.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_ondemand diff --git a/external/badvpn_dns/generated/blog_channel_ncd_parse.h b/external/badvpn_dns/generated/blog_channel_ncd_parse.h deleted file mode 100644 index 672155b..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_parse.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_parse diff --git a/external/badvpn_dns/generated/blog_channel_ncd_print.h b/external/badvpn_dns/generated/blog_channel_ncd_print.h deleted file mode 100644 index 22638f3..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_print.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_print diff --git a/external/badvpn_dns/generated/blog_channel_ncd_process_manager.h b/external/badvpn_dns/generated/blog_channel_ncd_process_manager.h deleted file mode 100644 index 627ba0e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_process_manager.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_process_manager diff --git a/external/badvpn_dns/generated/blog_channel_ncd_reboot.h b/external/badvpn_dns/generated/blog_channel_ncd_reboot.h deleted file mode 100644 index 0e31d55..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_reboot.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_reboot diff --git a/external/badvpn_dns/generated/blog_channel_ncd_ref.h b/external/badvpn_dns/generated/blog_channel_ncd_ref.h deleted file mode 100644 index 4f9f24a..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_ref.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_ref diff --git a/external/badvpn_dns/generated/blog_channel_ncd_regex_match.h b/external/badvpn_dns/generated/blog_channel_ncd_regex_match.h deleted file mode 100644 index 3081347..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_regex_match.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_regex_match diff --git a/external/badvpn_dns/generated/blog_channel_ncd_request.h b/external/badvpn_dns/generated/blog_channel_ncd_request.h deleted file mode 100644 index 00103ea..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_request.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_request diff --git a/external/badvpn_dns/generated/blog_channel_ncd_run.h b/external/badvpn_dns/generated/blog_channel_ncd_run.h deleted file mode 100644 index 036a93e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_run.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_run diff --git a/external/badvpn_dns/generated/blog_channel_ncd_runonce.h b/external/badvpn_dns/generated/blog_channel_ncd_runonce.h deleted file mode 100644 index 2e54452..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_runonce.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_runonce diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sleep.h b/external/badvpn_dns/generated/blog_channel_ncd_sleep.h deleted file mode 100644 index fb6c7fe..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sleep.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sleep diff --git a/external/badvpn_dns/generated/blog_channel_ncd_socket.h b/external/badvpn_dns/generated/blog_channel_ncd_socket.h deleted file mode 100644 index 3c1f0c4..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_socket.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_socket diff --git a/external/badvpn_dns/generated/blog_channel_ncd_spawn.h b/external/badvpn_dns/generated/blog_channel_ncd_spawn.h deleted file mode 100644 index b9b3b24..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_spawn.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_spawn diff --git a/external/badvpn_dns/generated/blog_channel_ncd_strcmp.h b/external/badvpn_dns/generated/blog_channel_ncd_strcmp.h deleted file mode 100644 index 6ef09ad..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_strcmp.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_strcmp diff --git a/external/badvpn_dns/generated/blog_channel_ncd_substr.h b/external/badvpn_dns/generated/blog_channel_ncd_substr.h deleted file mode 100644 index 691ad0e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_substr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_substr diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_evdev.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_evdev.h deleted file mode 100644 index 4a7244e..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_evdev.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_evdev diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_request_client.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_request_client.h deleted file mode 100644 index ce0f9e4..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_request_client.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_request_client diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_request_server.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_request_server.h deleted file mode 100644 index 1197958..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_request_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_request_server diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_start_process.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_start_process.h deleted file mode 100644 index 45c2edc..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_start_process.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_start_process diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_directory.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_directory.h deleted file mode 100644 index e190da5..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_directory.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_directory diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_input.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_input.h deleted file mode 100644 index b899555..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_input.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_input diff --git a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_usb.h b/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_usb.h deleted file mode 100644 index bc5102a..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_sys_watch_usb.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_usb diff --git a/external/badvpn_dns/generated/blog_channel_ncd_timer.h b/external/badvpn_dns/generated/blog_channel_ncd_timer.h deleted file mode 100644 index beaa73d..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_timer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_timer diff --git a/external/badvpn_dns/generated/blog_channel_ncd_to_string.h b/external/badvpn_dns/generated/blog_channel_ncd_to_string.h deleted file mode 100644 index 41cd8b9..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_to_string.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_to_string diff --git a/external/badvpn_dns/generated/blog_channel_ncd_try.h b/external/badvpn_dns/generated/blog_channel_ncd_try.h deleted file mode 100644 index bb76c68..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_try.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_try diff --git a/external/badvpn_dns/generated/blog_channel_ncd_value.h b/external/badvpn_dns/generated/blog_channel_ncd_value.h deleted file mode 100644 index fa624e8..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_value.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_value diff --git a/external/badvpn_dns/generated/blog_channel_ncd_valuemetic.h b/external/badvpn_dns/generated/blog_channel_ncd_valuemetic.h deleted file mode 100644 index 385d2bb..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_valuemetic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_valuemetic diff --git a/external/badvpn_dns/generated/blog_channel_ncd_var.h b/external/badvpn_dns/generated/blog_channel_ncd_var.h deleted file mode 100644 index fa5c0c4..0000000 --- a/external/badvpn_dns/generated/blog_channel_ncd_var.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_var diff --git a/external/badvpn_dns/generated/blog_channel_nsskey.h b/external/badvpn_dns/generated/blog_channel_nsskey.h deleted file mode 100644 index 66e6a72..0000000 --- a/external/badvpn_dns/generated/blog_channel_nsskey.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_nsskey diff --git a/external/badvpn_dns/generated/blog_channel_server.h b/external/badvpn_dns/generated/blog_channel_server.h deleted file mode 100644 index acb3ed0..0000000 --- a/external/badvpn_dns/generated/blog_channel_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_server diff --git a/external/badvpn_dns/generated/blog_channel_tun2socks.h b/external/badvpn_dns/generated/blog_channel_tun2socks.h deleted file mode 100644 index 21c1ce2..0000000 --- a/external/badvpn_dns/generated/blog_channel_tun2socks.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_tun2socks diff --git a/external/badvpn_dns/generated/blog_channel_udpgw.h b/external/badvpn_dns/generated/blog_channel_udpgw.h deleted file mode 100644 index 504a352..0000000 --- a/external/badvpn_dns/generated/blog_channel_udpgw.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_udpgw diff --git a/external/badvpn_dns/generated/blog_channels_defines.h b/external/badvpn_dns/generated/blog_channels_defines.h deleted file mode 100644 index d89dc86..0000000 --- a/external/badvpn_dns/generated/blog_channels_defines.h +++ /dev/null @@ -1,146 +0,0 @@ -#define BLOG_CHANNEL_server 0 -#define BLOG_CHANNEL_client 1 -#define BLOG_CHANNEL_flooder 2 -#define BLOG_CHANNEL_tun2socks 3 -#define BLOG_CHANNEL_ncd 4 -#define BLOG_CHANNEL_ncd_var 5 -#define BLOG_CHANNEL_ncd_list 6 -#define BLOG_CHANNEL_ncd_depend 7 -#define BLOG_CHANNEL_ncd_multidepend 8 -#define BLOG_CHANNEL_ncd_dynamic_depend 9 -#define BLOG_CHANNEL_ncd_concat 10 -#define BLOG_CHANNEL_ncd_if 11 -#define BLOG_CHANNEL_ncd_strcmp 12 -#define BLOG_CHANNEL_ncd_regex_match 13 -#define BLOG_CHANNEL_ncd_logical 14 -#define BLOG_CHANNEL_ncd_sleep 15 -#define BLOG_CHANNEL_ncd_print 16 -#define BLOG_CHANNEL_ncd_blocker 17 -#define BLOG_CHANNEL_ncd_run 18 -#define BLOG_CHANNEL_ncd_runonce 19 -#define BLOG_CHANNEL_ncd_daemon 20 -#define BLOG_CHANNEL_ncd_spawn 21 -#define BLOG_CHANNEL_ncd_imperative 22 -#define BLOG_CHANNEL_ncd_ref 23 -#define BLOG_CHANNEL_ncd_index 24 -#define BLOG_CHANNEL_ncd_alias 25 -#define BLOG_CHANNEL_ncd_process_manager 26 -#define BLOG_CHANNEL_ncd_ondemand 27 -#define BLOG_CHANNEL_ncd_foreach 28 -#define BLOG_CHANNEL_ncd_choose 29 -#define BLOG_CHANNEL_ncd_net_backend_waitdevice 30 -#define BLOG_CHANNEL_ncd_net_backend_waitlink 31 -#define BLOG_CHANNEL_ncd_net_backend_badvpn 32 -#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 33 -#define BLOG_CHANNEL_ncd_net_backend_rfkill 34 -#define BLOG_CHANNEL_ncd_net_up 35 -#define BLOG_CHANNEL_ncd_net_dns 36 -#define BLOG_CHANNEL_ncd_net_iptables 37 -#define BLOG_CHANNEL_ncd_net_ipv4_addr 38 -#define BLOG_CHANNEL_ncd_net_ipv4_route 39 -#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 40 -#define BLOG_CHANNEL_ncd_net_ipv4_arp_probe 41 -#define BLOG_CHANNEL_ncd_net_watch_interfaces 42 -#define BLOG_CHANNEL_ncd_sys_watch_input 43 -#define BLOG_CHANNEL_ncd_sys_watch_usb 44 -#define BLOG_CHANNEL_ncd_sys_evdev 45 -#define BLOG_CHANNEL_ncd_sys_watch_directory 46 -#define BLOG_CHANNEL_StreamPeerIO 47 -#define BLOG_CHANNEL_DatagramPeerIO 48 -#define BLOG_CHANNEL_BReactor 49 -#define BLOG_CHANNEL_BSignal 50 -#define BLOG_CHANNEL_FragmentProtoAssembler 51 -#define BLOG_CHANNEL_BPredicate 52 -#define BLOG_CHANNEL_ServerConnection 53 -#define BLOG_CHANNEL_Listener 54 -#define BLOG_CHANNEL_DataProto 55 -#define BLOG_CHANNEL_FrameDecider 56 -#define BLOG_CHANNEL_BSocksClient 57 -#define BLOG_CHANNEL_BDHCPClientCore 58 -#define BLOG_CHANNEL_BDHCPClient 59 -#define BLOG_CHANNEL_NCDIfConfig 60 -#define BLOG_CHANNEL_BUnixSignal 61 -#define BLOG_CHANNEL_BProcess 62 -#define BLOG_CHANNEL_PRStreamSink 63 -#define BLOG_CHANNEL_PRStreamSource 64 -#define BLOG_CHANNEL_PacketProtoDecoder 65 -#define BLOG_CHANNEL_DPRelay 66 -#define BLOG_CHANNEL_BThreadWork 67 -#define BLOG_CHANNEL_DPReceive 68 -#define BLOG_CHANNEL_BInputProcess 69 -#define BLOG_CHANNEL_NCDUdevMonitorParser 70 -#define BLOG_CHANNEL_NCDUdevMonitor 71 -#define BLOG_CHANNEL_NCDUdevCache 72 -#define BLOG_CHANNEL_NCDUdevManager 73 -#define BLOG_CHANNEL_BTime 74 -#define BLOG_CHANNEL_BEncryption 75 -#define BLOG_CHANNEL_SPProtoDecoder 76 -#define BLOG_CHANNEL_LineBuffer 77 -#define BLOG_CHANNEL_BTap 78 -#define BLOG_CHANNEL_lwip 79 -#define BLOG_CHANNEL_NCDConfigTokenizer 80 -#define BLOG_CHANNEL_NCDConfigParser 81 -#define BLOG_CHANNEL_NCDValParser 82 -#define BLOG_CHANNEL_nsskey 83 -#define BLOG_CHANNEL_addr 84 -#define BLOG_CHANNEL_PasswordListener 85 -#define BLOG_CHANNEL_NCDInterfaceMonitor 86 -#define BLOG_CHANNEL_NCDRfkillMonitor 87 -#define BLOG_CHANNEL_udpgw 88 -#define BLOG_CHANNEL_UdpGwClient 89 -#define BLOG_CHANNEL_SocksUdpGwClient 90 -#define BLOG_CHANNEL_BNetwork 91 -#define BLOG_CHANNEL_BConnection 92 -#define BLOG_CHANNEL_BSSLConnection 93 -#define BLOG_CHANNEL_BDatagram 94 -#define BLOG_CHANNEL_PeerChat 95 -#define BLOG_CHANNEL_BArpProbe 96 -#define BLOG_CHANNEL_NCDModuleIndex 97 -#define BLOG_CHANNEL_NCDModuleProcess 98 -#define BLOG_CHANNEL_NCDValGenerator 99 -#define BLOG_CHANNEL_ncd_from_string 100 -#define BLOG_CHANNEL_ncd_to_string 101 -#define BLOG_CHANNEL_ncd_value 102 -#define BLOG_CHANNEL_ncd_try 103 -#define BLOG_CHANNEL_ncd_sys_request_server 104 -#define BLOG_CHANNEL_NCDRequest 105 -#define BLOG_CHANNEL_ncd_net_ipv6_wait_dynamic_addr 106 -#define BLOG_CHANNEL_NCDRequestClient 107 -#define BLOG_CHANNEL_ncd_request 108 -#define BLOG_CHANNEL_ncd_sys_request_client 109 -#define BLOG_CHANNEL_ncd_exit 110 -#define BLOG_CHANNEL_ncd_getargs 111 -#define BLOG_CHANNEL_ncd_arithmetic 112 -#define BLOG_CHANNEL_ncd_parse 113 -#define BLOG_CHANNEL_ncd_valuemetic 114 -#define BLOG_CHANNEL_ncd_file 115 -#define BLOG_CHANNEL_ncd_netmask 116 -#define BLOG_CHANNEL_ncd_implode 117 -#define BLOG_CHANNEL_ncd_call2 118 -#define BLOG_CHANNEL_ncd_assert 119 -#define BLOG_CHANNEL_ncd_reboot 120 -#define BLOG_CHANNEL_ncd_explode 121 -#define BLOG_CHANNEL_NCDPlaceholderDb 122 -#define BLOG_CHANNEL_NCDVal 123 -#define BLOG_CHANNEL_ncd_net_ipv6_addr 124 -#define BLOG_CHANNEL_ncd_net_ipv6_route 125 -#define BLOG_CHANNEL_ncd_net_ipv4_addr_in_network 126 -#define BLOG_CHANNEL_ncd_net_ipv6_addr_in_network 127 -#define BLOG_CHANNEL_dostest_server 128 -#define BLOG_CHANNEL_dostest_attacker 129 -#define BLOG_CHANNEL_ncd_timer 130 -#define BLOG_CHANNEL_ncd_file_open 131 -#define BLOG_CHANNEL_ncd_backtrack 132 -#define BLOG_CHANNEL_ncd_socket 133 -#define BLOG_CHANNEL_ncd_depend_scope 134 -#define BLOG_CHANNEL_ncd_substr 135 -#define BLOG_CHANNEL_ncd_sys_start_process 136 -#define BLOG_CHANNEL_NCDBuildProgram 137 -#define BLOG_CHANNEL_ncd_log 138 -#define BLOG_CHANNEL_ncd_log_msg 139 -#define BLOG_CHANNEL_ncd_buffer 140 -#define BLOG_CHANNEL_ncd_getenv 141 -#define BLOG_CHANNEL_BThreadSignal 142 -#define BLOG_CHANNEL_BLockReactor 143 -#define BLOG_CHANNEL_ncd_load_module 144 -#define BLOG_NUM_CHANNELS 145 diff --git a/external/badvpn_dns/generated/blog_channels_list.h b/external/badvpn_dns/generated/blog_channels_list.h deleted file mode 100644 index c903c0f..0000000 --- a/external/badvpn_dns/generated/blog_channels_list.h +++ /dev/null @@ -1,145 +0,0 @@ -{"server", 4}, -{"client", 4}, -{"flooder", 4}, -{"tun2socks", 4}, -{"ncd", 4}, -{"ncd_var", 4}, -{"ncd_list", 4}, -{"ncd_depend", 4}, -{"ncd_multidepend", 4}, -{"ncd_dynamic_depend", 4}, -{"ncd_concat", 4}, -{"ncd_if", 4}, -{"ncd_strcmp", 4}, -{"ncd_regex_match", 4}, -{"ncd_logical", 4}, -{"ncd_sleep", 4}, -{"ncd_print", 4}, -{"ncd_blocker", 4}, -{"ncd_run", 4}, -{"ncd_runonce", 4}, -{"ncd_daemon", 4}, -{"ncd_spawn", 4}, -{"ncd_imperative", 4}, -{"ncd_ref", 4}, -{"ncd_index", 4}, -{"ncd_alias", 4}, -{"ncd_process_manager", 4}, -{"ncd_ondemand", 4}, -{"ncd_foreach", 4}, -{"ncd_choose", 4}, -{"ncd_net_backend_waitdevice", 4}, -{"ncd_net_backend_waitlink", 4}, -{"ncd_net_backend_badvpn", 4}, -{"ncd_net_backend_wpa_supplicant", 4}, -{"ncd_net_backend_rfkill", 4}, -{"ncd_net_up", 4}, -{"ncd_net_dns", 4}, -{"ncd_net_iptables", 4}, -{"ncd_net_ipv4_addr", 4}, -{"ncd_net_ipv4_route", 4}, -{"ncd_net_ipv4_dhcp", 4}, -{"ncd_net_ipv4_arp_probe", 4}, -{"ncd_net_watch_interfaces", 4}, -{"ncd_sys_watch_input", 4}, -{"ncd_sys_watch_usb", 4}, -{"ncd_sys_evdev", 4}, -{"ncd_sys_watch_directory", 4}, -{"StreamPeerIO", 4}, -{"DatagramPeerIO", 4}, -{"BReactor", 3}, -{"BSignal", 3}, -{"FragmentProtoAssembler", 4}, -{"BPredicate", 3}, -{"ServerConnection", 4}, -{"Listener", 4}, -{"DataProto", 4}, -{"FrameDecider", 4}, -{"BSocksClient", 4}, -{"BDHCPClientCore", 4}, -{"BDHCPClient", 4}, -{"NCDIfConfig", 4}, -{"BUnixSignal", 4}, -{"BProcess", 4}, -{"PRStreamSink", 4}, -{"PRStreamSource", 4}, -{"PacketProtoDecoder", 4}, -{"DPRelay", 4}, -{"BThreadWork", 4}, -{"DPReceive", 4}, -{"BInputProcess", 4}, -{"NCDUdevMonitorParser", 4}, -{"NCDUdevMonitor", 4}, -{"NCDUdevCache", 4}, -{"NCDUdevManager", 4}, -{"BTime", 4}, -{"BEncryption", 4}, -{"SPProtoDecoder", 4}, -{"LineBuffer", 4}, -{"BTap", 4}, -{"lwip", 4}, -{"NCDConfigTokenizer", 4}, -{"NCDConfigParser", 4}, -{"NCDValParser", 4}, -{"nsskey", 4}, -{"addr", 4}, -{"PasswordListener", 4}, -{"NCDInterfaceMonitor", 4}, -{"NCDRfkillMonitor", 4}, -{"udpgw", 4}, -{"UdpGwClient", 4}, -{"SocksUdpGwClient", 4}, -{"BNetwork", 4}, -{"BConnection", 4}, -{"BSSLConnection", 4}, -{"BDatagram", 4}, -{"PeerChat", 4}, -{"BArpProbe", 4}, -{"NCDModuleIndex", 4}, -{"NCDModuleProcess", 4}, -{"NCDValGenerator", 4}, -{"ncd_from_string", 4}, -{"ncd_to_string", 4}, -{"ncd_value", 4}, -{"ncd_try", 4}, -{"ncd_sys_request_server", 4}, -{"NCDRequest", 4}, -{"ncd_net_ipv6_wait_dynamic_addr", 4}, -{"NCDRequestClient", 4}, -{"ncd_request", 4}, -{"ncd_sys_request_client", 4}, -{"ncd_exit", 4}, -{"ncd_getargs", 4}, -{"ncd_arithmetic", 4}, -{"ncd_parse", 4}, -{"ncd_valuemetic", 4}, -{"ncd_file", 4}, -{"ncd_netmask", 4}, -{"ncd_implode", 4}, -{"ncd_call2", 4}, -{"ncd_assert", 4}, -{"ncd_reboot", 4}, -{"ncd_explode", 4}, -{"NCDPlaceholderDb", 4}, -{"NCDVal", 4}, -{"ncd_net_ipv6_addr", 4}, -{"ncd_net_ipv6_route", 4}, -{"ncd_net_ipv4_addr_in_network", 4}, -{"ncd_net_ipv6_addr_in_network", 4}, -{"dostest_server", 4}, -{"dostest_attacker", 4}, -{"ncd_timer", 4}, -{"ncd_file_open", 4}, -{"ncd_backtrack", 4}, -{"ncd_socket", 4}, -{"ncd_depend_scope", 4}, -{"ncd_substr", 4}, -{"ncd_sys_start_process", 4}, -{"NCDBuildProgram", 4}, -{"ncd_log", 4}, -{"ncd_log_msg", 4}, -{"ncd_buffer", 4}, -{"ncd_getenv", 4}, -{"BThreadSignal", 4}, -{"BLockReactor", 4}, -{"ncd_load_module", 4}, diff --git a/external/badvpn_dns/generated/bproto_addr.h b/external/badvpn_dns/generated/bproto_addr.h deleted file mode 100644 index fbd96a8..0000000 --- a/external/badvpn_dns/generated/bproto_addr.h +++ /dev/null @@ -1,675 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <bproto/BProto.h> - - -#define addr_SIZEtype (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint8_s)) -#define addr_SIZEip_port (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (2)) -#define addr_SIZEipv4_addr (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (4)) -#define addr_SIZEipv6_addr (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (16)) - -typedef struct { - uint8_t *out; - int used; - int type_count; - int ip_port_count; - int ipv4_addr_count; - int ipv6_addr_count; -} addrWriter; - -static void addrWriter_Init (addrWriter *o, uint8_t *out); -static int addrWriter_Finish (addrWriter *o); -static void addrWriter_Addtype (addrWriter *o, uint8_t v); -static uint8_t * addrWriter_Addip_port (addrWriter *o); -static uint8_t * addrWriter_Addipv4_addr (addrWriter *o); -static uint8_t * addrWriter_Addipv6_addr (addrWriter *o); - -typedef struct { - uint8_t *buf; - int buf_len; - int type_start; - int type_span; - int type_pos; - int ip_port_start; - int ip_port_span; - int ip_port_pos; - int ipv4_addr_start; - int ipv4_addr_span; - int ipv4_addr_pos; - int ipv6_addr_start; - int ipv6_addr_span; - int ipv6_addr_pos; -} addrParser; - -static int addrParser_Init (addrParser *o, uint8_t *buf, int buf_len); -static int addrParser_GotEverything (addrParser *o); -static int addrParser_Gettype (addrParser *o, uint8_t *v); -static void addrParser_Resettype (addrParser *o); -static void addrParser_Forwardtype (addrParser *o); -static int addrParser_Getip_port (addrParser *o, uint8_t **data); -static void addrParser_Resetip_port (addrParser *o); -static void addrParser_Forwardip_port (addrParser *o); -static int addrParser_Getipv4_addr (addrParser *o, uint8_t **data); -static void addrParser_Resetipv4_addr (addrParser *o); -static void addrParser_Forwardipv4_addr (addrParser *o); -static int addrParser_Getipv6_addr (addrParser *o, uint8_t **data); -static void addrParser_Resetipv6_addr (addrParser *o); -static void addrParser_Forwardipv6_addr (addrParser *o); - -void addrWriter_Init (addrWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->type_count = 0; - o->ip_port_count = 0; - o->ipv4_addr_count = 0; - o->ipv6_addr_count = 0; -} - -int addrWriter_Finish (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 1) - ASSERT(o->ip_port_count >= 0 && o->ip_port_count <= 1) - ASSERT(o->ipv4_addr_count >= 0 && o->ipv4_addr_count <= 1) - ASSERT(o->ipv6_addr_count >= 0 && o->ipv6_addr_count <= 1) - - return o->used; -} - -void addrWriter_Addtype (addrWriter *o, uint8_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT8); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint8_s data; - data.v = htol8(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint8_s); - - o->type_count++; -} - -uint8_t * addrWriter_Addip_port (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ip_port_count == 0) - - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(2); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (2); - - o->ip_port_count++; - - return dest; -} - -uint8_t * addrWriter_Addipv4_addr (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ipv4_addr_count == 0) - - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(4); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (4); - - o->ipv4_addr_count++; - - return dest; -} - -uint8_t * addrWriter_Addipv6_addr (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ipv6_addr_count == 0) - - - struct BProto_header_s header; - header.id = htol16(4); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(16); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (16); - - o->ipv6_addr_count++; - - return dest; -} - -int addrParser_Init (addrParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->type_start = o->buf_len; - o->type_span = 0; - o->type_pos = 0; - o->ip_port_start = o->buf_len; - o->ip_port_span = 0; - o->ip_port_pos = 0; - o->ipv4_addr_start = o->buf_len; - o->ipv4_addr_span = 0; - o->ipv4_addr_pos = 0; - o->ipv6_addr_start = o->buf_len; - o->ipv6_addr_span = 0; - o->ipv6_addr_pos = 0; - - int type_count = 0; - int ip_port_count = 0; - int ipv4_addr_count = 0; - int ipv6_addr_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - case 1: - if (o->type_start == o->buf_len) { - o->type_start = entry_pos; - } - o->type_span = pos - o->type_start; - type_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (2))) { - return 0; - } - if (o->ip_port_start == o->buf_len) { - o->ip_port_start = entry_pos; - } - o->ip_port_span = pos - o->ip_port_start; - ip_port_count++; - break; - case 3: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (4))) { - return 0; - } - if (o->ipv4_addr_start == o->buf_len) { - o->ipv4_addr_start = entry_pos; - } - o->ipv4_addr_span = pos - o->ipv4_addr_start; - ipv4_addr_count++; - break; - case 4: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (16))) { - return 0; - } - if (o->ipv6_addr_start == o->buf_len) { - o->ipv6_addr_start = entry_pos; - } - o->ipv6_addr_span = pos - o->ipv6_addr_start; - ipv6_addr_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(type_count == 1)) { - return 0; - } - if (!(ip_port_count <= 1)) { - return 0; - } - if (!(ipv4_addr_count <= 1)) { - return 0; - } - if (!(ipv6_addr_count <= 1)) { - return 0; - } - - return 1; -} - -int addrParser_GotEverything (addrParser *o) -{ - return ( - o->type_pos == o->type_span - && - o->ip_port_pos == o->ip_port_span - && - o->ipv4_addr_pos == o->ipv4_addr_span - && - o->ipv6_addr_pos == o->ipv6_addr_span - ); -} - -int addrParser_Gettype (addrParser *o, uint8_t *v) -{ - ASSERT(o->type_pos >= 0) - ASSERT(o->type_pos <= o->type_span) - - int left = o->type_span - o->type_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->type_start + o->type_pos, sizeof(header)); - o->type_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - struct BProto_uint8_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - if (id == 1) { - *v = ltoh8(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->type_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->type_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->type_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->type_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resettype (addrParser *o) -{ - o->type_pos = 0; -} - -void addrParser_Forwardtype (addrParser *o) -{ - o->type_pos = o->type_span; -} - -int addrParser_Getip_port (addrParser *o, uint8_t **data) -{ - ASSERT(o->ip_port_pos >= 0) - ASSERT(o->ip_port_pos <= o->ip_port_span) - - int left = o->ip_port_span - o->ip_port_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ip_port_start + o->ip_port_pos, sizeof(header)); - o->ip_port_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ip_port_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ip_port_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ip_port_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ip_port_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ip_port_start + o->ip_port_pos, sizeof(val)); - o->ip_port_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ip_port_start + o->ip_port_pos; - o->ip_port_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 2) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetip_port (addrParser *o) -{ - o->ip_port_pos = 0; -} - -void addrParser_Forwardip_port (addrParser *o) -{ - o->ip_port_pos = o->ip_port_span; -} - -int addrParser_Getipv4_addr (addrParser *o, uint8_t **data) -{ - ASSERT(o->ipv4_addr_pos >= 0) - ASSERT(o->ipv4_addr_pos <= o->ipv4_addr_span) - - int left = o->ipv4_addr_span - o->ipv4_addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ipv4_addr_start + o->ipv4_addr_pos, sizeof(header)); - o->ipv4_addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ipv4_addr_start + o->ipv4_addr_pos, sizeof(val)); - o->ipv4_addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ipv4_addr_start + o->ipv4_addr_pos; - o->ipv4_addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 3) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetipv4_addr (addrParser *o) -{ - o->ipv4_addr_pos = 0; -} - -void addrParser_Forwardipv4_addr (addrParser *o) -{ - o->ipv4_addr_pos = o->ipv4_addr_span; -} - -int addrParser_Getipv6_addr (addrParser *o, uint8_t **data) -{ - ASSERT(o->ipv6_addr_pos >= 0) - ASSERT(o->ipv6_addr_pos <= o->ipv6_addr_span) - - int left = o->ipv6_addr_span - o->ipv6_addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ipv6_addr_start + o->ipv6_addr_pos, sizeof(header)); - o->ipv6_addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ipv6_addr_start + o->ipv6_addr_pos, sizeof(val)); - o->ipv6_addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ipv6_addr_start + o->ipv6_addr_pos; - o->ipv6_addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 4) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetipv6_addr (addrParser *o) -{ - o->ipv6_addr_pos = 0; -} - -void addrParser_Forwardipv6_addr (addrParser *o) -{ - o->ipv6_addr_pos = o->ipv6_addr_span; -} - diff --git a/external/badvpn_dns/generated/bproto_bproto_test.h b/external/badvpn_dns/generated/bproto_bproto_test.h deleted file mode 100644 index dc4ad80..0000000 --- a/external/badvpn_dns/generated/bproto_bproto_test.h +++ /dev/null @@ -1,1029 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <bproto/BProto.h> - - -#define msg1_SIZEa (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg1_SIZEb (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint32_s)) -#define msg1_SIZEc (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint64_s)) -#define msg1_SIZEd (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg1_SIZEe (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint8_s)) -#define msg1_SIZEf(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg1_SIZEg (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (4)) - -typedef struct { - uint8_t *out; - int used; - int a_count; - int b_count; - int c_count; - int d_count; - int e_count; - int f_count; - int g_count; -} msg1Writer; - -static void msg1Writer_Init (msg1Writer *o, uint8_t *out); -static int msg1Writer_Finish (msg1Writer *o); -static void msg1Writer_Adda (msg1Writer *o, uint16_t v); -static void msg1Writer_Addb (msg1Writer *o, uint32_t v); -static void msg1Writer_Addc (msg1Writer *o, uint64_t v); -static void msg1Writer_Addd (msg1Writer *o, uint16_t v); -static void msg1Writer_Adde (msg1Writer *o, uint8_t v); -static uint8_t * msg1Writer_Addf (msg1Writer *o, int len); -static uint8_t * msg1Writer_Addg (msg1Writer *o); - -typedef struct { - uint8_t *buf; - int buf_len; - int a_start; - int a_span; - int a_pos; - int b_start; - int b_span; - int b_pos; - int c_start; - int c_span; - int c_pos; - int d_start; - int d_span; - int d_pos; - int e_start; - int e_span; - int e_pos; - int f_start; - int f_span; - int f_pos; - int g_start; - int g_span; - int g_pos; -} msg1Parser; - -static int msg1Parser_Init (msg1Parser *o, uint8_t *buf, int buf_len); -static int msg1Parser_GotEverything (msg1Parser *o); -static int msg1Parser_Geta (msg1Parser *o, uint16_t *v); -static void msg1Parser_Reseta (msg1Parser *o); -static void msg1Parser_Forwarda (msg1Parser *o); -static int msg1Parser_Getb (msg1Parser *o, uint32_t *v); -static void msg1Parser_Resetb (msg1Parser *o); -static void msg1Parser_Forwardb (msg1Parser *o); -static int msg1Parser_Getc (msg1Parser *o, uint64_t *v); -static void msg1Parser_Resetc (msg1Parser *o); -static void msg1Parser_Forwardc (msg1Parser *o); -static int msg1Parser_Getd (msg1Parser *o, uint16_t *v); -static void msg1Parser_Resetd (msg1Parser *o); -static void msg1Parser_Forwardd (msg1Parser *o); -static int msg1Parser_Gete (msg1Parser *o, uint8_t *v); -static void msg1Parser_Resete (msg1Parser *o); -static void msg1Parser_Forwarde (msg1Parser *o); -static int msg1Parser_Getf (msg1Parser *o, uint8_t **data, int *data_len); -static void msg1Parser_Resetf (msg1Parser *o); -static void msg1Parser_Forwardf (msg1Parser *o); -static int msg1Parser_Getg (msg1Parser *o, uint8_t **data); -static void msg1Parser_Resetg (msg1Parser *o); -static void msg1Parser_Forwardg (msg1Parser *o); - -void msg1Writer_Init (msg1Writer *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->a_count = 0; - o->b_count = 0; - o->c_count = 0; - o->d_count = 0; - o->e_count = 0; - o->f_count = 0; - o->g_count = 0; -} - -int msg1Writer_Finish (msg1Writer *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->a_count == 1) - ASSERT(o->b_count >= 0 && o->b_count <= 1) - ASSERT(o->c_count >= 1) - ASSERT(o->d_count >= 0) - ASSERT(o->e_count == 1) - ASSERT(o->f_count == 1) - ASSERT(o->g_count == 1) - - return o->used; -} - -void msg1Writer_Adda (msg1Writer *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->a_count == 0) - - - struct BProto_header_s header; - header.id = htol16(5); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->a_count++; -} - -void msg1Writer_Addb (msg1Writer *o, uint32_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->b_count == 0) - - - struct BProto_header_s header; - header.id = htol16(6); - header.type = htol16(BPROTO_TYPE_UINT32); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint32_s data; - data.v = htol32(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint32_s); - - o->b_count++; -} - -void msg1Writer_Addc (msg1Writer *o, uint64_t v) -{ - ASSERT(o->used >= 0) - - - - struct BProto_header_s header; - header.id = htol16(7); - header.type = htol16(BPROTO_TYPE_UINT64); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint64_s data; - data.v = htol64(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint64_s); - - o->c_count++; -} - -void msg1Writer_Addd (msg1Writer *o, uint16_t v) -{ - ASSERT(o->used >= 0) - - - - struct BProto_header_s header; - header.id = htol16(8); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->d_count++; -} - -void msg1Writer_Adde (msg1Writer *o, uint8_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->e_count == 0) - - - struct BProto_header_s header; - header.id = htol16(9); - header.type = htol16(BPROTO_TYPE_UINT8); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint8_s data; - data.v = htol8(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint8_s); - - o->e_count++; -} - -uint8_t * msg1Writer_Addf (msg1Writer *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->f_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(10); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->f_count++; - - return dest; -} - -uint8_t * msg1Writer_Addg (msg1Writer *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->g_count == 0) - - - struct BProto_header_s header; - header.id = htol16(11); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(4); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (4); - - o->g_count++; - - return dest; -} - -int msg1Parser_Init (msg1Parser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->a_start = o->buf_len; - o->a_span = 0; - o->a_pos = 0; - o->b_start = o->buf_len; - o->b_span = 0; - o->b_pos = 0; - o->c_start = o->buf_len; - o->c_span = 0; - o->c_pos = 0; - o->d_start = o->buf_len; - o->d_span = 0; - o->d_pos = 0; - o->e_start = o->buf_len; - o->e_span = 0; - o->e_pos = 0; - o->f_start = o->buf_len; - o->f_span = 0; - o->f_pos = 0; - o->g_start = o->buf_len; - o->g_span = 0; - o->g_pos = 0; - - int a_count = 0; - int b_count = 0; - int c_count = 0; - int d_count = 0; - int e_count = 0; - int f_count = 0; - int g_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - case 9: - if (o->e_start == o->buf_len) { - o->e_start = entry_pos; - } - o->e_span = pos - o->e_start; - e_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 5: - if (o->a_start == o->buf_len) { - o->a_start = entry_pos; - } - o->a_span = pos - o->a_start; - a_count++; - break; - case 8: - if (o->d_start == o->buf_len) { - o->d_start = entry_pos; - } - o->d_span = pos - o->d_start; - d_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - case 6: - if (o->b_start == o->buf_len) { - o->b_start = entry_pos; - } - o->b_span = pos - o->b_start; - b_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - case 7: - if (o->c_start == o->buf_len) { - o->c_start = entry_pos; - } - o->c_span = pos - o->c_start; - c_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 10: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->f_start == o->buf_len) { - o->f_start = entry_pos; - } - o->f_span = pos - o->f_start; - f_count++; - break; - case 11: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (4))) { - return 0; - } - if (o->g_start == o->buf_len) { - o->g_start = entry_pos; - } - o->g_span = pos - o->g_start; - g_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(a_count == 1)) { - return 0; - } - if (!(b_count <= 1)) { - return 0; - } - if (!(c_count >= 1)) { - return 0; - } - if (!(e_count == 1)) { - return 0; - } - if (!(f_count == 1)) { - return 0; - } - if (!(g_count == 1)) { - return 0; - } - - return 1; -} - -int msg1Parser_GotEverything (msg1Parser *o) -{ - return ( - o->a_pos == o->a_span - && - o->b_pos == o->b_span - && - o->c_pos == o->c_span - && - o->d_pos == o->d_span - && - o->e_pos == o->e_span - && - o->f_pos == o->f_span - && - o->g_pos == o->g_span - ); -} - -int msg1Parser_Geta (msg1Parser *o, uint16_t *v) -{ - ASSERT(o->a_pos >= 0) - ASSERT(o->a_pos <= o->a_span) - - int left = o->a_span - o->a_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->a_start + o->a_pos, sizeof(header)); - o->a_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->a_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->a_start + o->a_pos, sizeof(val)); - o->a_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 5) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->a_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->a_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->a_start + o->a_pos, sizeof(val)); - o->a_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->a_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Reseta (msg1Parser *o) -{ - o->a_pos = 0; -} - -void msg1Parser_Forwarda (msg1Parser *o) -{ - o->a_pos = o->a_span; -} - -int msg1Parser_Getb (msg1Parser *o, uint32_t *v) -{ - ASSERT(o->b_pos >= 0) - ASSERT(o->b_pos <= o->b_span) - - int left = o->b_span - o->b_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->b_start + o->b_pos, sizeof(header)); - o->b_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->b_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->b_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - struct BProto_uint32_s val; - memcpy(&val, o->buf + o->b_start + o->b_pos, sizeof(val)); - o->b_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - if (id == 6) { - *v = ltoh32(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->b_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->b_start + o->b_pos, sizeof(val)); - o->b_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->b_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetb (msg1Parser *o) -{ - o->b_pos = 0; -} - -void msg1Parser_Forwardb (msg1Parser *o) -{ - o->b_pos = o->b_span; -} - -int msg1Parser_Getc (msg1Parser *o, uint64_t *v) -{ - ASSERT(o->c_pos >= 0) - ASSERT(o->c_pos <= o->c_span) - - int left = o->c_span - o->c_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->c_start + o->c_pos, sizeof(header)); - o->c_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->c_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->c_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->c_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - struct BProto_uint64_s val; - memcpy(&val, o->buf + o->c_start + o->c_pos, sizeof(val)); - o->c_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - if (id == 7) { - *v = ltoh64(val.v); - return 1; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->c_start + o->c_pos, sizeof(val)); - o->c_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->c_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetc (msg1Parser *o) -{ - o->c_pos = 0; -} - -void msg1Parser_Forwardc (msg1Parser *o) -{ - o->c_pos = o->c_span; -} - -int msg1Parser_Getd (msg1Parser *o, uint16_t *v) -{ - ASSERT(o->d_pos >= 0) - ASSERT(o->d_pos <= o->d_span) - - int left = o->d_span - o->d_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->d_start + o->d_pos, sizeof(header)); - o->d_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->d_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->d_start + o->d_pos, sizeof(val)); - o->d_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 8) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->d_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->d_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->d_start + o->d_pos, sizeof(val)); - o->d_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->d_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetd (msg1Parser *o) -{ - o->d_pos = 0; -} - -void msg1Parser_Forwardd (msg1Parser *o) -{ - o->d_pos = o->d_span; -} - -int msg1Parser_Gete (msg1Parser *o, uint8_t *v) -{ - ASSERT(o->e_pos >= 0) - ASSERT(o->e_pos <= o->e_span) - - int left = o->e_span - o->e_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->e_start + o->e_pos, sizeof(header)); - o->e_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - struct BProto_uint8_s val; - memcpy(&val, o->buf + o->e_start + o->e_pos, sizeof(val)); - o->e_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - if (id == 9) { - *v = ltoh8(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->e_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->e_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->e_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->e_start + o->e_pos, sizeof(val)); - o->e_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->e_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resete (msg1Parser *o) -{ - o->e_pos = 0; -} - -void msg1Parser_Forwarde (msg1Parser *o) -{ - o->e_pos = o->e_span; -} - -int msg1Parser_Getf (msg1Parser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->f_pos >= 0) - ASSERT(o->f_pos <= o->f_span) - - int left = o->f_span - o->f_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->f_start + o->f_pos, sizeof(header)); - o->f_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->f_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->f_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->f_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->f_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->f_start + o->f_pos, sizeof(val)); - o->f_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->f_start + o->f_pos; - o->f_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 10) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetf (msg1Parser *o) -{ - o->f_pos = 0; -} - -void msg1Parser_Forwardf (msg1Parser *o) -{ - o->f_pos = o->f_span; -} - -int msg1Parser_Getg (msg1Parser *o, uint8_t **data) -{ - ASSERT(o->g_pos >= 0) - ASSERT(o->g_pos <= o->g_span) - - int left = o->g_span - o->g_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->g_start + o->g_pos, sizeof(header)); - o->g_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->g_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->g_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->g_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->g_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->g_start + o->g_pos, sizeof(val)); - o->g_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->g_start + o->g_pos; - o->g_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 11) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetg (msg1Parser *o) -{ - o->g_pos = 0; -} - -void msg1Parser_Forwardg (msg1Parser *o) -{ - o->g_pos = o->g_span; -} - diff --git a/external/badvpn_dns/generated/bproto_msgproto.h b/external/badvpn_dns/generated/bproto_msgproto.h deleted file mode 100644 index e429223..0000000 --- a/external/badvpn_dns/generated/bproto_msgproto.h +++ /dev/null @@ -1,2122 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <bproto/BProto.h> - - -#define msg_SIZEtype (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg_SIZEpayload(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int type_count; - int payload_count; -} msgWriter; - -static void msgWriter_Init (msgWriter *o, uint8_t *out); -static int msgWriter_Finish (msgWriter *o); -static void msgWriter_Addtype (msgWriter *o, uint16_t v); -static uint8_t * msgWriter_Addpayload (msgWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int type_start; - int type_span; - int type_pos; - int payload_start; - int payload_span; - int payload_pos; -} msgParser; - -static int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len); -static int msgParser_GotEverything (msgParser *o); -static int msgParser_Gettype (msgParser *o, uint16_t *v); -static void msgParser_Resettype (msgParser *o); -static void msgParser_Forwardtype (msgParser *o); -static int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len); -static void msgParser_Resetpayload (msgParser *o); -static void msgParser_Forwardpayload (msgParser *o); - -void msgWriter_Init (msgWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->type_count = 0; - o->payload_count = 0; -} - -int msgWriter_Finish (msgWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 1) - ASSERT(o->payload_count == 1) - - return o->used; -} - -void msgWriter_Addtype (msgWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->type_count++; -} - -uint8_t * msgWriter_Addpayload (msgWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->payload_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->payload_count++; - - return dest; -} - -int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->type_start = o->buf_len; - o->type_span = 0; - o->type_pos = 0; - o->payload_start = o->buf_len; - o->payload_span = 0; - o->payload_pos = 0; - - int type_count = 0; - int payload_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->type_start == o->buf_len) { - o->type_start = entry_pos; - } - o->type_span = pos - o->type_start; - type_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->payload_start == o->buf_len) { - o->payload_start = entry_pos; - } - o->payload_span = pos - o->payload_start; - payload_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(type_count == 1)) { - return 0; - } - if (!(payload_count == 1)) { - return 0; - } - - return 1; -} - -int msgParser_GotEverything (msgParser *o) -{ - return ( - o->type_pos == o->type_span - && - o->payload_pos == o->payload_span - ); -} - -int msgParser_Gettype (msgParser *o, uint16_t *v) -{ - ASSERT(o->type_pos >= 0) - ASSERT(o->type_pos <= o->type_span) - - int left = o->type_span - o->type_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->type_start + o->type_pos, sizeof(header)); - o->type_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->type_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->type_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->type_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->type_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msgParser_Resettype (msgParser *o) -{ - o->type_pos = 0; -} - -void msgParser_Forwardtype (msgParser *o) -{ - o->type_pos = o->type_span; -} - -int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->payload_pos >= 0) - ASSERT(o->payload_pos <= o->payload_span) - - int left = o->payload_span - o->payload_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->payload_start + o->payload_pos, sizeof(header)); - o->payload_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->payload_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->payload_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->payload_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->payload_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->payload_start + o->payload_pos, sizeof(val)); - o->payload_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->payload_start + o->payload_pos; - o->payload_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msgParser_Resetpayload (msgParser *o) -{ - o->payload_pos = 0; -} - -void msgParser_Forwardpayload (msgParser *o) -{ - o->payload_pos = o->payload_span; -} - -#define msg_youconnect_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_SIZEpassword (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint64_s)) - -typedef struct { - uint8_t *out; - int used; - int addr_count; - int key_count; - int password_count; -} msg_youconnectWriter; - -static void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out); -static int msg_youconnectWriter_Finish (msg_youconnectWriter *o); -static uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len); -static uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len); -static void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v); - -typedef struct { - uint8_t *buf; - int buf_len; - int addr_start; - int addr_span; - int addr_pos; - int key_start; - int key_span; - int key_pos; - int password_start; - int password_span; - int password_pos; -} msg_youconnectParser; - -static int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len); -static int msg_youconnectParser_GotEverything (msg_youconnectParser *o); -static int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len); -static void msg_youconnectParser_Resetaddr (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o); -static int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len); -static void msg_youconnectParser_Resetkey (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardkey (msg_youconnectParser *o); -static int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v); -static void msg_youconnectParser_Resetpassword (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o); - -void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->addr_count = 0; - o->key_count = 0; - o->password_count = 0; -} - -int msg_youconnectWriter_Finish (msg_youconnectWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->addr_count >= 1) - ASSERT(o->key_count >= 0 && o->key_count <= 1) - ASSERT(o->password_count >= 0 && o->password_count <= 1) - - return o->used; -} - -uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len) -{ - ASSERT(o->used >= 0) - - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->addr_count++; - - return dest; -} - -uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->key_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->key_count++; - - return dest; -} - -void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->password_count == 0) - - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_UINT64); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint64_s data; - data.v = htol64(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint64_s); - - o->password_count++; -} - -int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->addr_start = o->buf_len; - o->addr_span = 0; - o->addr_pos = 0; - o->key_start = o->buf_len; - o->key_span = 0; - o->key_pos = 0; - o->password_start = o->buf_len; - o->password_span = 0; - o->password_pos = 0; - - int addr_count = 0; - int key_count = 0; - int password_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - case 3: - if (o->password_start == o->buf_len) { - o->password_start = entry_pos; - } - o->password_span = pos - o->password_start; - password_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 1: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->addr_start == o->buf_len) { - o->addr_start = entry_pos; - } - o->addr_span = pos - o->addr_start; - addr_count++; - break; - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->key_start == o->buf_len) { - o->key_start = entry_pos; - } - o->key_span = pos - o->key_start; - key_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(addr_count >= 1)) { - return 0; - } - if (!(key_count <= 1)) { - return 0; - } - if (!(password_count <= 1)) { - return 0; - } - - return 1; -} - -int msg_youconnectParser_GotEverything (msg_youconnectParser *o) -{ - return ( - o->addr_pos == o->addr_span - && - o->key_pos == o->key_span - && - o->password_pos == o->password_span - ); -} - -int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->addr_pos >= 0) - ASSERT(o->addr_pos <= o->addr_span) - - int left = o->addr_span - o->addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); - o->addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); - o->addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->addr_start + o->addr_pos; - o->addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 1) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetaddr (msg_youconnectParser *o) -{ - o->addr_pos = 0; -} - -void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o) -{ - o->addr_pos = o->addr_span; -} - -int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->key_pos >= 0) - ASSERT(o->key_pos <= o->key_span) - - int left = o->key_span - o->key_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); - o->key_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->key_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->key_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->key_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->key_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); - o->key_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->key_start + o->key_pos; - o->key_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetkey (msg_youconnectParser *o) -{ - o->key_pos = 0; -} - -void msg_youconnectParser_Forwardkey (msg_youconnectParser *o) -{ - o->key_pos = o->key_span; -} - -int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v) -{ - ASSERT(o->password_pos >= 0) - ASSERT(o->password_pos <= o->password_span) - - int left = o->password_span - o->password_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->password_start + o->password_pos, sizeof(header)); - o->password_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->password_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->password_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->password_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - struct BProto_uint64_s val; - memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); - o->password_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - if (id == 3) { - *v = ltoh64(val.v); - return 1; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); - o->password_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->password_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetpassword (msg_youconnectParser *o) -{ - o->password_pos = 0; -} - -void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o) -{ - o->password_pos = o->password_span; -} - -#define msg_youconnect_addr_SIZEname(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_addr_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int name_count; - int addr_count; -} msg_youconnect_addrWriter; - -static void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out); -static int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o); -static uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len); -static uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int name_start; - int name_span; - int name_pos; - int addr_start; - int addr_span; - int addr_pos; -} msg_youconnect_addrParser; - -static int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len); -static int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o); -static int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); -static void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o); -static void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o); -static int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); -static void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o); -static void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o); - -void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->name_count = 0; - o->addr_count = 0; -} - -int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->name_count == 1) - ASSERT(o->addr_count == 1) - - return o->used; -} - -uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->name_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->name_count++; - - return dest; -} - -uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->addr_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->addr_count++; - - return dest; -} - -int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->name_start = o->buf_len; - o->name_span = 0; - o->name_pos = 0; - o->addr_start = o->buf_len; - o->addr_span = 0; - o->addr_pos = 0; - - int name_count = 0; - int addr_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 1: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->name_start == o->buf_len) { - o->name_start = entry_pos; - } - o->name_span = pos - o->name_start; - name_count++; - break; - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->addr_start == o->buf_len) { - o->addr_start = entry_pos; - } - o->addr_span = pos - o->addr_start; - addr_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(name_count == 1)) { - return 0; - } - if (!(addr_count == 1)) { - return 0; - } - - return 1; -} - -int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o) -{ - return ( - o->name_pos == o->name_span - && - o->addr_pos == o->addr_span - ); -} - -int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->name_pos >= 0) - ASSERT(o->name_pos <= o->name_span) - - int left = o->name_span - o->name_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->name_start + o->name_pos, sizeof(header)); - o->name_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->name_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->name_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->name_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->name_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->name_start + o->name_pos, sizeof(val)); - o->name_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->name_start + o->name_pos; - o->name_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 1) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o) -{ - o->name_pos = 0; -} - -void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o) -{ - o->name_pos = o->name_span; -} - -int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->addr_pos >= 0) - ASSERT(o->addr_pos <= o->addr_span) - - int left = o->addr_span - o->addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); - o->addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); - o->addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->addr_start + o->addr_pos; - o->addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o) -{ - o->addr_pos = 0; -} - -void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o) -{ - o->addr_pos = o->addr_span; -} - -#define msg_seed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg_seed_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_seed_SIZEiv(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int seed_id_count; - int key_count; - int iv_count; -} msg_seedWriter; - -static void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out); -static int msg_seedWriter_Finish (msg_seedWriter *o); -static void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v); -static uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len); -static uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int seed_id_start; - int seed_id_span; - int seed_id_pos; - int key_start; - int key_span; - int key_pos; - int iv_start; - int iv_span; - int iv_pos; -} msg_seedParser; - -static int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len); -static int msg_seedParser_GotEverything (msg_seedParser *o); -static int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v); -static void msg_seedParser_Resetseed_id (msg_seedParser *o); -static void msg_seedParser_Forwardseed_id (msg_seedParser *o); -static int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len); -static void msg_seedParser_Resetkey (msg_seedParser *o); -static void msg_seedParser_Forwardkey (msg_seedParser *o); -static int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len); -static void msg_seedParser_Resetiv (msg_seedParser *o); -static void msg_seedParser_Forwardiv (msg_seedParser *o); - -void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->seed_id_count = 0; - o->key_count = 0; - o->iv_count = 0; -} - -int msg_seedWriter_Finish (msg_seedWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 1) - ASSERT(o->key_count == 1) - ASSERT(o->iv_count == 1) - - return o->used; -} - -void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->seed_id_count++; -} - -uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->key_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->key_count++; - - return dest; -} - -uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->iv_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->iv_count++; - - return dest; -} - -int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->seed_id_start = o->buf_len; - o->seed_id_span = 0; - o->seed_id_pos = 0; - o->key_start = o->buf_len; - o->key_span = 0; - o->key_pos = 0; - o->iv_start = o->buf_len; - o->iv_span = 0; - o->iv_pos = 0; - - int seed_id_count = 0; - int key_count = 0; - int iv_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->seed_id_start == o->buf_len) { - o->seed_id_start = entry_pos; - } - o->seed_id_span = pos - o->seed_id_start; - seed_id_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->key_start == o->buf_len) { - o->key_start = entry_pos; - } - o->key_span = pos - o->key_start; - key_count++; - break; - case 3: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->iv_start == o->buf_len) { - o->iv_start = entry_pos; - } - o->iv_span = pos - o->iv_start; - iv_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(seed_id_count == 1)) { - return 0; - } - if (!(key_count == 1)) { - return 0; - } - if (!(iv_count == 1)) { - return 0; - } - - return 1; -} - -int msg_seedParser_GotEverything (msg_seedParser *o) -{ - return ( - o->seed_id_pos == o->seed_id_span - && - o->key_pos == o->key_span - && - o->iv_pos == o->iv_span - ); -} - -int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v) -{ - ASSERT(o->seed_id_pos >= 0) - ASSERT(o->seed_id_pos <= o->seed_id_span) - - int left = o->seed_id_span - o->seed_id_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); - o->seed_id_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->seed_id_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->seed_id_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->seed_id_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->seed_id_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetseed_id (msg_seedParser *o) -{ - o->seed_id_pos = 0; -} - -void msg_seedParser_Forwardseed_id (msg_seedParser *o) -{ - o->seed_id_pos = o->seed_id_span; -} - -int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->key_pos >= 0) - ASSERT(o->key_pos <= o->key_span) - - int left = o->key_span - o->key_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); - o->key_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->key_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->key_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->key_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->key_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); - o->key_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->key_start + o->key_pos; - o->key_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetkey (msg_seedParser *o) -{ - o->key_pos = 0; -} - -void msg_seedParser_Forwardkey (msg_seedParser *o) -{ - o->key_pos = o->key_span; -} - -int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->iv_pos >= 0) - ASSERT(o->iv_pos <= o->iv_span) - - int left = o->iv_span - o->iv_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->iv_start + o->iv_pos, sizeof(header)); - o->iv_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->iv_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->iv_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->iv_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->iv_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->iv_start + o->iv_pos, sizeof(val)); - o->iv_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->iv_start + o->iv_pos; - o->iv_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 3) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetiv (msg_seedParser *o) -{ - o->iv_pos = 0; -} - -void msg_seedParser_Forwardiv (msg_seedParser *o) -{ - o->iv_pos = o->iv_span; -} - -#define msg_confirmseed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) - -typedef struct { - uint8_t *out; - int used; - int seed_id_count; -} msg_confirmseedWriter; - -static void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out); -static int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o); -static void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v); - -typedef struct { - uint8_t *buf; - int buf_len; - int seed_id_start; - int seed_id_span; - int seed_id_pos; -} msg_confirmseedParser; - -static int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len); -static int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o); -static int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v); -static void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o); -static void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o); - -void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->seed_id_count = 0; -} - -int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 1) - - return o->used; -} - -void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->seed_id_count++; -} - -int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->seed_id_start = o->buf_len; - o->seed_id_span = 0; - o->seed_id_pos = 0; - - int seed_id_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->seed_id_start == o->buf_len) { - o->seed_id_start = entry_pos; - } - o->seed_id_span = pos - o->seed_id_start; - seed_id_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(seed_id_count == 1)) { - return 0; - } - - return 1; -} - -int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o) -{ - return ( - o->seed_id_pos == o->seed_id_span - ); -} - -int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v) -{ - ASSERT(o->seed_id_pos >= 0) - ASSERT(o->seed_id_pos <= o->seed_id_span) - - int left = o->seed_id_span - o->seed_id_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); - o->seed_id_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->seed_id_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->seed_id_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->seed_id_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->seed_id_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o) -{ - o->seed_id_pos = 0; -} - -void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o) -{ - o->seed_id_pos = o->seed_id_span; -} - diff --git a/external/badvpn_dns/generated/flex_BPredicate.c b/external/badvpn_dns/generated/flex_BPredicate.c deleted file mode 100644 index 95f4ff6..0000000 --- a/external/badvpn_dns/generated/flex_BPredicate.c +++ /dev/null @@ -1,2143 +0,0 @@ -#line 2 "generated//flex_BPredicate.c" - -#line 4 "generated//flex_BPredicate.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <stdint.h>. Non-C99 systems may or may not. */ - -#if 1 - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <stdint.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void yypop_buffer_state (yyscan_t yyscanner ); - -static void yyensure_buffer_stack (yyscan_t yyscanner ); -static void yy_load_buffer_state (yyscan_t yyscanner ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap(yyscanner) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 13 -#define YY_END_OF_BUFFER 14 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[34] = - { 0, - 0, 0, 14, 12, 11, 11, 12, 1, 2, 3, - 9, 9, 9, 9, 9, 9, 11, 0, 10, 9, - 9, 9, 5, 9, 9, 4, 6, 9, 9, 9, - 7, 8, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 4, 1, 1, 1, 1, 1, 5, - 6, 1, 1, 7, 1, 1, 1, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, - 1, 1, 1, 1, 9, 8, 8, 10, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 11, 12, 8, - 8, 13, 8, 14, 8, 8, 8, 8, 8, 8, - 1, 1, 1, 1, 8, 1, 15, 8, 8, 8, - - 16, 17, 8, 8, 8, 8, 8, 18, 8, 8, - 8, 8, 8, 19, 20, 21, 22, 8, 8, 8, - 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[23] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2 - } ; - -static yyconst flex_int16_t yy_base[36] = - { 0, - 0, 0, 46, 47, 21, 23, 41, 47, 47, 47, - 0, 33, 31, 29, 26, 21, 25, 35, 47, 0, - 28, 23, 0, 18, 13, 0, 0, 14, 17, 16, - 0, 0, 47, 28, 29 - } ; - -static yyconst flex_int16_t yy_def[36] = - { 0, - 33, 1, 33, 33, 33, 33, 34, 33, 33, 33, - 35, 35, 35, 35, 35, 35, 33, 34, 33, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 0, 33, 33 - } ; - -static yyconst flex_int16_t yy_nxt[70] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 11, - 13, 14, 11, 11, 11, 11, 15, 11, 11, 11, - 16, 11, 17, 17, 17, 17, 17, 17, 18, 18, - 20, 32, 31, 30, 29, 28, 27, 26, 19, 25, - 24, 23, 22, 21, 19, 33, 3, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33 - } ; - -static yyconst flex_int16_t yy_chk[70] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 5, 5, 6, 6, 17, 17, 34, 34, - 35, 30, 29, 28, 25, 24, 22, 21, 18, 16, - 15, 14, 13, 12, 7, 3, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "predicate/BPredicate.l" -/** - * @file BPredicate.l - * @author Ambroz Bizjak <ambrop7@gmail.com> - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} lexer file. - */ -#line 35 "predicate/BPredicate.l" - -#include <string.h> -#include <stdlib.h> - -#include <predicate/LexMemoryBufferInput.h> -#include <predicate/BPredicate_internal.h> - -#include <generated/bison_BPredicate.h> - -#define YY_INPUT(buffer, res, max_size) \ - int bytes_read = LexMemoryBufferInput_Read((LexMemoryBufferInput *)yyget_extra(yyscanner), buffer, max_size); \ - res = (bytes_read == 0 ? YY_NULL : bytes_read); - -#define YY_NO_UNISTD_H 1 -#line 503 "generated//flex_BPredicate.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - yy_size_t yy_n_chars; - yy_size_t yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (yyscan_t yyscanner ); - -int yyget_debug (yyscan_t yyscanner ); - -void yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *yyget_in (yyscan_t yyscanner ); - -void yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *yyget_out (yyscan_t yyscanner ); - -void yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t yyget_leng (yyscan_t yyscanner ); - -char *yyget_text (yyscan_t yyscanner ); - -int yyget_lineno (yyscan_t yyscanner ); - -void yyset_lineno (int line_number ,yyscan_t yyscanner ); - -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - -YYSTYPE * yyget_lval (yyscan_t yyscanner ); - -void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *yyget_lloc (yyscan_t yyscanner ); - - void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (yyscan_t yyscanner ); -#else -extern int yywrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - - static void yy_push_state (int new_state ,yyscan_t yyscanner); - - static void yy_pop_state (yyscan_t yyscanner ); - - static int yy_top_state (yyscan_t yyscanner ); - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 52 "predicate/BPredicate.l" - -#line 756 "generated//flex_BPredicate.c" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 33 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 53 "predicate/BPredicate.l" -return SPAR; - YY_BREAK -case 2: -YY_RULE_SETUP -#line 54 "predicate/BPredicate.l" -return EPAR; - YY_BREAK -case 3: -YY_RULE_SETUP -#line 55 "predicate/BPredicate.l" -return COMMA; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 56 "predicate/BPredicate.l" -return AND; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 57 "predicate/BPredicate.l" -return OR; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 58 "predicate/BPredicate.l" -return NOT; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 59 "predicate/BPredicate.l" -return CONSTANT_TRUE; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 60 "predicate/BPredicate.l" -return CONSTANT_FALSE; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 61 "predicate/BPredicate.l" -{ - int l = strlen(yytext); - char *p = (char *)malloc(l + 1); - if (p) { - memcpy(p, yytext, l); - p[l] = '\0'; - } - yylval->text = p; - return NAME; - } - YY_BREAK -case 10: -/* rule 10 can match eol */ -YY_RULE_SETUP -#line 71 "predicate/BPredicate.l" -{ - int l = strlen(yytext); - char *p = (char *)malloc(l - 1); - if (p) { - memcpy(p, yytext + 1, l - 2); - p[l - 2] = '\0'; - } - yylval->text = p; - return STRING; - } - YY_BREAK -case 11: -/* rule 11 can match eol */ -YY_RULE_SETUP -#line 81 "predicate/BPredicate.l" -; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 82 "predicate/BPredicate.l" -LexMemoryBufferInput_SetError((LexMemoryBufferInput *)yyget_extra(yyscanner)); return 0; // remember failure and report EOF - YY_BREAK -case 13: -YY_RULE_SETUP -#line 83 "predicate/BPredicate.l" -ECHO; - YY_BREAK -#line 924 "generated//flex_BPredicate.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( yywrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 33); - - (void)yyg; - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register yy_size_t number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - yy_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void yy_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * @param yyscanner The scanner object. - */ - void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ,yyscanner ); - - yyfree((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(yyscanner); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void yypop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (yyscan_t yyscanner) -{ - yy_size_t num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - - static void yy_push_state (int new_state , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) - { - yy_size_t new_size; - - yyg->yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yyg->yy_start_stack_depth * sizeof( int ); - - if ( ! yyg->yy_start_stack ) - yyg->yy_start_stack = (int *) yyalloc(new_size ,yyscanner ); - - else - yyg->yy_start_stack = (int *) yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); - - if ( ! yyg->yy_start_stack ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); -} - - static void yy_pop_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( --yyg->yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); -} - - static int yy_top_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int yyget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int yyget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -yy_size_t yyget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *yyget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_column called with no buffer" ); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void yyset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int yyget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void yyset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * yyget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *yyget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* yylex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int yylex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* yylex_init_extra has the same functionality as yylex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to yyalloc in - * the yyextra field. - */ - -int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - yyset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - yyset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - yyfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - yyfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - yyfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 83 "predicate/BPredicate.l" - - - diff --git a/external/badvpn_dns/generated/flex_BPredicate.h b/external/badvpn_dns/generated/flex_BPredicate.h deleted file mode 100644 index f3d2428..0000000 --- a/external/badvpn_dns/generated/flex_BPredicate.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef yyHEADER_H -#define yyHEADER_H 1 -#define yyIN_HEADER 1 - -#line 6 "generated//flex_BPredicate.h" - -#line 8 "generated//flex_BPredicate.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <stdint.h>. Non-C99 systems may or may not. */ - -#if 1 - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <stdint.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void yypop_buffer_state (yyscan_t yyscanner ); - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void yyfree (void * ,yyscan_t yyscanner ); - -/* Begin user sect3 */ - -#define yywrap(yyscanner) 1 -#define YY_SKIP_YYWRAP - -#define yytext_ptr yytext_r - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (yyscan_t yyscanner ); - -int yyget_debug (yyscan_t yyscanner ); - -void yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *yyget_in (yyscan_t yyscanner ); - -void yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *yyget_out (yyscan_t yyscanner ); - -void yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t yyget_leng (yyscan_t yyscanner ); - -char *yyget_text (yyscan_t yyscanner ); - -int yyget_lineno (yyscan_t yyscanner ); - -void yyset_lineno (int line_number ,yyscan_t yyscanner ); - -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - -YYSTYPE * yyget_lval (yyscan_t yyscanner ); - -void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *yyget_lloc (yyscan_t yyscanner ); - - void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (yyscan_t yyscanner ); -#else -extern int yywrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 83 "predicate/BPredicate.l" - - -#line 349 "generated//flex_BPredicate.h" -#undef yyIN_HEADER -#endif /* yyHEADER_H */ diff --git a/external/badvpn_dns/lemon/lemon.c b/external/badvpn_dns/lemon/lemon.c deleted file mode 100644 index 8336e9a..0000000 --- a/external/badvpn_dns/lemon/lemon.c +++ /dev/null @@ -1,4889 +0,0 @@ -/* -** This file contains all sources (including headers) to the LEMON -** LALR(1) parser generator. The sources have been combined into a -** single file to make it easy to include LEMON in the source tree -** and Makefile of another program. -** -** The author of this program disclaims copyright. -*/ -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <assert.h> - -#ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) -# define __WIN32__ -# endif -#endif - -#ifdef __WIN32__ -extern int access(); -#else -#include <unistd.h> -#endif - -/* #define PRIVATE static */ -#define PRIVATE - -#ifdef TEST -#define MAXRHS 5 /* Set low to exercise exception code */ -#else -#define MAXRHS 1000 -#endif - -static char *msort(char*,char**,int(*)(const char*,const char*)); - -/* -** Compilers are getting increasingly pedantic about type conversions -** as C evolves ever closer to Ada.... To work around the latest problems -** we have to define the following variant of strlen(). -*/ -#define lemonStrlen(X) ((int)strlen(X)) - -static struct action *Action_new(void); -static struct action *Action_sort(struct action *); - -/********** From the file "build.h" ************************************/ -void FindRulePrecedences(); -void FindFirstSets(); -void FindStates(); -void FindLinks(); -void FindFollowSets(); -void FindActions(); - -/********* From the file "configlist.h" *********************************/ -void Configlist_init(/* void */); -struct config *Configlist_add(/* struct rule *, int */); -struct config *Configlist_addbasis(/* struct rule *, int */); -void Configlist_closure(/* void */); -void Configlist_sort(/* void */); -void Configlist_sortbasis(/* void */); -struct config *Configlist_return(/* void */); -struct config *Configlist_basis(/* void */); -void Configlist_eat(/* struct config * */); -void Configlist_reset(/* void */); - -/********* From the file "error.h" ***************************************/ -void ErrorMsg(const char *, int,const char *, ...); - -/****** From the file "option.h" ******************************************/ -struct s_options { - enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type; - char *label; - char *arg; - char *message; -}; -int OptInit(/* char**,struct s_options*,FILE* */); -int OptNArgs(/* void */); -char *OptArg(/* int */); -void OptErr(/* int */); -void OptPrint(/* void */); - -/******** From the file "parse.h" *****************************************/ -void Parse(/* struct lemon *lemp */); - -/********* From the file "plink.h" ***************************************/ -struct plink *Plink_new(/* void */); -void Plink_add(/* struct plink **, struct config * */); -void Plink_copy(/* struct plink **, struct plink * */); -void Plink_delete(/* struct plink * */); - -/********** From the file "report.h" *************************************/ -void Reprint(/* struct lemon * */); -void ReportOutput(/* struct lemon * */); -void ReportTable(/* struct lemon * */); -void ReportHeader(/* struct lemon * */); -void CompressTables(/* struct lemon * */); -void ResortStates(/* struct lemon * */); - -/********** From the file "set.h" ****************************************/ -void SetSize(/* int N */); /* All sets will be of size N */ -char *SetNew(/* void */); /* A new set for element 0..N */ -void SetFree(/* char* */); /* Deallocate a set */ - -int SetAdd(/* char*,int */); /* Add element to a set */ -int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ - -#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ - -/********** From the file "struct.h" *************************************/ -/* -** Principal data structures for the LEMON parser generator. -*/ - -typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean; - -/* Symbols (terminals and nonterminals) of the grammar are stored -** in the following: */ -struct symbol { - char *name; /* Name of the symbol */ - int index; /* Index number for this symbol */ - enum { - TERMINAL, - NONTERMINAL, - MULTITERMINAL - } type; /* Symbols are all either TERMINALS or NTs */ - struct rule *rule; /* Linked list of rules of this (if an NT) */ - struct symbol *fallback; /* fallback token in case this token doesn't parse */ - int prec; /* Precedence if defined (-1 otherwise) */ - enum e_assoc { - LEFT, - RIGHT, - NONE, - UNK - } assoc; /* Associativity if precedence is defined */ - char *firstset; /* First-set for all rules of this symbol */ - Boolean lambda; /* True if NT and can generate an empty string */ - int useCnt; /* Number of times used */ - char *destructor; /* Code which executes whenever this symbol is - ** popped from the stack during error processing */ - int destLineno; /* Line number for start of destructor */ - char *datatype; /* The data type of information held by this - ** object. Only used if type==NONTERMINAL */ - int dtnum; /* The data type number. In the parser, the value - ** stack is a union. The .yy%d element of this - ** union is the correct data type for this object */ - /* The following fields are used by MULTITERMINALs only */ - int nsubsym; /* Number of constituent symbols in the MULTI */ - struct symbol **subsym; /* Array of constituent symbols */ -}; - -/* Each production rule in the grammar is stored in the following -** structure. */ -struct rule { - struct symbol *lhs; /* Left-hand side of the rule */ - char *lhsalias; /* Alias for the LHS (NULL if none) */ - int lhsStart; /* True if left-hand side is the start symbol */ - int ruleline; /* Line number for the rule */ - int nrhs; /* Number of RHS symbols */ - struct symbol **rhs; /* The RHS symbols */ - char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ - int line; /* Line number at which code begins */ - char *code; /* The code executed when this rule is reduced */ - struct symbol *precsym; /* Precedence symbol for this rule */ - int index; /* An index number for this rule */ - Boolean canReduce; /* True if this rule is ever reduced */ - struct rule *nextlhs; /* Next rule with the same LHS */ - struct rule *next; /* Next rule in the global list */ -}; - -/* A configuration is a production rule of the grammar together with -** a mark (dot) showing how much of that rule has been processed so far. -** Configurations also contain a follow-set which is a list of terminal -** symbols which are allowed to immediately follow the end of the rule. -** Every configuration is recorded as an instance of the following: */ -struct config { - struct rule *rp; /* The rule upon which the configuration is based */ - int dot; /* The parse point */ - char *fws; /* Follow-set for this configuration only */ - struct plink *fplp; /* Follow-set forward propagation links */ - struct plink *bplp; /* Follow-set backwards propagation links */ - struct state *stp; /* Pointer to state which contains this */ - enum { - COMPLETE, /* The status is used during followset and */ - INCOMPLETE /* shift computations */ - } status; - struct config *next; /* Next configuration in the state */ - struct config *bp; /* The next basis configuration */ -}; - -/* Every shift or reduce operation is stored as one of the following */ -struct action { - struct symbol *sp; /* The look-ahead symbol */ - enum e_action { - SHIFT, - ACCEPT, - REDUCE, - ERROR, - SSCONFLICT, /* A shift/shift conflict */ - SRCONFLICT, /* Was a reduce, but part of a conflict */ - RRCONFLICT, /* Was a reduce, but part of a conflict */ - SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ - RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ - NOT_USED /* Deleted by compression */ - } type; - union { - struct state *stp; /* The new state, if a shift */ - struct rule *rp; /* The rule, if a reduce */ - } x; - struct action *next; /* Next action for this state */ - struct action *collide; /* Next action with the same hash */ -}; - -/* Each state of the generated parser's finite state machine -** is encoded as an instance of the following structure. */ -struct state { - struct config *bp; /* The basis configurations for this state */ - struct config *cfp; /* All configurations in this set */ - int statenum; /* Sequential number for this state */ - struct action *ap; /* Array of actions for this state */ - int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ - int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ - int iDflt; /* Default action */ -}; -#define NO_OFFSET (-2147483647) - -/* A followset propagation link indicates that the contents of one -** configuration followset should be propagated to another whenever -** the first changes. */ -struct plink { - struct config *cfp; /* The configuration to which linked */ - struct plink *next; /* The next propagate link */ -}; - -/* The state vector for the entire parser generator is recorded as -** follows. (LEMON uses no global variables and makes little use of -** static variables. Fields in the following structure can be thought -** of as begin global variables in the program.) */ -struct lemon { - struct state **sorted; /* Table of states sorted by state number */ - struct rule *rule; /* List of all rules */ - int nstate; /* Number of states */ - int nrule; /* Number of rules */ - int nsymbol; /* Number of terminal and nonterminal symbols */ - int nterminal; /* Number of terminal symbols */ - struct symbol **symbols; /* Sorted array of pointers to symbols */ - int errorcnt; /* Number of errors */ - struct symbol *errsym; /* The error symbol */ - struct symbol *wildcard; /* Token that matches anything */ - char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ - char *tokentype; /* Type of terminal symbols in the parser stack */ - char *vartype; /* The default type of non-terminal symbols */ - char *start; /* Name of the start symbol for the grammar */ - char *stacksize; /* Size of the parser stack */ - char *include; /* Code to put at the start of the C file */ - char *error; /* Code to execute when an error is seen */ - char *overflow; /* Code to execute on a stack overflow */ - char *failure; /* Code to execute on parser failure */ - char *accept; /* Code to execute when the parser excepts */ - char *extracode; /* Code appended to the generated file */ - char *tokendest; /* Code to execute to destroy token data */ - char *vardest; /* Code for the default non-terminal destructor */ - char *filename; /* Name of the input file */ - char *outname; /* Name of the current output file */ - char *tokenprefix; /* A prefix added to token names in the .h file */ - int nconflict; /* Number of parsing conflicts */ - int tablesize; /* Size of the parse tables */ - int basisflag; /* Print only basis configurations */ - int has_fallback; /* True if any %fallback is seen in the grammar */ - int nolinenosflag; /* True if #line statements should not be printed */ - char *argv0; /* Name of the program */ -}; - -#define MemoryCheck(X) if((X)==0){ \ - extern void memory_error(); \ - memory_error(); \ -} - -/**************** From the file "table.h" *********************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -/* Routines for handling a strings */ - -char *Strsafe(); - -void Strsafe_init(/* void */); -int Strsafe_insert(/* char * */); -char *Strsafe_find(/* char * */); - -/* Routines for handling symbols of the grammar */ - -struct symbol *Symbol_new(); -int Symbolcmpp(/* struct symbol **, struct symbol ** */); -void Symbol_init(/* void */); -int Symbol_insert(/* struct symbol *, char * */); -struct symbol *Symbol_find(/* char * */); -struct symbol *Symbol_Nth(/* int */); -int Symbol_count(/* */); -struct symbol **Symbol_arrayof(/* */); - -/* Routines to manage the state table */ - -int Configcmp(/* struct config *, struct config * */); -struct state *State_new(); -void State_init(/* void */); -int State_insert(/* struct state *, struct config * */); -struct state *State_find(/* struct config * */); -struct state **State_arrayof(/* */); - -/* Routines used for efficiency in Configlist_add */ - -void Configtable_init(/* void */); -int Configtable_insert(/* struct config * */); -struct config *Configtable_find(/* struct config * */); -void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -static struct action *Action_new(void){ - static struct action *freelist = 0; - struct action *new; - - if( freelist==0 ){ - int i; - int amt = 100; - freelist = (struct action *)calloc(amt, sizeof(struct action)); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; - freelist[amt-1].next = 0; - } - new = freelist; - freelist = freelist->next; - return new; -} - -/* Compare two actions for sorting purposes. Return negative, zero, or -** positive if the first action is less than, equal to, or greater than -** the first -*/ -static int actioncmp( - struct action *ap1, - struct action *ap2 -){ - int rc; - rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ){ - rc = (int)ap1->type - (int)ap2->type; - } - if( rc==0 && ap1->type==REDUCE ){ - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -static struct action *Action_sort( - struct action *ap -){ - ap = (struct action *)msort((char *)ap,(char **)&ap->next, - (int(*)(const char*,const char*))actioncmp); - return ap; -} - -void Action_add(app,type,sp,arg) -struct action **app; -enum e_action type; -struct symbol *sp; -char *arg; -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if( type==SHIFT ){ - new->x.stp = (struct state *)arg; - }else{ - new->x.rp = (struct rule *)arg; - } -} -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ - acttab *p = calloc( 1, sizeof(*p) ); - if( p==0 ){ - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action){ - if( p->nLookahead>=p->nLookaheadAlloc ){ - p->nLookaheadAlloc += 25; - p->aLookahead = realloc( p->aLookahead, - sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if( p->aLookahead==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if( p->nLookahead==0 ){ - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - }else{ - if( p->mxLookahead<lookahead ) p->mxLookahead = lookahead; - if( p->mnLookahead>lookahead ){ - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p){ - int i, j, k, n; - assert( p->nLookahead>0 ); - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if( p->nAction + n >= p->nActionAlloc ){ - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc( p->aAction, - sizeof(p->aAction[0])*p->nActionAlloc); - if( p->aAction==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; i<p->nActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; i<p->nAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( j<p->nLookahead ) continue; - for(j=0; j<p->nAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ - if( p->aAction[i].action!=p->mnAction ) continue; - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 || k>=p->nAction ) break; - if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; - if( p->aLookahead[j].action!=p->aAction[k].action ) break; - } - if( j<p->nLookahead ) continue; - n = 0; - for(j=0; j<p->nAction; j++){ - if( p->aAction[j].lookahead<0 ) continue; - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; - } - if( n==p->nLookahead ){ - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if( k>=p->nAction ) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - -/********************** From the file "build.c" *****************************/ -/* -** Routines to construction the finite state machine for the LEMON -** parser generator. -*/ - -/* Find a precedence symbol of every rule in the grammar. -** -** Those rules which have a precedence symbol coded in the input -** grammar using the "[symbol]" construct will already have the -** rp->precsym field filled. Other rules take as their precedence -** symbol the first RHS symbol with a defined precedence. If there -** are not RHS symbols with a defined precedence, the precedence -** symbol field is left blank. -*/ -void FindRulePrecedences(xp) -struct lemon *xp; -{ - struct rule *rp; - for(rp=xp->rule; rp; rp=rp->next){ - if( rp->precsym==0 ){ - int i, j; - for(i=0; i<rp->nrhs && rp->precsym==0; i++){ - struct symbol *sp = rp->rhs[i]; - if( sp->type==MULTITERMINAL ){ - for(j=0; j<sp->nsubsym; j++){ - if( sp->subsym[j]->prec>=0 ){ - rp->precsym = sp->subsym[j]; - break; - } - } - }else if( sp->prec>=0 ){ - rp->precsym = rp->rhs[i]; - } - } - } - } - return; -} - -/* Find all nonterminals which will generate the empty string. -** Then go back and compute the first sets of every nonterminal. -** The first set is the set of all terminal symbols which can begin -** a string generated by that nonterminal. -*/ -void FindFirstSets(lemp) -struct lemon *lemp; -{ - int i, j; - struct rule *rp; - int progress; - - for(i=0; i<lemp->nsymbol; i++){ - lemp->symbols[i]->lambda = LEMON_FALSE; - } - for(i=lemp->nterminal; i<lemp->nsymbol; i++){ - lemp->symbols[i]->firstset = SetNew(); - } - - /* First compute all lambdas */ - do{ - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->lhs->lambda ) continue; - for(i=0; i<rp->nrhs; i++){ - struct symbol *sp = rp->rhs[i]; - if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; - } - if( i==rp->nrhs ){ - rp->lhs->lambda = LEMON_TRUE; - progress = 1; - } - } - }while( progress ); - - /* Now compute all first sets */ - do{ - struct symbol *s1, *s2; - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - s1 = rp->lhs; - for(i=0; i<rp->nrhs; i++){ - s2 = rp->rhs[i]; - if( s2->type==TERMINAL ){ - progress += SetAdd(s1->firstset,s2->index); - break; - }else if( s2->type==MULTITERMINAL ){ - for(j=0; j<s2->nsubsym; j++){ - progress += SetAdd(s1->firstset,s2->subsym[j]->index); - } - break; - }else if( s1==s2 ){ - if( s1->lambda==LEMON_FALSE ) break; - }else{ - progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==LEMON_FALSE ) break; - } - } - } - }while( progress ); - return; -} - -/* Compute all LR(0) states for the grammar. Links -** are added to between some states so that the LR(1) follow sets -** can be computed later. -*/ -PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */ -void FindStates(lemp) -struct lemon *lemp; -{ - struct symbol *sp; - struct rule *rp; - - Configlist_init(); - - /* Find the start symbol */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ){ - ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); - lemp->errorcnt++; - sp = lemp->rule->lhs; - } - }else{ - sp = lemp->rule->lhs; - } - - /* Make sure the start symbol doesn't occur on the right-hand side of - ** any rule. Report an error if it does. (YACC would generate a new - ** start symbol in this case.) */ - for(rp=lemp->rule; rp; rp=rp->next){ - int i; - for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ - ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); - lemp->errorcnt++; - } - } - } - - /* The basis configuration set for the first state - ** is all rules which have the start symbol as their - ** left-hand side */ - for(rp=sp->rule; rp; rp=rp->nextlhs){ - struct config *newcfp; - rp->lhsStart = 1; - newcfp = Configlist_addbasis(rp,0); - SetAdd(newcfp->fws,0); - } - - /* Compute the first state. All other states will be - ** computed automatically during the computation of the first one. - ** The returned pointer to the first state is not used. */ - (void)getstate(lemp); - return; -} - -/* Return a pointer to a state which is described by the configuration -** list which has been built from calls to Configlist_add. -*/ -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */ -PRIVATE struct state *getstate(lemp) -struct lemon *lemp; -{ - struct config *cfp, *bp; - struct state *stp; - - /* Extract the sorted basis of the new state. The basis was constructed - ** by prior calls to "Configlist_addbasis()". */ - Configlist_sortbasis(); - bp = Configlist_basis(); - - /* Get a state with the same basis */ - stp = State_find(bp); - if( stp ){ - /* A state with the same basis already exists! Copy all the follow-set - ** propagation links from the state under construction into the - ** preexisting state, then return a pointer to the preexisting state */ - struct config *x, *y; - for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ - Plink_copy(&y->bplp,x->bplp); - Plink_delete(x->fplp); - x->fplp = x->bplp = 0; - } - cfp = Configlist_return(); - Configlist_eat(cfp); - }else{ - /* This really is a new state. Construct all the details */ - Configlist_closure(lemp); /* Compute the configuration closure */ - Configlist_sort(); /* Sort the configuration closure */ - cfp = Configlist_return(); /* Get a pointer to the config list */ - stp = State_new(); /* A new state structure */ - MemoryCheck(stp); - stp->bp = bp; /* Remember the configuration basis */ - stp->cfp = cfp; /* Remember the configuration closure */ - stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ - State_insert(stp,stp->bp); /* Add to the state table */ - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; -} - -/* -** Return true if two symbols are the same. -*/ -int same_symbol(a,b) -struct symbol *a; -struct symbol *b; -{ - int i; - if( a==b ) return 1; - if( a->type!=MULTITERMINAL ) return 0; - if( b->type!=MULTITERMINAL ) return 0; - if( a->nsubsym!=b->nsubsym ) return 0; - for(i=0; i<a->nsubsym; i++){ - if( a->subsym[i]!=b->subsym[i] ) return 0; - } - return 1; -} - -/* Construct all successor states to the given state. A "successor" -** state is any state which can be reached by a shift action. -*/ -PRIVATE void buildshifts(lemp,stp) -struct lemon *lemp; -struct state *stp; /* The state from which successors are computed */ -{ - struct config *cfp; /* For looping thru the config closure of "stp" */ - struct config *bcfp; /* For the inner loop on config closure of "stp" */ - struct config *new; /* */ - struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ - struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ - struct state *newstp; /* A pointer to a successor state */ - - /* Each configuration becomes complete after it contibutes to a successor - ** state. Initially, all configurations are incomplete */ - for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; - - /* Loop through all configurations of the state "stp" */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ - if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ - Configlist_reset(); /* Reset the new config set */ - sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ - - /* For every configuration in the state "stp" which has the symbol "sp" - ** following its dot, add the same configuration to the basis set under - ** construction but with the dot shifted one symbol to the right. */ - for(bcfp=cfp; bcfp; bcfp=bcfp->next){ - if( bcfp->status==COMPLETE ) continue; /* Already used */ - if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ - bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */ - bcfp->status = COMPLETE; /* Mark this config as used */ - new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); - Plink_add(&new->bplp,bcfp); - } - - /* Get a pointer to the state described by the basis configuration set - ** constructed in the preceding loop */ - newstp = getstate(lemp); - - /* The state "newstp" is reached from the state "stp" by a shift action - ** on the symbol "sp" */ - if( sp->type==MULTITERMINAL ){ - int i; - for(i=0; i<sp->nsubsym; i++){ - Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp); - } - }else{ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); - } - } -} - -/* -** Construct the propagation links -*/ -void FindLinks(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp, *other; - struct state *stp; - struct plink *plp; - - /* Housekeeping detail: - ** Add to every propagate link a pointer back to the state to - ** which the link is attached. */ - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } - } - - /* Convert all backlinks into forward links. Only the forward - ** links are used in the follow-set computation. */ - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } - } - } -} - -/* Compute all followsets. -** -** A followset is the set of all symbols which can come immediately -** after a configuration. -*/ -void FindFollowSets(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp; - struct plink *plp; - int progress; - int change; - - for(i=0; i<lemp->nstate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } - } - - do{ - progress = 0; - for(i=0; i<lemp->nstate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } - } - cfp->status = COMPLETE; - } - } - }while( progress ); -} - -static int resolve_conflict(); - -/* Compute the reduce actions, and resolve conflicts. -*/ -void FindActions(lemp) -struct lemon *lemp; -{ - int i,j; - struct config *cfp; - struct state *stp; - struct symbol *sp; - struct rule *rp; - - /* Add all of the reduce actions - ** A reduce action is added for each element of the followset of - ** a configuration which has its dot at the extreme right. - */ - for(i=0; i<lemp->nstate; i++){ /* Loop over all states */ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; j<lemp->nterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } - } - } - } - } - - /* Add the accepting token */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; - }else{ - sp = lemp->rule->lhs; - } - /* Add to the first state (which is always the starting state of the - ** finite state machine) an action to ACCEPT if the lookahead is the - ** start nonterminal. */ - Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); - - /* Resolve conflicts */ - for(i=0; i<lemp->nstate; i++){ - struct action *ap, *nap; - struct state *stp; - stp = lemp->sorted[i]; - /* assert( stp->ap ); */ - stp->ap = Action_sort(stp->ap); - for(ap=stp->ap; ap && ap->next; ap=ap->next){ - for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ - /* The two actions "ap" and "nap" have the same lookahead. - ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); - } - } - } - - /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE; - for(i=0; i<lemp->nstate; i++){ - struct action *ap; - for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE; - } - } - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->canReduce ) continue; - ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); - lemp->errorcnt++; - } -} - -/* Resolve a conflict between the two given actions. If the -** conflict can't be resolved, return non-zero. -** -** NO LONGER TRUE: -** To resolve a conflict, first look to see if either action -** is on an error rule. In that case, take the action which -** is not associated with the error rule. If neither or both -** actions are associated with an error rule, then try to -** use precedence to resolve the conflict. -** -** If either action is a SHIFT, then it must be apx. This -** function won't work if apx->type==REDUCE and apy->type==SHIFT. -*/ -static int resolve_conflict(apx,apy,errsym) -struct action *apx; -struct action *apy; -struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ -{ - struct symbol *spx, *spy; - int errcnt = 0; - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==SHIFT ){ - apy->type = SSCONFLICT; - errcnt++; - } - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; - spy = apy->x.rp->precsym; - if( spy==0 || spx->prec<0 || spy->prec<0 ){ - /* Not enough precedence information. */ - apy->type = SRCONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ - apy->type = RD_RESOLVED; - }else if( spx->prec<spy->prec ){ - apx->type = SH_RESOLVED; - }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ - apy->type = RD_RESOLVED; /* associativity */ - }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ - apx->type = SH_RESOLVED; - }else{ - assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = SRCONFLICT; - errcnt++; - } - }else if( apx->type==REDUCE && apy->type==REDUCE ){ - spx = apx->x.rp->precsym; - spy = apy->x.rp->precsym; - if( spx==0 || spy==0 || spx->prec<0 || - spy->prec<0 || spx->prec==spy->prec ){ - apy->type = RRCONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ - apy->type = RD_RESOLVED; - }else if( spx->prec<spy->prec ){ - apx->type = RD_RESOLVED; - } - }else{ - assert( - apx->type==SH_RESOLVED || - apx->type==RD_RESOLVED || - apx->type==SSCONFLICT || - apx->type==SRCONFLICT || - apx->type==RRCONFLICT || - apy->type==SH_RESOLVED || - apy->type==RD_RESOLVED || - apy->type==SSCONFLICT || - apy->type==SRCONFLICT || - apy->type==RRCONFLICT - ); - /* The REDUCE/SHIFT case cannot happen because SHIFTs come before - ** REDUCEs on the list. If we reach this point it must be because - ** the parser conflict had already been resolved. */ - } - return errcnt; -} -/********************* From the file "configlist.c" *************************/ -/* -** Routines to processing a configuration list and building a state -** in the LEMON parser generator. -*/ - -static struct config *freelist = 0; /* List of free configurations */ -static struct config *current = 0; /* Top of list of configurations */ -static struct config **currentend = 0; /* Last on list of configs */ -static struct config *basis = 0; /* Top of list of basis configs */ -static struct config **basisend = 0; /* End of list of basis configs */ - -/* Return a pointer to a new configuration */ -PRIVATE struct config *newconfig(){ - struct config *new; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)calloc( amt, sizeof(struct config) ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; - freelist[amt-1].next = 0; - } - new = freelist; - freelist = freelist->next; - return new; -} - -/* The configuration "old" is no longer used */ -PRIVATE void deleteconfig(old) -struct config *old; -{ - old->next = freelist; - freelist = old; -} - -/* Initialized the configuration list builder */ -void Configlist_init(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_init(); - return; -} - -/* Initialized the configuration list builder */ -void Configlist_reset(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_clear(0); - return; -} - -/* Add another configuration to the configuration list */ -struct config *Configlist_add(rp,dot) -struct rule *rp; /* The rule */ -int dot; /* Index into the RHS of the rule where the dot goes */ -{ - struct config *cfp, model; - - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - Configtable_insert(cfp); - } - return cfp; -} - -/* Add a basis configuration to the configuration list */ -struct config *Configlist_addbasis(rp,dot) -struct rule *rp; -int dot; -{ - struct config *cfp, model; - - assert( basisend!=0 ); - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - *basisend = cfp; - basisend = &cfp->bp; - Configtable_insert(cfp); - } - return cfp; -} - -/* Compute the closure of the configuration list */ -void Configlist_closure(lemp) -struct lemon *lemp; -{ - struct config *cfp, *newcfp; - struct rule *rp, *newrp; - struct symbol *sp, *xsp; - int i, dot; - - assert( currentend!=0 ); - for(cfp=current; cfp; cfp=cfp->next){ - rp = cfp->rp; - dot = cfp->dot; - if( dot>=rp->nrhs ) continue; - sp = rp->rhs[dot]; - if( sp->type==NONTERMINAL ){ - if( sp->rule==0 && sp!=lemp->errsym ){ - ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", - sp->name); - lemp->errorcnt++; - } - for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ - newcfp = Configlist_add(newrp,0); - for(i=dot+1; i<rp->nrhs; i++){ - xsp = rp->rhs[i]; - if( xsp->type==TERMINAL ){ - SetAdd(newcfp->fws,xsp->index); - break; - }else if( xsp->type==MULTITERMINAL ){ - int k; - for(k=0; k<xsp->nsubsym; k++){ - SetAdd(newcfp->fws, xsp->subsym[k]->index); - } - break; - }else{ - SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==LEMON_FALSE ) break; - } - } - if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); - } - } - } - return; -} - -/* Sort the configuration list */ -void Configlist_sort(){ - current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); - currentend = 0; - return; -} - -/* Sort the basis configuration list */ -void Configlist_sortbasis(){ - basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); - basisend = 0; - return; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_return(){ - struct config *old; - old = current; - current = 0; - currentend = 0; - return old; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_basis(){ - struct config *old; - old = basis; - basis = 0; - basisend = 0; - return old; -} - -/* Free all elements of the given configuration list */ -void Configlist_eat(cfp) -struct config *cfp; -{ - struct config *nextcfp; - for(; cfp; cfp=nextcfp){ - nextcfp = cfp->next; - assert( cfp->fplp==0 ); - assert( cfp->bplp==0 ); - if( cfp->fws ) SetFree(cfp->fws); - deleteconfig(cfp); - } - return; -} -/***************** From the file "error.c" *********************************/ -/* -** Code for printing error message. -*/ - -/* Find a good place to break "msg" so that its length is at least "min" -** but no more than "max". Make the point as close to max as possible. -*/ -static int findbreak(msg,min,max) -char *msg; -int min; -int max; -{ - int i,spot; - char c; - for(i=spot=min; i<=max; i++){ - c = msg[i]; - if( c=='\t' ) msg[i] = ' '; - if( c=='\n' ){ msg[i] = ' '; spot = i; break; } - if( c==0 ){ spot = i; break; } - if( c=='-' && i<max-1 ) spot = i+1; - if( c==' ' ) spot = i; - } - return spot; -} - -/* -** The error message is split across multiple lines if necessary. The -** splits occur at a space, if there is a space available near the end -** of the line. -*/ -#define ERRMSGSIZE 10000 /* Hope this is big enough. No way to error check */ -#define LINEWIDTH 79 /* Max width of any output line */ -#define PREFIXLIMIT 30 /* Max width of the prefix on each line */ -void ErrorMsg(const char *filename, int lineno, const char *format, ...){ - char errmsg[ERRMSGSIZE]; - char prefix[PREFIXLIMIT+10]; - int errmsgsize; - int prefixsize; - int availablewidth; - va_list ap; - int end, restart, base; - - va_start(ap, format); - /* Prepare a prefix to be prepended to every output line */ - if( lineno>0 ){ - sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno); - }else{ - sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename); - } - prefixsize = lemonStrlen(prefix); - availablewidth = LINEWIDTH - prefixsize; - - /* Generate the error message */ - vsprintf(errmsg,format,ap); - va_end(ap); - errmsgsize = lemonStrlen(errmsg); - /* Remove trailing '\n's from the error message. */ - while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){ - errmsg[--errmsgsize] = 0; - } - - /* Print the error message */ - base = 0; - while( errmsg[base]!=0 ){ - end = restart = findbreak(&errmsg[base],0,availablewidth); - restart += base; - while( errmsg[restart]==' ' ) restart++; - fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]); - base = restart; - } -} -/**************** From the file "main.c" ************************************/ -/* -** Main program file for the LEMON parser generator. -*/ - -/* Report an out-of-memory condition and abort. This function -** is used mostly by the "MemoryCheck" macro in struct.h -*/ -void memory_error(){ - fprintf(stderr,"Out of memory. Aborting...\n"); - exit(1); -} - -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ - -/* This routine is called with the argument to each -D command-line option. -** Add the macro defined to the azDefine array. -*/ -static void handle_D_option(char *z){ - char **paz; - nDefine++; - azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine); - if( azDefine==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - paz = &azDefine[nDefine-1]; - *paz = malloc( lemonStrlen(z)+1 ); - if( *paz==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - strcpy(*paz, z); - for(z=*paz; *z && *z!='='; z++){} - *z = 0; -} - - -/* The main program. Parse the command line and do it... */ -int main(argc,argv) -int argc; -char **argv; -{ - static int version = 0; - static int rpflag = 0; - static int basisflag = 0; - static int compress = 0; - static int quiet = 0; - static int statistics = 0; - static int mhflag = 0; - static int nolinenosflag = 0; - static struct s_options options[] = { - {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, - {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, - {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, - {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, - {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."}, - {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."}, - {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, - {OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output."}, - {OPT_FLAG, "x", (char*)&version, "Print the version number."}, - {OPT_FLAG,0,0,0} - }; - int i; - struct lemon lem; - - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); - exit(0); - } - if( OptNArgs()!=1 ){ - fprintf(stderr,"Exactly one filename argument is required.\n"); - exit(1); - } - memset(&lem, 0, sizeof(lem)); - lem.errorcnt = 0; - - /* Initialize the machine */ - Strsafe_init(); - Symbol_init(); - State_init(); - lem.argv0 = argv[0]; - lem.filename = OptArg(0); - lem.basisflag = basisflag; - lem.nolinenosflag = nolinenosflag; - Symbol_new("$"); - lem.errsym = Symbol_new("error"); - lem.errsym->useCnt = 0; - - /* Parse the input file */ - Parse(&lem); - if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.nrule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); - } - - /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); - Symbol_new("{default}"); - lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), - (int(*)())Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); - lem.nterminal = i; - - /* Generate a reprint of the grammar, if requested on the command line */ - if( rpflag ){ - Reprint(&lem); - }else{ - /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal+1); - - /* Find the precedence for every production rule (that has one) */ - FindRulePrecedences(&lem); - - /* Compute the lambda-nonterminals and the first-sets for every - ** nonterminal */ - FindFirstSets(&lem); - - /* Compute all LR(0) states. Also record follow-set propagation - ** links so that the follow-set can be computed later */ - lem.nstate = 0; - FindStates(&lem); - lem.sorted = State_arrayof(); - - /* Tie up loose ends on the propagation links */ - FindLinks(&lem); - - /* Compute the follow set of every reducible configuration */ - FindFollowSets(&lem); - - /* Compute the action tables */ - FindActions(&lem); - - /* Compress the action tables */ - if( compress==0 ) CompressTables(&lem); - - /* Reorder and renumber the states so that states with fewer choices - ** occur at the end. */ - ResortStates(&lem); - - /* Generate a report of the parser generated. (the "y.output" file) */ - if( !quiet ) ReportOutput(&lem); - - /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); - - /* Produce a header file for use by the scanner. (This step is - ** omitted if the "-m" option is used because makeheaders will - ** generate the file for us.) */ - if( !mhflag ) ReportHeader(&lem); - } - if( statistics ){ - printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", - lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); - printf(" %d states, %d parser table entries, %d conflicts\n", - lem.nstate, lem.tablesize, lem.nconflict); - } - if( lem.nconflict ){ - fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); - } - exit(lem.errorcnt + lem.nconflict); - return (lem.errorcnt + lem.nconflict); -} -/******************** From the file "msort.c" *******************************/ -/* -** A generic merge-sort program. -** -** USAGE: -** Let "ptr" be a pointer to some structure which is at the head of -** a null-terminated list. Then to sort the list call: -** -** ptr = msort(ptr,&(ptr->next),cmpfnc); -** -** In the above, "cmpfnc" is a pointer to a function which compares -** two instances of the structure and returns an integer, as in -** strcmp. The second argument is a pointer to the pointer to the -** second element of the linked list. This address is used to compute -** the offset to the "next" field within the structure. The offset to -** the "next" field must be constant for all structures in the list. -** -** The function returns a new pointer which is the head of the list -** after sorting. -** -** ALGORITHM: -** Merge-sort. -*/ - -/* -** Return a pointer to the next structure in the linked list. -*/ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) - -/* -** Inputs: -** a: A sorted, null-terminated linked list. (May be null). -** b: A sorted, null-terminated linked list. (May be null). -** cmp: A pointer to the comparison function. -** offset: Offset in the structure to the "next" field. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** of both a and b. -** -** Side effects: -** The "next" pointers for elements in the lists a and b are -** changed. -*/ -static char *merge( - char *a, - char *b, - int (*cmp)(const char*,const char*), - int offset -){ - char *ptr, *head; - - if( a==0 ){ - head = b; - }else if( b==0 ){ - head = a; - }else{ - if( (*cmp)(a,b)<0 ){ - ptr = a; - a = NEXT(a); - }else{ - ptr = b; - b = NEXT(b); - } - head = ptr; - while( a && b ){ - if( (*cmp)(a,b)<0 ){ - NEXT(ptr) = a; - ptr = a; - a = NEXT(a); - }else{ - NEXT(ptr) = b; - ptr = b; - b = NEXT(b); - } - } - if( a ) NEXT(ptr) = a; - else NEXT(ptr) = b; - } - return head; -} - -/* -** Inputs: -** list: Pointer to a singly-linked list of structures. -** next: Pointer to pointer to the second element of the list. -** cmp: A comparison function. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** orginally in list. -** -** Side effects: -** The "next" pointers for elements in list are changed. -*/ -#define LISTSIZE 30 -static char *msort( - char *list, - char **next, - int (*cmp)(const char*,const char*) -){ - unsigned long offset; - char *ep; - char *set[LISTSIZE]; - int i; - offset = (unsigned long)next - (unsigned long)list; - for(i=0; i<LISTSIZE; i++) set[i] = 0; - while( list ){ - ep = list; - list = NEXT(list); - NEXT(ep) = 0; - for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){ - ep = merge(ep,set[i],cmp,offset); - set[i] = 0; - } - set[i] = ep; - } - ep = 0; - for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset); - return ep; -} -/************************ From the file "option.c" **************************/ -static char **argv; -static struct s_options *op; -static FILE *errstream; - -#define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0) - -/* -** Print the command line with a carrot pointing to the k-th character -** of the n-th field. -*/ -static void errline(n,k,err) -int n; -int k; -FILE *err; -{ - int spcnt, i; - if( argv[0] ) fprintf(err,"%s",argv[0]); - spcnt = lemonStrlen(argv[0]) + 1; - for(i=1; i<n && argv[i]; i++){ - fprintf(err," %s",argv[i]); - spcnt += lemonStrlen(argv[i])+1; - } - spcnt += k; - for(; argv[i]; i++) fprintf(err," %s",argv[i]); - if( spcnt<20 ){ - fprintf(err,"\n%*s^-- here\n",spcnt,""); - }else{ - fprintf(err,"\n%*shere --^\n",spcnt-7,""); - } -} - -/* -** Return the index of the N-th non-switch argument. Return -1 -** if N is out of range. -*/ -static int argindex(n) -int n; -{ - int i; - int dashdash = 0; - if( argv!=0 && *argv!=0 ){ - for(i=1; argv[i]; i++){ - if( dashdash || !ISOPT(argv[i]) ){ - if( n==0 ) return i; - n--; - } - if( strcmp(argv[i],"--")==0 ) dashdash = 1; - } - } - return -1; -} - -static char emsg[] = "Command line syntax error: "; - -/* -** Process a flag command line argument. -*/ -static int handleflags(i,err) -int i; -FILE *err; -{ - int v; - int errcnt = 0; - int j; - for(j=0; op[j].label; j++){ - if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break; - } - v = argv[i][0]=='-' ? 1 : 0; - if( op[j].label==0 ){ - if( err ){ - fprintf(err,"%sundefined option.\n",emsg); - errline(i,1,err); - } - errcnt++; - }else if( op[j].type==OPT_FLAG ){ - *((int*)op[j].arg) = v; - }else if( op[j].type==OPT_FFLAG ){ - (*(void(*)())(op[j].arg))(v); - }else if( op[j].type==OPT_FSTR ){ - (*(void(*)())(op[j].arg))(&argv[i][2]); - }else{ - if( err ){ - fprintf(err,"%smissing argument on switch.\n",emsg); - errline(i,1,err); - } - errcnt++; - } - return errcnt; -} - -/* -** Process a command line switch which has an argument. -*/ -static int handleswitch(i,err) -int i; -FILE *err; -{ - int lv = 0; - double dv = 0.0; - char *sv = 0, *end; - char *cp; - int j; - int errcnt = 0; - cp = strchr(argv[i],'='); - assert( cp!=0 ); - *cp = 0; - for(j=0; op[j].label; j++){ - if( strcmp(argv[i],op[j].label)==0 ) break; - } - *cp = '='; - if( op[j].label==0 ){ - if( err ){ - fprintf(err,"%sundefined option.\n",emsg); - errline(i,0,err); - } - errcnt++; - }else{ - cp++; - switch( op[j].type ){ - case OPT_FLAG: - case OPT_FFLAG: - if( err ){ - fprintf(err,"%soption requires an argument.\n",emsg); - errline(i,0,err); - } - errcnt++; - break; - case OPT_DBL: - case OPT_FDBL: - dv = strtod(cp,&end); - if( *end ){ - if( err ){ - fprintf(err,"%sillegal character in floating-point argument.\n",emsg); - errline(i,((unsigned long)end)-(unsigned long)argv[i],err); - } - errcnt++; - } - break; - case OPT_INT: - case OPT_FINT: - lv = strtol(cp,&end,0); - if( *end ){ - if( err ){ - fprintf(err,"%sillegal character in integer argument.\n",emsg); - errline(i,((unsigned long)end)-(unsigned long)argv[i],err); - } - errcnt++; - } - break; - case OPT_STR: - case OPT_FSTR: - sv = cp; - break; - } - switch( op[j].type ){ - case OPT_FLAG: - case OPT_FFLAG: - break; - case OPT_DBL: - *(double*)(op[j].arg) = dv; - break; - case OPT_FDBL: - (*(void(*)())(op[j].arg))(dv); - break; - case OPT_INT: - *(int*)(op[j].arg) = lv; - break; - case OPT_FINT: - (*(void(*)())(op[j].arg))((int)lv); - break; - case OPT_STR: - *(char**)(op[j].arg) = sv; - break; - case OPT_FSTR: - (*(void(*)())(op[j].arg))(sv); - break; - } - } - return errcnt; -} - -int OptInit(a,o,err) -char **a; -struct s_options *o; -FILE *err; -{ - int errcnt = 0; - argv = a; - op = o; - errstream = err; - if( argv && *argv && op ){ - int i; - for(i=1; argv[i]; i++){ - if( argv[i][0]=='+' || argv[i][0]=='-' ){ - errcnt += handleflags(i,err); - }else if( strchr(argv[i],'=') ){ - errcnt += handleswitch(i,err); - } - } - } - if( errcnt>0 ){ - fprintf(err,"Valid command line options for \"%s\" are:\n",*a); - OptPrint(); - exit(1); - } - return 0; -} - -int OptNArgs(){ - int cnt = 0; - int dashdash = 0; - int i; - if( argv!=0 && argv[0]!=0 ){ - for(i=1; argv[i]; i++){ - if( dashdash || !ISOPT(argv[i]) ) cnt++; - if( strcmp(argv[i],"--")==0 ) dashdash = 1; - } - } - return cnt; -} - -char *OptArg(n) -int n; -{ - int i; - i = argindex(n); - return i>=0 ? argv[i] : 0; -} - -void OptErr(n) -int n; -{ - int i; - i = argindex(n); - if( i>=0 ) errline(i,0,errstream); -} - -void OptPrint(){ - int i; - int max, len; - max = 0; - for(i=0; op[i].label; i++){ - len = lemonStrlen(op[i].label) + 1; - switch( op[i].type ){ - case OPT_FLAG: - case OPT_FFLAG: - break; - case OPT_INT: - case OPT_FINT: - len += 9; /* length of "<integer>" */ - break; - case OPT_DBL: - case OPT_FDBL: - len += 6; /* length of "<real>" */ - break; - case OPT_STR: - case OPT_FSTR: - len += 8; /* length of "<string>" */ - break; - } - if( len>max ) max = len; - } - for(i=0; op[i].label; i++){ - switch( op[i].type ){ - case OPT_FLAG: - case OPT_FFLAG: - fprintf(errstream," -%-*s %s\n",max,op[i].label,op[i].message); - break; - case OPT_INT: - case OPT_FINT: - fprintf(errstream," %s=<integer>%*s %s\n",op[i].label, - (int)(max-lemonStrlen(op[i].label)-9),"",op[i].message); - break; - case OPT_DBL: - case OPT_FDBL: - fprintf(errstream," %s=<real>%*s %s\n",op[i].label, - (int)(max-lemonStrlen(op[i].label)-6),"",op[i].message); - break; - case OPT_STR: - case OPT_FSTR: - fprintf(errstream," %s=<string>%*s %s\n",op[i].label, - (int)(max-lemonStrlen(op[i].label)-8),"",op[i].message); - break; - } - } -} -/*********************** From the file "parse.c" ****************************/ -/* -** Input file parser for the LEMON parser generator. -*/ - -/* The state of the parser */ -struct pstate { - char *filename; /* Name of the input file */ - int tokenlineno; /* Linenumber at which current token starts */ - int errorcnt; /* Number of errors so far */ - char *tokenstart; /* Text of current token */ - struct lemon *gp; /* Global state vector */ - enum e_state { - INITIALIZE, - WAITING_FOR_DECL_OR_RULE, - WAITING_FOR_DECL_KEYWORD, - WAITING_FOR_DECL_ARG, - WAITING_FOR_PRECEDENCE_SYMBOL, - WAITING_FOR_ARROW, - IN_RHS, - LHS_ALIAS_1, - LHS_ALIAS_2, - LHS_ALIAS_3, - RHS_ALIAS_1, - RHS_ALIAS_2, - PRECEDENCE_MARK_1, - PRECEDENCE_MARK_2, - RESYNC_AFTER_RULE_ERROR, - RESYNC_AFTER_DECL_ERROR, - WAITING_FOR_DESTRUCTOR_SYMBOL, - WAITING_FOR_DATATYPE_SYMBOL, - WAITING_FOR_FALLBACK_ID, - WAITING_FOR_WILDCARD_ID - } state; /* The state of the parser */ - struct symbol *fallback; /* The fallback token */ - struct symbol *lhs; /* Left-hand side of current rule */ - char *lhsalias; /* Alias for the LHS */ - int nrhs; /* Number of right-hand side symbols seen */ - struct symbol *rhs[MAXRHS]; /* RHS symbols */ - char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */ - struct rule *prevrule; /* Previous rule parsed */ - char *declkeyword; /* Keyword of a declaration */ - char **declargslot; /* Where the declaration argument should be put */ - int insertLineMacro; /* Add #line before declaration insert */ - int *decllinenoslot; /* Where to write declaration line number */ - enum e_assoc declassoc; /* Assign this association to decl arguments */ - int preccounter; /* Assign this precedence to decl arguments */ - struct rule *firstrule; /* Pointer to first rule in the grammar */ - struct rule *lastrule; /* Pointer to the most recently parsed rule */ -}; - -/* Parse a single token */ -static void parseonetoken(psp) -struct pstate *psp; -{ - char *x; - x = Strsafe(psp->tokenstart); /* Save the token permanently */ -#if 0 - printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno, - x,psp->state); -#endif - switch( psp->state ){ - case INITIALIZE: - psp->prevrule = 0; - psp->preccounter = 0; - psp->firstrule = psp->lastrule = 0; - psp->gp->nrule = 0; - /* Fall thru to next case */ - case WAITING_FOR_DECL_OR_RULE: - if( x[0]=='%' ){ - psp->state = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ - psp->lhs = Symbol_new(x); - psp->nrhs = 0; - psp->lhsalias = 0; - psp->state = WAITING_FOR_ARROW; - }else if( x[0]=='{' ){ - if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"There is no prior rule opon which to attach the code \ -fragment which begins on this line."); - psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->line = psp->tokenlineno; - psp->prevrule->code = &x[1]; - } - }else if( x[0]=='[' ){ - psp->state = PRECEDENCE_MARK_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Token \"%s\" should be either \"%%\" or a nonterminal name.", - x); - psp->errorcnt++; - } - break; - case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The precedence symbol must be a terminal."); - psp->errorcnt++; - }else if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "There is no prior rule to assign precedence \"[%s]\".",x); - psp->errorcnt++; - }else if( psp->prevrule->precsym!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->precsym = Symbol_new(x); - } - psp->state = PRECEDENCE_MARK_2; - break; - case PRECEDENCE_MARK_2: - if( x[0]!=']' ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"]\" on precedence mark."); - psp->errorcnt++; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - break; - case WAITING_FOR_ARROW: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else if( x[0]=='(' ){ - psp->state = LHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Expected to see a \":\" following the LHS symbol \"%s\".", - psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->lhsalias = x; - psp->state = LHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the LHS \"%s\"\n", - x,psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = LHS_ALIAS_3; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_3: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"->\" following: \"%s(%s)\".", - psp->lhs->name,psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case IN_RHS: - if( x[0]=='.' ){ - struct rule *rp; - rp = (struct rule *)calloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); - if( rp==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't allocate enough memory for this rule."); - psp->errorcnt++; - psp->prevrule = 0; - }else{ - int i; - rp->ruleline = psp->tokenlineno; - rp->rhs = (struct symbol**)&rp[1]; - rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]); - for(i=0; i<psp->nrhs; i++){ - rp->rhs[i] = psp->rhs[i]; - rp->rhsalias[i] = psp->alias[i]; - } - rp->lhs = psp->lhs; - rp->lhsalias = psp->lhsalias; - rp->nrhs = psp->nrhs; - rp->code = 0; - rp->precsym = 0; - rp->index = psp->gp->nrule++; - rp->nextlhs = rp->lhs->rule; - rp->lhs->rule = rp; - rp->next = 0; - if( psp->firstrule==0 ){ - psp->firstrule = psp->lastrule = rp; - }else{ - psp->lastrule->next = rp; - psp->lastrule = rp; - } - psp->prevrule = rp; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ - if( psp->nrhs>=MAXRHS ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbols on RHS of rule beginning at \"%s\".", - x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - }else{ - psp->rhs[psp->nrhs] = Symbol_new(x); - psp->alias[psp->nrhs] = 0; - psp->nrhs++; - } - }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ - struct symbol *msp = psp->rhs[psp->nrhs-1]; - if( msp->type!=MULTITERMINAL ){ - struct symbol *origsp = msp; - msp = calloc(1,sizeof(*msp)); - memset(msp, 0, sizeof(*msp)); - msp->type = MULTITERMINAL; - msp->nsubsym = 1; - msp->subsym = calloc(1,sizeof(struct symbol*)); - msp->subsym[0] = origsp; - msp->name = origsp->name; - psp->rhs[psp->nrhs-1] = msp; - } - msp->nsubsym++; - msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); - msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); - if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Cannot form a compound containing a non-terminal"); - psp->errorcnt++; - } - }else if( x[0]=='(' && psp->nrhs>0 ){ - psp->state = RHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal character on RHS of rule: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->alias[psp->nrhs-1] = x; - psp->state = RHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", - x,psp->rhs[psp->nrhs-1]->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ - psp->declkeyword = x; - psp->declargslot = 0; - psp->decllinenoslot = 0; - psp->insertLineMacro = 1; - psp->state = WAITING_FOR_DECL_ARG; - if( strcmp(x,"name")==0 ){ - psp->declargslot = &(psp->gp->name); - psp->insertLineMacro = 0; - }else if( strcmp(x,"include")==0 ){ - psp->declargslot = &(psp->gp->include); - }else if( strcmp(x,"code")==0 ){ - psp->declargslot = &(psp->gp->extracode); - }else if( strcmp(x,"token_destructor")==0 ){ - psp->declargslot = &psp->gp->tokendest; - }else if( strcmp(x,"default_destructor")==0 ){ - psp->declargslot = &psp->gp->vardest; - }else if( strcmp(x,"token_prefix")==0 ){ - psp->declargslot = &psp->gp->tokenprefix; - psp->insertLineMacro = 0; - }else if( strcmp(x,"syntax_error")==0 ){ - psp->declargslot = &(psp->gp->error); - }else if( strcmp(x,"parse_accept")==0 ){ - psp->declargslot = &(psp->gp->accept); - }else if( strcmp(x,"parse_failure")==0 ){ - psp->declargslot = &(psp->gp->failure); - }else if( strcmp(x,"stack_overflow")==0 ){ - psp->declargslot = &(psp->gp->overflow); - }else if( strcmp(x,"extra_argument")==0 ){ - psp->declargslot = &(psp->gp->arg); - psp->insertLineMacro = 0; - }else if( strcmp(x,"token_type")==0 ){ - psp->declargslot = &(psp->gp->tokentype); - psp->insertLineMacro = 0; - }else if( strcmp(x,"default_type")==0 ){ - psp->declargslot = &(psp->gp->vartype); - psp->insertLineMacro = 0; - }else if( strcmp(x,"stack_size")==0 ){ - psp->declargslot = &(psp->gp->stacksize); - psp->insertLineMacro = 0; - }else if( strcmp(x,"start_symbol")==0 ){ - psp->declargslot = &(psp->gp->start); - psp->insertLineMacro = 0; - }else if( strcmp(x,"left")==0 ){ - psp->preccounter++; - psp->declassoc = LEFT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"right")==0 ){ - psp->preccounter++; - psp->declassoc = RIGHT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"nonassoc")==0 ){ - psp->preccounter++; - psp->declassoc = NONE; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"destructor")==0 ){ - psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; - }else if( strcmp(x,"type")==0 ){ - psp->state = WAITING_FOR_DATATYPE_SYMBOL; - }else if( strcmp(x,"fallback")==0 ){ - psp->fallback = 0; - psp->state = WAITING_FOR_FALLBACK_ID; - }else if( strcmp(x,"wildcard")==0 ){ - psp->state = WAITING_FOR_WILDCARD_ID; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Unknown declaration keyword: \"%%%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal declaration keyword: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->destructor; - psp->decllinenoslot = &sp->destLineno; - psp->insertLineMacro = 1; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->datatype; - psp->insertLineMacro = 0; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_PRECEDENCE_SYMBOL: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ - struct symbol *sp; - sp = Symbol_new(x); - if( sp->prec>=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol \"%s\" has already be given a precedence.",x); - psp->errorcnt++; - }else{ - sp->prec = psp->preccounter; - sp->assoc = psp->declassoc; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't assign a precedence to \"%s\".",x); - psp->errorcnt++; - } - break; - case WAITING_FOR_DECL_ARG: - if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ - char *zOld, *zNew, *zBuf, *z; - int nOld, n, nLine, nNew, nBack; - int addLineMacro; - char zLine[50]; - zNew = x; - if( zNew[0]=='"' || zNew[0]=='{' ) zNew++; - nNew = lemonStrlen(zNew); - if( *psp->declargslot ){ - zOld = *psp->declargslot; - }else{ - zOld = ""; - } - nOld = lemonStrlen(zOld); - n = nOld + nNew + 20; - addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro && - (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0); - if( addLineMacro ){ - for(z=psp->filename, nBack=0; *z; z++){ - if( *z=='\\' ) nBack++; - } - sprintf(zLine, "#line %d ", psp->tokenlineno); - nLine = lemonStrlen(zLine); - n += nLine + lemonStrlen(psp->filename) + nBack; - } - *psp->declargslot = zBuf = realloc(*psp->declargslot, n); - zBuf += nOld; - if( addLineMacro ){ - if( nOld && zBuf[-1]!='\n' ){ - *(zBuf++) = '\n'; - } - memcpy(zBuf, zLine, nLine); - zBuf += nLine; - *(zBuf++) = '"'; - for(z=psp->filename; *z; z++){ - if( *z=='\\' ){ - *(zBuf++) = '\\'; - } - *(zBuf++) = *z; - } - *(zBuf++) = '"'; - *(zBuf++) = '\n'; - } - if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){ - psp->decllinenoslot[0] = psp->tokenlineno; - } - memcpy(zBuf, zNew, nNew); - zBuf += nNew; - *zBuf = 0; - psp->state = WAITING_FOR_DECL_OR_RULE; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal argument to %%%s: %s",psp->declkeyword,x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_FALLBACK_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%fallback argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->fallback==0 ){ - psp->fallback = sp; - }else if( sp->fallback ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "More than one fallback assigned to token %s", x); - psp->errorcnt++; - }else{ - sp->fallback = psp->fallback; - psp->gp->has_fallback = 1; - } - } - break; - case WAITING_FOR_WILDCARD_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%wildcard argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->gp->wildcard==0 ){ - psp->gp->wildcard = sp; - }else{ - ErrorMsg(psp->filename, psp->tokenlineno, - "Extra wildcard to token: %s", x); - psp->errorcnt++; - } - } - break; - case RESYNC_AFTER_RULE_ERROR: -/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; -** break; */ - case RESYNC_AFTER_DECL_ERROR: - if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; - if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; - break; - } -} - -/* Run the preprocessor over the input file text. The global variables -** azDefine[0] through azDefine[nDefine-1] contains the names of all defined -** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and -** comments them out. Text in between is also commented out as appropriate. -*/ -static void preprocess_input(char *z){ - int i, j, k, n; - int exclude = 0; - int start = 0; - int lineno = 1; - int start_lineno = 1; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) lineno++; - if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ - if( exclude ){ - exclude--; - if( exclude==0 ){ - for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' '; - } - } - for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; - }else if( (strncmp(&z[i],"%ifdef",6)==0 && isspace(z[i+6])) - || (strncmp(&z[i],"%ifndef",7)==0 && isspace(z[i+7])) ){ - if( exclude ){ - exclude++; - }else{ - for(j=i+7; isspace(z[j]); j++){} - for(n=0; z[j+n] && !isspace(z[j+n]); n++){} - exclude = 1; - for(k=0; k<nDefine; k++){ - if( strncmp(azDefine[k],&z[j],n)==0 && lemonStrlen(azDefine[k])==n ){ - exclude = 0; - break; - } - } - if( z[i+3]=='n' ) exclude = !exclude; - if( exclude ){ - start = i; - start_lineno = lineno; - } - } - for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; - } - } - if( exclude ){ - fprintf(stderr,"unterminated %%ifdef starting on line %d\n", start_lineno); - exit(1); - } -} - -/* In spite of its name, this function is really a scanner. It read -** in the entire input file (all at once) then tokenizes it. Each -** token is passed to the function "parseonetoken" which builds all -** the appropriate data structures in the global state vector "gp". -*/ -void Parse(gp) -struct lemon *gp; -{ - struct pstate ps; - FILE *fp; - char *filebuf; - int filesize; - int lineno; - int c; - char *cp, *nextcp; - int startline = 0; - - memset(&ps, '\0', sizeof(ps)); - ps.gp = gp; - ps.filename = gp->filename; - ps.errorcnt = 0; - ps.state = INITIALIZE; - - /* Begin by reading the input file */ - fp = fopen(ps.filename,"rb"); - if( fp==0 ){ - ErrorMsg(ps.filename,0,"Can't open this file for reading."); - gp->errorcnt++; - return; - } - fseek(fp,0,2); - filesize = ftell(fp); - rewind(fp); - filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); - gp->errorcnt++; - return; - } - if( fread(filebuf,1,filesize,fp)!=filesize ){ - ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", - filesize); - free(filebuf); - gp->errorcnt++; - return; - } - fclose(fp); - filebuf[filesize] = 0; - - /* Make an initial pass through the file to handle %ifdef and %ifndef */ - preprocess_input(filebuf); - - /* Now scan the text of the input file */ - lineno = 1; - for(cp=filebuf; (c= *cp)!=0; ){ - if( c=='\n' ) lineno++; /* Keep track of the line number */ - if( isspace(c) ){ cp++; continue; } /* Skip all white space */ - if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ - cp+=2; - while( (c= *cp)!=0 && c!='\n' ) cp++; - continue; - } - if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ - cp+=2; - while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c ) cp++; - continue; - } - ps.tokenstart = cp; /* Mark the beginning of the token */ - ps.tokenlineno = lineno; /* Linenumber on which token begins */ - if( c=='\"' ){ /* String literals */ - cp++; - while( (c= *cp)!=0 && c!='\"' ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c==0 ){ - ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( c=='{' ){ /* A block of C code */ - int level; - cp++; - for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ - if( c=='\n' ) lineno++; - else if( c=='{' ) level++; - else if( c=='}' ) level--; - else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ - int prevc; - cp = &cp[2]; - prevc = 0; - while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ - if( c=='\n' ) lineno++; - prevc = c; - cp++; - } - }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ - cp = &cp[2]; - while( (c= *cp)!=0 && c!='\n' ) cp++; - if( c ) lineno++; - }else if( c=='\'' || c=='\"' ){ /* String a character literals */ - int startchar, prevc; - startchar = c; - prevc = 0; - for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ - if( c=='\n' ) lineno++; - if( prevc=='\\' ) prevc = 0; - else prevc = c; - } - } - } - if( c==0 ){ - ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( isalnum(c) ){ /* Identifiers */ - while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ - cp += 3; - nextcp = cp; - }else if( (c=='/' || c=='|') && isalpha(cp[1]) ){ - cp += 2; - while( (c = *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else{ /* All other (one character) operators */ - cp++; - nextcp = cp; - } - c = *cp; - *cp = 0; /* Null terminate the token */ - parseonetoken(&ps); /* Parse the token */ - *cp = c; /* Restore the buffer */ - cp = nextcp; - } - free(filebuf); /* Release the buffer after parsing */ - gp->rule = ps.firstrule; - gp->errorcnt = ps.errorcnt; -} -/*************************** From the file "plink.c" *********************/ -/* -** Routines processing configuration follow-set propagation links -** in the LEMON parser generator. -*/ -static struct plink *plink_freelist = 0; - -/* Allocate a new plink */ -struct plink *Plink_new(){ - struct plink *new; - - if( plink_freelist==0 ){ - int i; - int amt = 100; - plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); - if( plink_freelist==0 ){ - fprintf(stderr, - "Unable to allocate memory for a new follow-set propagation link.\n"); - exit(1); - } - for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1]; - plink_freelist[amt-1].next = 0; - } - new = plink_freelist; - plink_freelist = plink_freelist->next; - return new; -} - -/* Add a plink to a plink list */ -void Plink_add(plpp,cfp) -struct plink **plpp; -struct config *cfp; -{ - struct plink *new; - new = Plink_new(); - new->next = *plpp; - *plpp = new; - new->cfp = cfp; -} - -/* Transfer every plink on the list "from" to the list "to" */ -void Plink_copy(to,from) -struct plink **to; -struct plink *from; -{ - struct plink *nextpl; - while( from ){ - nextpl = from->next; - from->next = *to; - *to = from; - from = nextpl; - } -} - -/* Delete every plink on the list */ -void Plink_delete(plp) -struct plink *plp; -{ - struct plink *nextpl; - - while( plp ){ - nextpl = plp->next; - plp->next = plink_freelist; - plink_freelist = plp; - plp = nextpl; - } -} -/*********************** From the file "report.c" **************************/ -/* -** Procedures for generating reports and tables in the LEMON parser generator. -*/ - -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. -*/ -PRIVATE char *file_makename(lemp,suffix) -struct lemon *lemp; -char *suffix; -{ - char *name; - char *cp; - - name = malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); - if( name==0 ){ - fprintf(stderr,"Can't allocate space for a filename.\n"); - exit(1); - } - strcpy(name,lemp->filename); - cp = strrchr(name,'.'); - if( cp ) *cp = 0; - strcat(name,suffix); - return name; -} - -/* Open a file with a name based on the name of the input file, -** but with a different (specified) suffix, and return a pointer -** to the stream */ -PRIVATE FILE *file_open(lemp,suffix,mode) -struct lemon *lemp; -char *suffix; -char *mode; -{ - FILE *fp; - - if( lemp->outname ) free(lemp->outname); - lemp->outname = file_makename(lemp, suffix); - fp = fopen(lemp->outname,mode); - if( fp==0 && *mode=='w' ){ - fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); - lemp->errorcnt++; - return 0; - } - return fp; -} - -/* Duplicate the input file without comments and without actions -** on rules */ -void Reprint(lemp) -struct lemon *lemp; -{ - struct rule *rp; - struct symbol *sp; - int i, j, maxlen, len, ncolumns, skip; - printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); - maxlen = 10; - for(i=0; i<lemp->nsymbol; i++){ - sp = lemp->symbols[i]; - len = lemonStrlen(sp->name); - if( len>maxlen ) maxlen = len; - } - ncolumns = 76/(maxlen+5); - if( ncolumns<1 ) ncolumns = 1; - skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; - for(i=0; i<skip; i++){ - printf("//"); - for(j=i; j<lemp->nsymbol; j+=skip){ - sp = lemp->symbols[j]; - assert( sp->index==j ); - printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); - } - printf("\n"); - } - for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); - /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; i<rp->nrhs; i++){ - sp = rp->rhs[i]; - printf(" %s", sp->name); - if( sp->type==MULTITERMINAL ){ - for(j=1; j<sp->nsubsym; j++){ - printf("|%s", sp->subsym[j]->name); - } - } - /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } - printf("."); - if( rp->precsym ) printf(" [%s]",rp->precsym->name); - /* if( rp->code ) printf("\n %s",rp->code); */ - printf("\n"); - } -} - -void ConfigPrint(fp,cfp) -FILE *fp; -struct config *cfp; -{ - struct rule *rp; - struct symbol *sp; - int i, j; - rp = cfp->rp; - fprintf(fp,"%s ::=",rp->lhs->name); - for(i=0; i<=rp->nrhs; i++){ - if( i==cfp->dot ) fprintf(fp," *"); - if( i==rp->nrhs ) break; - sp = rp->rhs[i]; - fprintf(fp," %s", sp->name); - if( sp->type==MULTITERMINAL ){ - for(j=1; j<sp->nsubsym; j++){ - fprintf(fp,"|%s",sp->subsym[j]->name); - } - } - } -} - -/* #define TEST */ -#if 0 -/* Print a set */ -PRIVATE void SetPrint(out,set,lemp) -FILE *out; -char *set; -struct lemon *lemp; -{ - int i; - char *spacer; - spacer = ""; - fprintf(out,"%12s[",""); - for(i=0; i<lemp->nterminal; i++){ - if( SetFind(set,i) ){ - fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); - spacer = " "; - } - } - fprintf(out,"]\n"); -} - -/* Print a plink chain */ -PRIVATE void PlinkPrint(out,plp,tag) -FILE *out; -struct plink *plp; -char *tag; -{ - while( plp ){ - fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->statenum); - ConfigPrint(out,plp->cfp); - fprintf(out,"\n"); - plp = plp->next; - } -} -#endif - -/* Print an action to the given file descriptor. Return FALSE if -** nothing was actually printed. -*/ -int PrintAction(struct action *ap, FILE *fp, int indent){ - int result = 1; - switch( ap->type ){ - case SHIFT: - fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->statenum); - break; - case REDUCE: - fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); - break; - case ACCEPT: - fprintf(fp,"%*s accept",indent,ap->sp->name); - break; - case ERROR: - fprintf(fp,"%*s error",indent,ap->sp->name); - break; - case SRCONFLICT: - case RRCONFLICT: - fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); - break; - case SSCONFLICT: - fprintf(fp,"%*s shift %d ** Parsing conflict **", - indent,ap->sp->name,ap->x.stp->statenum); - break; - case SH_RESOLVED: - case RD_RESOLVED: - case NOT_USED: - result = 0; - break; - } - return result; -} - -/* Generate the "y.output" log file */ -void ReportOutput(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct config *cfp; - struct action *ap; - FILE *fp; - - fp = file_open(lemp,".out","wb"); - if( fp==0 ) return; - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - fprintf(fp,"State %d:\n",stp->statenum); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#if 0 - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - } - fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } - fprintf(fp,"\n"); - } - fprintf(fp, "----------------------------------------------------\n"); - fprintf(fp, "Symbols:\n"); - for(i=0; i<lemp->nsymbol; i++){ - int j; - struct symbol *sp; - - sp = lemp->symbols[i]; - fprintf(fp, " %3d: %s", i, sp->name); - if( sp->type==NONTERMINAL ){ - fprintf(fp, ":"); - if( sp->lambda ){ - fprintf(fp, " <lambda>"); - } - for(j=0; j<lemp->nterminal; j++){ - if( sp->firstset && SetFind(sp->firstset, j) ){ - fprintf(fp, " %s", lemp->symbols[j]->name); - } - } - } - fprintf(fp, "\n"); - } - fclose(fp); - return; -} - -/* Search for the file "name" which is in the same directory as -** the exacutable */ -PRIVATE char *pathsearch(argv0,name,modemask) -char *argv0; -char *name; -int modemask; -{ - char *pathlist; - char *path,*cp; - char c; - -#ifdef __WIN32__ - cp = strrchr(argv0,'\\'); -#else - cp = strrchr(argv0,'/'); -#endif - if( cp ){ - c = *cp; - *cp = 0; - path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); - *cp = c; - }else{ - extern char *getenv(); - pathlist = getenv("PATH"); - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); - if( path!=0 ){ - while( *pathlist ){ - cp = strchr(pathlist,':'); - if( cp==0 ) cp = &pathlist[lemonStrlen(pathlist)]; - c = *cp; - *cp = 0; - sprintf(path,"%s/%s",pathlist,name); - *cp = c; - if( c==0 ) pathlist = ""; - else pathlist = &cp[1]; - if( access(path,modemask)==0 ) break; - } - } - } - return path; -} - -/* Given an action, compute the integer value for that action -** which is to be put in the action table of the generated machine. -** Return negative if no action should be generated. -*/ -PRIVATE int compute_action(lemp,ap) -struct lemon *lemp; -struct action *ap; -{ - int act; - switch( ap->type ){ - case SHIFT: act = ap->x.stp->statenum; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate; break; - case ERROR: act = lemp->nstate + lemp->nrule; break; - case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; - default: act = -1; break; - } - return act; -} - -#define LINESIZE 1000 -/* The next cluster of routines are for reading the template file -** and writing the results to the generated parser */ -/* The first function transfers data from "in" to "out" until -** a line is seen which begins with "%%". The line number is -** tracked. -** -** if name!=0, then any word that begin with "Parse" is changed to -** begin with *name instead. -*/ -PRIVATE void tplt_xfer(name,in,out,lineno) -char *name; -FILE *in; -FILE *out; -int *lineno; -{ - int i, iStart; - char line[LINESIZE]; - while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ - (*lineno)++; - iStart = 0; - if( name ){ - for(i=0; line[i]; i++){ - if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 - && (i==0 || !isalpha(line[i-1])) - ){ - if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); - fprintf(out,"%s",name); - i += 4; - iStart = i+1; - } - } - } - fprintf(out,"%s",&line[iStart]); - } -} - -/* The next function finds the template file and opens it, returning -** a pointer to the opened file. */ -PRIVATE FILE *tplt_open(lemp) -struct lemon *lemp; -{ - static char templatename[] = "lempar.c"; - char buf[1000]; - FILE *in; - char *tpltname; - char *cp; - - cp = strrchr(lemp->filename,'.'); - if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); - }else{ - sprintf(buf,"%s.lt",lemp->filename); - } - if( access(buf,004)==0 ){ - tpltname = buf; - }else if( access(templatename,004)==0 ){ - tpltname = templatename; - }else{ - tpltname = pathsearch(lemp->argv0,templatename,0); - } - if( tpltname==0 ){ - fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", - templatename); - lemp->errorcnt++; - return 0; - } - in = fopen(tpltname,"rb"); - if( in==0 ){ - fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - lemp->errorcnt++; - return 0; - } - return in; -} - -/* Print a #line directive line to the output file. */ -PRIVATE void tplt_linedir(out,lineno,filename) -FILE *out; -int lineno; -char *filename; -{ - fprintf(out,"#line %d \"",lineno); - while( *filename ){ - if( *filename == '\\' ) putc('\\',out); - putc(*filename,out); - filename++; - } - fprintf(out,"\"\n"); -} - -/* Print a string to the file and keep the linenumber up to date */ -PRIVATE void tplt_print(out,lemp,str,lineno) -FILE *out; -struct lemon *lemp; -char *str; -int *lineno; -{ - if( str==0 ) return; - while( *str ){ - putc(*str,out); - if( *str=='\n' ) (*lineno)++; - str++; - } - if( str[-1]!='\n' ){ - putc('\n',out); - (*lineno)++; - } - if (!lemp->nolinenosflag) { - (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); - } - return; -} - -/* -** The following routine emits code for the destructor for the -** symbol sp -*/ -void emit_destructor_code(out,sp,lemp,lineno) -FILE *out; -struct symbol *sp; -struct lemon *lemp; -int *lineno; -{ - char *cp = 0; - - if( sp->type==TERMINAL ){ - cp = lemp->tokendest; - if( cp==0 ) return; - fprintf(out,"{\n"); (*lineno)++; - }else if( sp->destructor ){ - cp = sp->destructor; - fprintf(out,"{\n"); (*lineno)++; - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,sp->destLineno,lemp->filename); } - }else if( lemp->vardest ){ - cp = lemp->vardest; - if( cp==0 ) return; - fprintf(out,"{\n"); (*lineno)++; - }else{ - assert( 0 ); /* Cannot happen */ - } - for(; *cp; cp++){ - if( *cp=='$' && cp[1]=='$' ){ - fprintf(out,"(yypminor->yy%d)",sp->dtnum); - cp++; - continue; - } - if( *cp=='\n' ) (*lineno)++; - fputc(*cp,out); - } - fprintf(out,"\n"); (*lineno)++; - if (!lemp->nolinenosflag) { - (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); - } - fprintf(out,"}\n"); (*lineno)++; - return; -} - -/* -** Return TRUE (non-zero) if the given symbol has a destructor. -*/ -int has_destructor(sp, lemp) -struct symbol *sp; -struct lemon *lemp; -{ - int ret; - if( sp->type==TERMINAL ){ - ret = lemp->tokendest!=0; - }else{ - ret = lemp->vardest!=0 || sp->destructor!=0; - } - return ret; -} - -/* -** Append text to a dynamically allocated string. If zText is 0 then -** reset the string to be empty again. Always return the complete text -** of the string (which is overwritten with each call). -** -** n bytes of zText are stored. If n==0 then all of zText up to the first -** \000 terminator is stored. zText can contain up to two instances of -** %d. The values of p1 and p2 are written into the first and second -** %d. -** -** If n==-1, then the previous character is overwritten. -*/ -PRIVATE char *append_str(char *zText, int n, int p1, int p2){ - static char *z = 0; - static int alloced = 0; - static int used = 0; - int c; - char zInt[40]; - - if( zText==0 ){ - used = 0; - return z; - } - if( n<=0 ){ - if( n<0 ){ - used += n; - assert( used>=0 ); - } - n = lemonStrlen(zText); - } - if( n+sizeof(zInt)*2+used >= alloced ){ - alloced = n + sizeof(zInt)*2 + used + 200; - z = realloc(z, alloced); - } - if( z==0 ) return ""; - while( n-- > 0 ){ - c = *(zText++); - if( c=='%' && n>0 && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); - p1 = p2; - strcpy(&z[used], zInt); - used += lemonStrlen(&z[used]); - zText++; - n--; - }else{ - z[used++] = c; - } - } - z[used] = 0; - return z; -} - -/* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. -*/ -PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ - char *cp, *xp; - int i; - char lhsused = 0; /* True if the LHS element has been used */ - char used[MAXRHS]; /* True for each RHS element which is used */ - - for(i=0; i<rp->nrhs; i++) used[i] = 0; - lhsused = 0; - - if( rp->code==0 ){ - rp->code = "\n"; - rp->line = rp->ruleline; - } - - append_str(0,0,0,0); - for(cp=rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ - char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); - saved = *xp; - *xp = 0; - if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ - append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); - cp = xp; - lhsused = 1; - }else{ - for(i=0; i<rp->nrhs; i++){ - if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ - if( cp!=rp->code && cp[-1]=='@' ){ - /* If the argument is of the form @X then substituted - ** the token number of X, not the value of X */ - append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); - }else{ - struct symbol *sp = rp->rhs[i]; - int dtnum; - if( sp->type==MULTITERMINAL ){ - dtnum = sp->subsym[0]->dtnum; - }else{ - dtnum = sp->dtnum; - } - append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum); - } - cp = xp; - used[i] = 1; - break; - } - } - } - *xp = saved; - } - append_str(cp, 1, 0, 0); - } /* End loop */ - - /* Check to make sure the LHS has been used */ - if( rp->lhsalias && !lhsused ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label \"%s\" for \"%s(%s)\" is never used.", - rp->lhsalias,rp->lhs->name,rp->lhsalias); - lemp->errorcnt++; - } - - /* Generate destructor code for RHS symbols which are not used in the - ** reduce code */ - for(i=0; i<rp->nrhs; i++){ - if( rp->rhsalias[i] && !used[i] ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label %s for \"%s(%s)\" is never used.", - rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); - lemp->errorcnt++; - }else if( rp->rhsalias[i]==0 ){ - if( has_destructor(rp->rhs[i],lemp) ){ - append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, - rp->rhs[i]->index,i-rp->nrhs+1); - }else{ - /* No destructor defined for this term */ - } - } - } - if( rp->code ){ - cp = append_str(0,0,0,0); - rp->code = Strsafe(cp?cp:""); - } -} - -/* -** Generate code which executes when the rule "rp" is reduced. Write -** the code to "out". Make sure lineno stays up-to-date. -*/ -PRIVATE void emit_code(out,rp,lemp,lineno) -FILE *out; -struct rule *rp; -struct lemon *lemp; -int *lineno; -{ - char *cp; - - /* Generate code to do the reduce action */ - if( rp->code ){ - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,rp->line,lemp->filename); } - fprintf(out,"{%s",rp->code); - for(cp=rp->code; *cp; cp++){ - if( *cp=='\n' ) (*lineno)++; - } /* End loop */ - fprintf(out,"}\n"); (*lineno)++; - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); } - } /* End if( rp->code ) */ - - return; -} - -/* -** Print the definition of the union used for the parser's data stack. -** This union contains fields for every possible data type for tokens -** and nonterminals. In the process of computing and printing this -** union, also set the ".dtnum" field of every terminal and nonterminal -** symbol. -*/ -void print_stack_union(out,lemp,plineno,mhflag) -FILE *out; /* The output stream */ -struct lemon *lemp; /* The main info structure for this parser */ -int *plineno; /* Pointer to the line number */ -int mhflag; /* True if generating makeheaders output */ -{ - int lineno = *plineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ - char *stddt; /* Standardized name for a datatype */ - int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ - char *name; /* Name of the parser */ - - /* Allocate and initialize types[] and allocate stddt[] */ - arraysize = lemp->nsymbol * 2; - types = (char**)calloc( arraysize, sizeof(char*) ); - for(i=0; i<arraysize; i++) types[i] = 0; - maxdtlength = 0; - if( lemp->vartype ){ - maxdtlength = lemonStrlen(lemp->vartype); - } - for(i=0; i<lemp->nsymbol; i++){ - int len; - struct symbol *sp = lemp->symbols[i]; - if( sp->datatype==0 ) continue; - len = lemonStrlen(sp->datatype); - if( len>maxdtlength ) maxdtlength = len; - } - stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - - /* Build a hash table of datatypes. The ".dtnum" field of each symbol - ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is - ** used for terminal symbols. If there is no %default_type defined then - ** 0 is also used as the .dtnum value for nonterminals which do not specify - ** a datatype using the %type directive. - */ - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - char *cp; - if( sp==lemp->errsym ){ - sp->dtnum = arraysize+1; - continue; - } - if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ - sp->dtnum = 0; - continue; - } - cp = sp->datatype; - if( cp==0 ) cp = lemp->vartype; - j = 0; - while( isspace(*cp) ) cp++; - while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; - stddt[j] = 0; - if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){ - sp->dtnum = 0; - continue; - } - hash = 0; - for(j=0; stddt[j]; j++){ - hash = hash*53 + stddt[j]; - } - hash = (hash & 0x7fffffff)%arraysize; - while( types[hash] ){ - if( strcmp(types[hash],stddt)==0 ){ - sp->dtnum = hash + 1; - break; - } - hash++; - if( hash>=arraysize ) hash = 0; - } - if( types[hash]==0 ){ - sp->dtnum = hash + 1; - types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); - if( types[hash]==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - strcpy(types[hash],stddt); - } - } - - /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ - name = lemp->name ? lemp->name : "Parse"; - lineno = *plineno; - if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } - fprintf(out,"#define %sTOKENTYPE %s\n",name, - lemp->tokentype?lemp->tokentype:"void*"); lineno++; - if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - fprintf(out,"typedef union {\n"); lineno++; - fprintf(out," int yyinit;\n"); lineno++; - fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; - for(i=0; i<arraysize; i++){ - if( types[i]==0 ) continue; - fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; - free(types[i]); - } - if( lemp->errsym->useCnt ){ - fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; - } - free(stddt); - free(types); - fprintf(out,"} YYMINORTYPE;\n"); lineno++; - *plineno = lineno; -} - -/* -** Return the name of a C datatype able to represent values between -** lwr and upr, inclusive. -*/ -static const char *minimum_size_type(int lwr, int upr){ - if( lwr>=0 ){ - if( upr<=255 ){ - return "unsigned char"; - }else if( upr<65535 ){ - return "unsigned short int"; - }else{ - return "unsigned int"; - } - }else if( lwr>=-127 && upr<=127 ){ - return "signed char"; - }else if( lwr>=-32767 && upr<32767 ){ - return "short"; - }else{ - return "int"; - } -} - -/* -** Each state contains a set of token transaction and a set of -** nonterminal transactions. Each of these sets makes an instance -** of the following structure. An array of these structures is used -** to order the creation of entries in the yy_action[] table. -*/ -struct axset { - struct state *stp; /* A pointer to a state */ - int isTkn; /* True to use tokens. False for non-terminals */ - int nAction; /* Number of actions */ -}; - -/* -** Compare to axset structures for sorting purposes -*/ -static int axset_compare(const void *a, const void *b){ - struct axset *p1 = (struct axset*)a; - struct axset *p2 = (struct axset*)b; - return p2->nAction - p1->nAction; -} - -/* -** Write text on "out" that describes the rule "rp". -*/ -static void writeRuleText(FILE *out, struct rule *rp){ - int j; - fprintf(out,"%s ::=", rp->lhs->name); - for(j=0; j<rp->nrhs; j++){ - struct symbol *sp = rp->rhs[j]; - fprintf(out," %s", sp->name); - if( sp->type==MULTITERMINAL ){ - int k; - for(k=1; k<sp->nsubsym; k++){ - fprintf(out,"|%s",sp->subsym[k]->name); - } - } - } -} - - -/* Generate C source code for the parser */ -void ReportTable(lemp, mhflag) -struct lemon *lemp; -int mhflag; /* Output in makeheaders format if true */ -{ - FILE *out, *in; - char line[LINESIZE]; - int lineno; - struct state *stp; - struct action *ap; - struct rule *rp; - struct acttab *pActtab; - int i, j, n; - char *name; - int mnTknOfst, mxTknOfst; - int mnNtOfst, mxNtOfst; - struct axset *ax; - - in = tplt_open(lemp); - if( in==0 ) return; - out = file_open(lemp,".c","wb"); - if( out==0 ){ - fclose(in); - return; - } - lineno = 1; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,&lineno); - if( mhflag ){ - char *name = file_makename(lemp, ".h"); - fprintf(out,"#include \"%s\"\n", name); lineno++; - free(name); - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate #defines for all tokens */ - if( mhflag ){ - char *prefix; - fprintf(out,"#if INTERFACE\n"); lineno++; - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - for(i=1; i<lemp->nterminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - lineno++; - } - fprintf(out,"#endif\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the defines */ - fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+1)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; - fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; - if( lemp->wildcard ){ - fprintf(out,"#define YYWILDCARD %d\n", - lemp->wildcard->index); lineno++; - } - print_stack_union(out,lemp,&lineno,mhflag); - fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++; - if( lemp->stacksize ){ - fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; - }else{ - fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; - } - fprintf(out, "#endif\n"); lineno++; - if( mhflag ){ - fprintf(out,"#if INTERFACE\n"); lineno++; - } - name = lemp->name ? lemp->name : "Parse"; - if( lemp->arg && lemp->arg[0] ){ - int i; - i = lemonStrlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; - fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", - name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", - name,&lemp->arg[i],&lemp->arg[i]); lineno++; - }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; - fprintf(out,"#define %sARG_FETCH\n",name); lineno++; - fprintf(out,"#define %sARG_STORE\n",name); lineno++; - } - if( mhflag ){ - fprintf(out,"#endif\n"); lineno++; - } - fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; - fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - if( lemp->errsym->useCnt ){ - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; - } - if( lemp->has_fallback ){ - fprintf(out,"#define YYFALLBACK 1\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the action table and its associates: - ** - ** yy_action[] A single table containing all actions. - ** yy_lookahead[] A table containing the lookahead for each entry in - ** yy_action. Used to detect hash collisions. - ** yy_shift_ofst[] For each state, the offset into yy_action for - ** shifting terminals. - ** yy_reduce_ofst[] For each state, the offset into yy_action for - ** shifting non-terminals after a reduce. - ** yy_default[] Default action for each state. - */ - - /* Compute the actions on all states and count them up */ - ax = calloc(lemp->nstate*2, sizeof(ax[0])); - if( ax==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - ax[i*2].stp = stp; - ax[i*2].isTkn = 1; - ax[i*2].nAction = stp->nTknAct; - ax[i*2+1].stp = stp; - ax[i*2+1].isTkn = 0; - ax[i*2+1].nAction = stp->nNtAct; - } - mxTknOfst = mnTknOfst = 0; - mxNtOfst = mnNtOfst = 0; - - /* Compute the action table. In order to try to keep the size of the - ** action table to a minimum, the heuristic of placing the largest action - ** sets first is used. - */ - qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); - for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){ - stp = ax[i].stp; - if( ax[i].isTkn ){ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index>=lemp->nterminal ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iTknOfst = acttab_insert(pActtab); - if( stp->iTknOfst<mnTknOfst ) mnTknOfst = stp->iTknOfst; - if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; - }else{ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index<lemp->nterminal ) continue; - if( ap->sp->index==lemp->nsymbol ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iNtOfst = acttab_insert(pActtab); - if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst; - if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; - } - } - free(ax); - - /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - n = acttab_size(pActtab); - for(i=j=0; i<n; i++){ - int action = acttab_yyaction(pActtab, i); - if( action<0 ) action = lemp->nstate + lemp->nrule + 2; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", action); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_lookahead table */ - fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; - for(i=j=0; i<n; i++){ - int la = acttab_yylookahead(pActtab, i); - if( la<0 ) la = lemp->nsymbol; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; - n = lemp->nstate; - while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++; - fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; - for(i=j=0; i<n; i++){ - int ofst; - stp = lemp->sorted[i]; - ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; - n = lemp->nstate; - while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++; - fprintf(out, "static const %s yy_reduce_ofst[] = {\n", - minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; - for(i=j=0; i<n; i++){ - int ofst; - stp = lemp->sorted[i]; - ofst = stp->iNtOfst; - if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the default action table */ - fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; - n = lemp->nstate; - for(i=j=0; i<n; i++){ - stp = lemp->sorted[i]; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDflt); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of fallback tokens. - */ - if( lemp->has_fallback ){ - int mx = lemp->nterminal - 1; - while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } - for(i=0; i<=mx; i++){ - struct symbol *p = lemp->symbols[i]; - if( p->fallback==0 ){ - fprintf(out, " 0, /* %10s => nothing */\n", p->name); - }else{ - fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, - p->name, p->fallback->name); - } - lineno++; - } - } - tplt_xfer(lemp->name, in, out, &lineno); - - /* Generate a table containing the symbolic name of every symbol - */ - for(i=0; i<lemp->nsymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } - } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate a table containing a text string that describes every - ** rule in the rule set of the grammar. This information is used - ** when tracing REDUCE actions. - */ - for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); - fprintf(out," /* %3d */ \"", i); - writeRuleText(out, rp); - fprintf(out,"\",\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes every time a symbol is popped from - ** the stack while processing errors or while destroying the parser. - ** (In other words, generate the %destructor actions) - */ - if( lemp->tokendest ){ - int once = 1; - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type!=TERMINAL ) continue; - if( once ){ - fprintf(out, " /* TERMINAL Destructor */\n"); lineno++; - once = 0; - } - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - } - for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++); - if( i<lemp->nsymbol ){ - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - int once = 1; - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - if( once ){ - fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++; - once = 0; - } - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - } - fprintf(out," break;\n"); lineno++; - } - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - - /* Combine duplicate destructors into a single case */ - for(j=i+1; j<lemp->nsymbol; j++){ - struct symbol *sp2 = lemp->symbols[j]; - if( sp2 && sp2->type!=TERMINAL && sp2->destructor - && sp2->dtnum==sp->dtnum - && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d: /* %s */\n", - sp2->index, sp2->name); lineno++; - sp2->destructor = 0; - } - } - - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes whenever the parser stack overflows */ - tplt_print(out,lemp,lemp->overflow,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of rule information - ** - ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. - */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which execution during each REDUCE action */ - for(rp=lemp->rule; rp; rp=rp->next){ - translate_code(lemp, rp); - } - /* First output rules other than the default: rule */ - for(rp=lemp->rule; rp; rp=rp->next){ - struct rule *rp2; /* Other rules with the same action */ - if( rp->code==0 ) continue; - if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ - fprintf(out," case %d: /* ", rp->index); - writeRuleText(out, rp); - fprintf(out, " */\n"); lineno++; - for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ - fprintf(out," case %d: /* ", rp2->index); - writeRuleText(out, rp2); - fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++; - rp2->code = 0; - } - } - emit_code(out,rp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - rp->code = 0; - } - /* Finally, output the default: rule. We choose as the default: all - ** empty actions. */ - fprintf(out," default:\n"); lineno++; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code==0 ) continue; - assert( rp->code[0]=='\n' && rp->code[1]==0 ); - fprintf(out," /* (%d) ", rp->index); - writeRuleText(out, rp); - fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++; - } - fprintf(out," break;\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes if a parse fails */ - tplt_print(out,lemp,lemp->failure,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when a syntax error occurs */ - tplt_print(out,lemp,lemp->error,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when the parser accepts its input */ - tplt_print(out,lemp,lemp->accept,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Append any addition code the user desires */ - tplt_print(out,lemp,lemp->extracode,&lineno); - - fclose(in); - fclose(out); - return; -} - -/* Generate a header file for the parser */ -void ReportHeader(lemp) -struct lemon *lemp; -{ - FILE *out, *in; - char *prefix; - char line[LINESIZE]; - char pattern[LINESIZE]; - int i; - - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - in = file_open(lemp,".h","rb"); - if( in ){ - for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - if( strcmp(line,pattern) ) break; - } - fclose(in); - if( i==lemp->nterminal ){ - /* No change in the file. Don't rewrite it. */ - return; - } - } - out = file_open(lemp,".h","wb"); - if( out ){ - for(i=1; i<lemp->nterminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - } - fclose(out); - } - return; -} - -/* Reduce the size of the action tables, if possible, by making use -** of defaults. -** -** In this version, we take the most frequent REDUCE action and make -** it the default. Except, there is no default if the wildcard token -** is a possible look-ahead. -*/ -void CompressTables(lemp) -struct lemon *lemp; -{ - struct state *stp; - struct action *ap, *ap2; - struct rule *rp, *rp2, *rbest; - int nbest, n; - int i; - int usesWildcard; - - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - nbest = 0; - rbest = 0; - usesWildcard = 0; - - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==SHIFT && ap->sp==lemp->wildcard ){ - usesWildcard = 1; - } - if( ap->type!=REDUCE ) continue; - rp = ap->x.rp; - if( rp->lhsStart ) continue; - if( rp==rbest ) continue; - n = 1; - for(ap2=ap->next; ap2; ap2=ap2->next){ - if( ap2->type!=REDUCE ) continue; - rp2 = ap2->x.rp; - if( rp2==rbest ) continue; - if( rp2==rp ) n++; - } - if( n>nbest ){ - nbest = n; - rbest = rp; - } - } - - /* Do not make a default if the number of rules to default - ** is not at least 1 or if the wildcard token is a possible - ** lookahead. - */ - if( nbest<1 || usesWildcard ) continue; - - - /* Combine matching REDUCE actions into a single default */ - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) break; - } - assert( ap ); - ap->sp = Symbol_new("{default}"); - for(ap=ap->next; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; - } - stp->ap = Action_sort(stp->ap); - } -} - - -/* -** Compare two states for sorting purposes. The smaller state is the -** one with the most non-terminal actions. If they have the same number -** of non-terminal actions, then the smaller is the one with the most -** token actions. -*/ -static int stateResortCompare(const void *a, const void *b){ - const struct state *pA = *(const struct state**)a; - const struct state *pB = *(const struct state**)b; - int n; - - n = pB->nNtAct - pA->nNtAct; - if( n==0 ){ - n = pB->nTknAct - pA->nTknAct; - } - return n; -} - - -/* -** Renumber and resort states so that states with fewer choices -** occur at the end. Except, keep state 0 as the first state. -*/ -void ResortStates(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct action *ap; - - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - stp->nTknAct = stp->nNtAct = 0; - stp->iDflt = lemp->nstate + lemp->nrule; - stp->iTknOfst = NO_OFFSET; - stp->iNtOfst = NO_OFFSET; - for(ap=stp->ap; ap; ap=ap->next){ - if( compute_action(lemp,ap)>=0 ){ - if( ap->sp->index<lemp->nterminal ){ - stp->nTknAct++; - }else if( ap->sp->index<lemp->nsymbol ){ - stp->nNtAct++; - }else{ - stp->iDflt = compute_action(lemp, ap); - } - } - } - } - qsort(&lemp->sorted[1], lemp->nstate-1, sizeof(lemp->sorted[0]), - stateResortCompare); - for(i=0; i<lemp->nstate; i++){ - lemp->sorted[i]->statenum = i; - } -} - - -/***************** From the file "set.c" ************************************/ -/* -** Set manipulation routines for the LEMON parser generator. -*/ - -static int size = 0; - -/* Set the set size */ -void SetSize(n) -int n; -{ - size = n+1; -} - -/* Allocate a new set */ -char *SetNew(){ - char *s; - s = (char*)calloc( size, 1); - if( s==0 ){ - extern void memory_error(); - memory_error(); - } - return s; -} - -/* Deallocate a set */ -void SetFree(s) -char *s; -{ - free(s); -} - -/* Add a new element to the set. Return TRUE if the element was added -** and FALSE if it was already there. */ -int SetAdd(s,e) -char *s; -int e; -{ - int rv; - assert( e>=0 && e<size ); - rv = s[e]; - s[e] = 1; - return !rv; -} - -/* Add every element of s2 to s1. Return TRUE if s1 changes. */ -int SetUnion(s1,s2) -char *s1; -char *s2; -{ - int i, progress; - progress = 0; - for(i=0; i<size; i++){ - if( s2[i]==0 ) continue; - if( s1[i]==0 ){ - progress = 1; - s1[i] = 1; - } - } - return progress; -} -/********************** From the file "table.c" ****************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -PRIVATE int strhash(x) -char *x; -{ - int h = 0; - while( *x) h = h*13 + *(x++); - return h; -} - -/* Works like strdup, sort of. Save a string in malloced memory, but -** keep strings in a table so that the same string is not in more -** than one place. -*/ -char *Strsafe(y) -char *y; -{ - char *z; - - if( y==0 ) return 0; - z = Strsafe_find(y); - if( z==0 && (z=malloc( lemonStrlen(y)+1 ))!=0 ){ - strcpy(z,y); - Strsafe_insert(z); - } - MemoryCheck(z); - return z; -} - -/* There is one instance of the following structure for each -** associative array of type "x1". -*/ -struct s_x1 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x1node *tbl; /* The data stored here */ - struct s_x1node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x1". -*/ -typedef struct s_x1node { - char *data; /* The data */ - struct s_x1node *next; /* Next entry with the same hash */ - struct s_x1node **from; /* Previous link */ -} x1node; - -/* There is only one instance of the array, which is the following */ -static struct s_x1 *x1a; - -/* Allocate a new associative array */ -void Strsafe_init(){ - if( x1a ) return; - x1a = (struct s_x1*)malloc( sizeof(struct s_x1) ); - if( x1a ){ - x1a->size = 1024; - x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); - if( x1a->tbl==0 ){ - free(x1a); - x1a = 0; - }else{ - int i; - x1a->ht = (x1node**)&(x1a->tbl[1024]); - for(i=0; i<1024; i++) x1a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Strsafe_insert(data) -char *data; -{ - x1node *np; - int h; - int ph; - - if( x1a==0 ) return 0; - ph = strhash(data); - h = ph & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x1a->count>=x1a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x1 array; - array.size = size = x1a->size*2; - array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x1node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x1a->count; i++){ - x1node *oldnp, *newnp; - oldnp = &(x1a->tbl[i]); - h = strhash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x1a->tbl); - *x1a = array; - } - /* Insert the new data */ - h = ph & (x1a->size-1); - np = &(x1a->tbl[x1a->count++]); - np->data = data; - if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); - np->next = x1a->ht[h]; - x1a->ht[h] = np; - np->from = &(x1a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -char *Strsafe_find(key) -char *key; -{ - int h; - x1node *np; - - if( x1a==0 ) return 0; - h = strhash(key) & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return a pointer to the (terminal or nonterminal) symbol "x". -** Create a new symbol if this is the first time "x" has been seen. -*/ -struct symbol *Symbol_new(x) -char *x; -{ - struct symbol *sp; - - sp = Symbol_find(x); - if( sp==0 ){ - sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); - MemoryCheck(sp); - sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; - sp->prec = -1; - sp->assoc = UNK; - sp->firstset = 0; - sp->lambda = LEMON_FALSE; - sp->destructor = 0; - sp->destLineno = 0; - sp->datatype = 0; - sp->useCnt = 0; - Symbol_insert(sp,sp->name); - } - sp->useCnt++; - return sp; -} - -/* Compare two symbols for working purposes -** -** Symbols that begin with upper case letters (terminals or tokens) -** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. -** -** We find experimentally that leaving the symbols in their original -** order (the order they appeared in the grammar file) gives the -** smallest parser tables in SQLite. -*/ -int Symbolcmpp(struct symbol **a, struct symbol **b){ - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - return i1-i2; -} - -/* There is one instance of the following structure for each -** associative array of type "x2". -*/ -struct s_x2 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x2node *tbl; /* The data stored here */ - struct s_x2node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x2". -*/ -typedef struct s_x2node { - struct symbol *data; /* The data */ - char *key; /* The key */ - struct s_x2node *next; /* Next entry with the same hash */ - struct s_x2node **from; /* Previous link */ -} x2node; - -/* There is only one instance of the array, which is the following */ -static struct s_x2 *x2a; - -/* Allocate a new associative array */ -void Symbol_init(){ - if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); - if( x2a ){ - x2a->size = 128; - x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); - if( x2a->tbl==0 ){ - free(x2a); - x2a = 0; - }else{ - int i; - x2a->ht = (x2node**)&(x2a->tbl[128]); - for(i=0; i<128; i++) x2a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Symbol_insert(data,key) -struct symbol *data; -char *key; -{ - x2node *np; - int h; - int ph; - - if( x2a==0 ) return 0; - ph = strhash(key); - h = ph & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x2a->count>=x2a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x2 array; - array.size = size = x2a->size*2; - array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x2node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x2a->count; i++){ - x2node *oldnp, *newnp; - oldnp = &(x2a->tbl[i]); - h = strhash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x2a->tbl); - *x2a = array; - } - /* Insert the new data */ - h = ph & (x2a->size-1); - np = &(x2a->tbl[x2a->count++]); - np->key = key; - np->data = data; - if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); - np->next = x2a->ht[h]; - x2a->ht[h] = np; - np->from = &(x2a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct symbol *Symbol_find(key) -char *key; -{ - int h; - x2node *np; - - if( x2a==0 ) return 0; - h = strhash(key) & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return the n-th data. Return NULL if n is out of range. */ -struct symbol *Symbol_Nth(n) -int n; -{ - struct symbol *data; - if( x2a && n>0 && n<=x2a->count ){ - data = x2a->tbl[n-1].data; - }else{ - data = 0; - } - return data; -} - -/* Return the size of the array */ -int Symbol_count() -{ - return x2a ? x2a->count : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof() -{ - struct symbol **array; - int i,size; - if( x2a==0 ) return 0; - size = x2a->count; - array = (struct symbol **)calloc(size, sizeof(struct symbol *)); - if( array ){ - for(i=0; i<size; i++) array[i] = x2a->tbl[i].data; - } - return array; -} - -/* Compare two configurations */ -int Configcmp(a,b) -struct config *a; -struct config *b; -{ - int x; - x = a->rp->index - b->rp->index; - if( x==0 ) x = a->dot - b->dot; - return x; -} - -/* Compare two states */ -PRIVATE int statecmp(a,b) -struct config *a; -struct config *b; -{ - int rc; - for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ - rc = a->rp->index - b->rp->index; - if( rc==0 ) rc = a->dot - b->dot; - } - if( rc==0 ){ - if( a ) rc = 1; - if( b ) rc = -1; - } - return rc; -} - -/* Hash a state */ -PRIVATE int statehash(a) -struct config *a; -{ - int h=0; - while( a ){ - h = h*571 + a->rp->index*37 + a->dot; - a = a->bp; - } - return h; -} - -/* Allocate a new state structure */ -struct state *State_new() -{ - struct state *new; - new = (struct state *)calloc(1, sizeof(struct state) ); - MemoryCheck(new); - return new; -} - -/* There is one instance of the following structure for each -** associative array of type "x3". -*/ -struct s_x3 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x3node *tbl; /* The data stored here */ - struct s_x3node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x3". -*/ -typedef struct s_x3node { - struct state *data; /* The data */ - struct config *key; /* The key */ - struct s_x3node *next; /* Next entry with the same hash */ - struct s_x3node **from; /* Previous link */ -} x3node; - -/* There is only one instance of the array, which is the following */ -static struct s_x3 *x3a; - -/* Allocate a new associative array */ -void State_init(){ - if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); - if( x3a ){ - x3a->size = 128; - x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); - if( x3a->tbl==0 ){ - free(x3a); - x3a = 0; - }else{ - int i; - x3a->ht = (x3node**)&(x3a->tbl[128]); - for(i=0; i<128; i++) x3a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int State_insert(data,key) -struct state *data; -struct config *key; -{ - x3node *np; - int h; - int ph; - - if( x3a==0 ) return 0; - ph = statehash(key); - h = ph & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x3a->count>=x3a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x3 array; - array.size = size = x3a->size*2; - array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x3node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x3a->count; i++){ - x3node *oldnp, *newnp; - oldnp = &(x3a->tbl[i]); - h = statehash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x3a->tbl); - *x3a = array; - } - /* Insert the new data */ - h = ph & (x3a->size-1); - np = &(x3a->tbl[x3a->count++]); - np->key = key; - np->data = data; - if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); - np->next = x3a->ht[h]; - x3a->ht[h] = np; - np->from = &(x3a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct state *State_find(key) -struct config *key; -{ - int h; - x3node *np; - - if( x3a==0 ) return 0; - h = statehash(key) & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct state **State_arrayof() -{ - struct state **array; - int i,size; - if( x3a==0 ) return 0; - size = x3a->count; - array = (struct state **)malloc( sizeof(struct state *)*size ); - if( array ){ - for(i=0; i<size; i++) array[i] = x3a->tbl[i].data; - } - return array; -} - -/* Hash a configuration */ -PRIVATE int confighash(a) -struct config *a; -{ - int h=0; - h = h*571 + a->rp->index*37 + a->dot; - return h; -} - -/* There is one instance of the following structure for each -** associative array of type "x4". -*/ -struct s_x4 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x4node *tbl; /* The data stored here */ - struct s_x4node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x4". -*/ -typedef struct s_x4node { - struct config *data; /* The data */ - struct s_x4node *next; /* Next entry with the same hash */ - struct s_x4node **from; /* Previous link */ -} x4node; - -/* There is only one instance of the array, which is the following */ -static struct s_x4 *x4a; - -/* Allocate a new associative array */ -void Configtable_init(){ - if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); - if( x4a ){ - x4a->size = 64; - x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); - if( x4a->tbl==0 ){ - free(x4a); - x4a = 0; - }else{ - int i; - x4a->ht = (x4node**)&(x4a->tbl[64]); - for(i=0; i<64; i++) x4a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Configtable_insert(data) -struct config *data; -{ - x4node *np; - int h; - int ph; - - if( x4a==0 ) return 0; - ph = confighash(data); - h = ph & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x4a->count>=x4a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x4 array; - array.size = size = x4a->size*2; - array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x4node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x4a->count; i++){ - x4node *oldnp, *newnp; - oldnp = &(x4a->tbl[i]); - h = confighash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x4a->tbl); - *x4a = array; - } - /* Insert the new data */ - h = ph & (x4a->size-1); - np = &(x4a->tbl[x4a->count++]); - np->data = data; - if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); - np->next = x4a->ht[h]; - x4a->ht[h] = np; - np->from = &(x4a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct config *Configtable_find(key) -struct config *key; -{ - int h; - x4node *np; - - if( x4a==0 ) return 0; - h = confighash(key) & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Remove all data from the table. Pass each data to the function "f" -** as it is removed. ("f" may be null to avoid this step.) */ -void Configtable_clear(f) -int(*f)(/* struct config * */); -{ - int i; - if( x4a==0 || x4a->count==0 ) return; - if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data); - for(i=0; i<x4a->size; i++) x4a->ht[i] = 0; - x4a->count = 0; - return; -} diff --git a/external/badvpn_dns/lemon/lempar.c b/external/badvpn_dns/lemon/lempar.c deleted file mode 100644 index 774b875..0000000 --- a/external/badvpn_dns/lemon/lempar.c +++ /dev/null @@ -1,842 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include <stdio.h> -%% -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -%% -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -%% -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -%% -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -%% -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include <stdio.h> -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -** <ul> -** <li> A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -** <li> A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -** </ul> -** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { -%% -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { -%% -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ -%% - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -** <ul> -** <li> A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -** <li> A pointer to a function used to reclaim memory obtained -** from malloc. -** </ul> -*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) - && (iFallback = yyFallback[iLookAhead])!=0 ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && i<YY_SZ_ACTTAB ); - assert( yy_lookahead[i]==iLookAhead ); -#endif - return yy_action[i]; -} - -/* -** The following routine is called if the stack overflows. -*/ -static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ - ParseARG_FETCH; - yypParser->yyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { -%% -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line <lineno> <grammarfile> - ** { ... } // User supplied code - ** #line <lineno> <thisfile> - ** break; - */ -%% - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -** <ul> -** <li> A pointer to the parser (an opaque structure.) -** <li> The major token number. -** <li> The minor token number. -** <li> An option argument of a grammar-specified type. -** </ul> -** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact<YYNSTATE ){ - assert( !yyendofinput ); /* Impossible to shift the $ token */ - yy_shift(yypParser,yyact,yymajor,&yyminorunion); - yypParser->yyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/external/badvpn_dns/lime/HOWTO b/external/badvpn_dns/lime/HOWTO deleted file mode 100644 index f447c84..0000000 --- a/external/badvpn_dns/lime/HOWTO +++ /dev/null @@ -1,70 +0,0 @@ -Lime: An LALR(1) parser generator in and for PHP. - -Interpretter pattern got you down? Time to use a real parser? Welcome to Lime. - -If you're familiar with BISON or YACC, you may want to read the metagrammar. -It's written in the Lime input language, so you'll get a head-start on -understanding how to use Lime. - -0. If you're not running Linux on an IA32 box, then you will have to rebuild - lime_scan_tokens for your system. It should be enough to erase it, - and then type "CFLAGS=-O2 make lime_scan_tokens" at the bash prompt. - -1. Stare at the file lime/metagrammar to understand the syntax. You're seeing - slightly modified and tweaked Backus-Naur forms. The main differences - are that you get to name your components, instead of refering to them - by numbers the way that BISON demands. This idea was stolen from the - C-based "Lemon" parser from which Lime derives its name. Incidentally, - the author of Lemon disclaimed copyright, so you get a copy of the C - code that taught me LALR(1) parsing better than any book, despite the - obvious difficulties in understanding it. Oh, and one other thing: - symbols are terminal if the scanner feeds them to the parser. They - are non-terminal if they appear on the left side of a production rule. - Lime names semantic categories using strings instead of the numbers - that BISON-based parsers use, so you don't have to declare any list of - terminal symbols anywhere. - -2. Look at the file lime/lime.php to see what pragmas are defined. To be more - specific, you might look at the method lime::pragma(), which at the - time of this writing, supports "%left", "%right", "%nonassoc", - "%start", and "%class". The first three are for operator precedence. - The last two declare the start symbol and the name of a PHP class to - generate which will hold all the bottom-up parsing tables. - -3. Write a grammar file. - -4. php /path/to/lime/lime.php list-of-grammar-files > my_parser.php - -5. Read the function parse_lime_grammar() in lime.php to understand - how to integrate your parser into your program. - -6. Integrate your parser as follows: - ---------------- CUT --------------- - -include_once "lime/parse_engine.php"; -include_once "my_parser.php"; -# -# Later: -# -$parser = new parse_engine(new my_parser()); -# -# And still later: -# -try { - while (..something..) { - $parser->eat($type, $val); - # You figure out how to get the parameters. - } - # And after the last token has been eaten: - $parser->eat_eof(); -} catch (parse_error $e) { - die($e->getMessage()); -} -return $parser->semantic; - ---------------- CUT --------------- - -7. You now have the computed semantic value of whatever you parsed. Add salt - and pepper to taste, and serve. - diff --git a/external/badvpn_dns/lime/flex_token_stream.php b/external/badvpn_dns/lime/flex_token_stream.php deleted file mode 100644 index c21e411..0000000 --- a/external/badvpn_dns/lime/flex_token_stream.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - - - -abstract class flex_scanner { - /* - Let's face it: PHP is not up to lexical processing. GNU flex handles - it well, so I've created a little protocol for delegating the work. - Extend this class so that executable() gives a path to your lexical - analyser program. - */ - abstract function executable(); - function __construct($path) { - if (!is_readable($path)) throw new Exception("$path is not readable."); - putenv("PHP_LIME_SCAN_STDIN=$path"); - $scanner = $this->executable(); - $tokens = explode("\0", `$scanner < "\$PHP_LIME_SCAN_STDIN"`); - array_pop($tokens); - $this->tokens = $tokens; - $this->lineno = 1; - } - function next() { - if (list($key, $token) = each($this->tokens)) { - list($this->lineno, $type, $text) = explode("\1", $token); - return array($type, $text); - } - } - function feed($parser) { - while (list($type, $text) = $this->next()) { - $parser->eat($type, $text); - } - return $parser->eat_eof(); - } -} diff --git a/external/badvpn_dns/lime/lemon.c b/external/badvpn_dns/lime/lemon.c deleted file mode 100644 index 708b353..0000000 --- a/external/badvpn_dns/lime/lemon.c +++ /dev/null @@ -1,4588 +0,0 @@ -/* -** This file contains all sources (including headers) to the LEMON -** LALR(1) parser generator. The sources have been combined into a -** single file to make it easy to include LEMON in the source tree -** and Makefile of another program. -** -** The author of this program disclaims copyright. -*/ -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> - -#ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) -# define __WIN32__ -# endif -#endif - -/* #define PRIVATE static */ -#define PRIVATE - -#ifdef TEST -#define MAXRHS 5 /* Set low to exercise exception code */ -#else -#define MAXRHS 1000 -#endif - -char *msort(); -extern void *malloc(); - -/******** From the file "action.h" *************************************/ -struct action *Action_new(); -struct action *Action_sort(); - -/********* From the file "assert.h" ************************************/ -void myassert(); -#ifndef NDEBUG -# define assert(X) if(!(X))myassert(__FILE__,__LINE__) -#else -# define assert(X) -#endif - -/********** From the file "build.h" ************************************/ -void FindRulePrecedences(); -void FindFirstSets(); -void FindStates(); -void FindLinks(); -void FindFollowSets(); -void FindActions(); - -/********* From the file "configlist.h" *********************************/ -void Configlist_init(/* void */); -struct config *Configlist_add(/* struct rule *, int */); -struct config *Configlist_addbasis(/* struct rule *, int */); -void Configlist_closure(/* void */); -void Configlist_sort(/* void */); -void Configlist_sortbasis(/* void */); -struct config *Configlist_return(/* void */); -struct config *Configlist_basis(/* void */); -void Configlist_eat(/* struct config * */); -void Configlist_reset(/* void */); - -/********* From the file "error.h" ***************************************/ -void ErrorMsg(const char *, int,const char *, ...); - -/****** From the file "option.h" ******************************************/ -struct s_options { - enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type; - char *label; - char *arg; - char *message; -}; -int OptInit(/* char**,struct s_options*,FILE* */); -int OptNArgs(/* void */); -char *OptArg(/* int */); -void OptErr(/* int */); -void OptPrint(/* void */); - -/******** From the file "parse.h" *****************************************/ -void Parse(/* struct lemon *lemp */); - -/********* From the file "plink.h" ***************************************/ -struct plink *Plink_new(/* void */); -void Plink_add(/* struct plink **, struct config * */); -void Plink_copy(/* struct plink **, struct plink * */); -void Plink_delete(/* struct plink * */); - -/********** From the file "report.h" *************************************/ -void Reprint(/* struct lemon * */); -void ReportOutput(/* struct lemon * */); -void ReportTable(/* struct lemon * */); -void ReportHeader(/* struct lemon * */); -void CompressTables(/* struct lemon * */); - -/********** From the file "set.h" ****************************************/ -void SetSize(/* int N */); /* All sets will be of size N */ -char *SetNew(/* void */); /* A new set for element 0..N */ -void SetFree(/* char* */); /* Deallocate a set */ - -int SetAdd(/* char*,int */); /* Add element to a set */ -int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ - -#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ - -/********** From the file "struct.h" *************************************/ -/* -** Principal data structures for the LEMON parser generator. -*/ - -typedef enum {B_FALSE=0, B_TRUE} Boolean; - -/* Symbols (terminals and nonterminals) of the grammar are stored -** in the following: */ -struct symbol { - char *name; /* Name of the symbol */ - int index; /* Index number for this symbol */ - enum { - TERMINAL, - NONTERMINAL - } type; /* Symbols are all either TERMINALS or NTs */ - struct rule *rule; /* Linked list of rules of this (if an NT) */ - struct symbol *fallback; /* fallback token in case this token doesn't parse */ - int prec; /* Precedence if defined (-1 otherwise) */ - enum e_assoc { - LEFT, - RIGHT, - NONE, - UNK - } assoc; /* Associativity if predecence is defined */ - char *firstset; /* First-set for all rules of this symbol */ - Boolean lambda; /* True if NT and can generate an empty string */ - char *destructor; /* Code which executes whenever this symbol is - ** popped from the stack during error processing */ - int destructorln; /* Line number of destructor code */ - char *datatype; /* The data type of information held by this - ** object. Only used if type==NONTERMINAL */ - int dtnum; /* The data type number. In the parser, the value - ** stack is a union. The .yy%d element of this - ** union is the correct data type for this object */ -}; - -/* Each production rule in the grammar is stored in the following -** structure. */ -struct rule { - struct symbol *lhs; /* Left-hand side of the rule */ - char *lhsalias; /* Alias for the LHS (NULL if none) */ - int ruleline; /* Line number for the rule */ - int nrhs; /* Number of RHS symbols */ - struct symbol **rhs; /* The RHS symbols */ - char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ - int line; /* Line number at which code begins */ - char *code; /* The code executed when this rule is reduced */ - struct symbol *precsym; /* Precedence symbol for this rule */ - int index; /* An index number for this rule */ - Boolean canReduce; /* True if this rule is ever reduced */ - struct rule *nextlhs; /* Next rule with the same LHS */ - struct rule *next; /* Next rule in the global list */ -}; - -/* A configuration is a production rule of the grammar together with -** a mark (dot) showing how much of that rule has been processed so far. -** Configurations also contain a follow-set which is a list of terminal -** symbols which are allowed to immediately follow the end of the rule. -** Every configuration is recorded as an instance of the following: */ -struct config { - struct rule *rp; /* The rule upon which the configuration is based */ - int dot; /* The parse point */ - char *fws; /* Follow-set for this configuration only */ - struct plink *fplp; /* Follow-set forward propagation links */ - struct plink *bplp; /* Follow-set backwards propagation links */ - struct state *stp; /* Pointer to state which contains this */ - enum { - COMPLETE, /* The status is used during followset and */ - INCOMPLETE /* shift computations */ - } status; - struct config *next; /* Next configuration in the state */ - struct config *bp; /* The next basis configuration */ -}; - -/* Every shift or reduce operation is stored as one of the following */ -struct action { - struct symbol *sp; /* The look-ahead symbol */ - enum e_action { - SHIFT, - ACCEPT, - REDUCE, - ERROR, - CONFLICT, /* Was a reduce, but part of a conflict */ - SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ - RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ - NOT_USED /* Deleted by compression */ - } type; - union { - struct state *stp; /* The new state, if a shift */ - struct rule *rp; /* The rule, if a reduce */ - } x; - struct action *next; /* Next action for this state */ - struct action *collide; /* Next action with the same hash */ -}; - -/* Each state of the generated parser's finite state machine -** is encoded as an instance of the following structure. */ -struct state { - struct config *bp; /* The basis configurations for this state */ - struct config *cfp; /* All configurations in this set */ - int index; /* Sequencial number for this state */ - struct action *ap; /* Array of actions for this state */ - int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ - int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ - int iDflt; /* Default action */ -}; -#define NO_OFFSET (-2147483647) - -/* A followset propagation link indicates that the contents of one -** configuration followset should be propagated to another whenever -** the first changes. */ -struct plink { - struct config *cfp; /* The configuration to which linked */ - struct plink *next; /* The next propagate link */ -}; - -/* The state vector for the entire parser generator is recorded as -** follows. (LEMON uses no global variables and makes little use of -** static variables. Fields in the following structure can be thought -** of as begin global variables in the program.) */ -struct lemon { - struct state **sorted; /* Table of states sorted by state number */ - struct rule *rule; /* List of all rules */ - int nstate; /* Number of states */ - int nrule; /* Number of rules */ - int nsymbol; /* Number of terminal and nonterminal symbols */ - int nterminal; /* Number of terminal symbols */ - struct symbol **symbols; /* Sorted array of pointers to symbols */ - int errorcnt; /* Number of errors */ - struct symbol *errsym; /* The error symbol */ - char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ - char *tokentype; /* Type of terminal symbols in the parser stack */ - char *vartype; /* The default type of non-terminal symbols */ - char *start; /* Name of the start symbol for the grammar */ - char *stacksize; /* Size of the parser stack */ - char *include; /* Code to put at the start of the C file */ - int includeln; /* Line number for start of include code */ - char *error; /* Code to execute when an error is seen */ - int errorln; /* Line number for start of error code */ - char *overflow; /* Code to execute on a stack overflow */ - int overflowln; /* Line number for start of overflow code */ - char *failure; /* Code to execute on parser failure */ - int failureln; /* Line number for start of failure code */ - char *accept; /* Code to execute when the parser excepts */ - int acceptln; /* Line number for the start of accept code */ - char *extracode; /* Code appended to the generated file */ - int extracodeln; /* Line number for the start of the extra code */ - char *tokendest; /* Code to execute to destroy token data */ - int tokendestln; /* Line number for token destroyer code */ - char *vardest; /* Code for the default non-terminal destructor */ - int vardestln; /* Line number for default non-term destructor code*/ - char *filename; /* Name of the input file */ - char *outname; /* Name of the current output file */ - char *tokenprefix; /* A prefix added to token names in the .h file */ - int nconflict; /* Number of parsing conflicts */ - int tablesize; /* Size of the parse tables */ - int basisflag; /* Print only basis configurations */ - int has_fallback; /* True if any %fallback is seen in the grammer */ - char *argv0; /* Name of the program */ -}; - -#define MemoryCheck(X) if((X)==0){ \ - extern void memory_error(); \ - memory_error(); \ -} - -/**************** From the file "table.h" *********************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -/* Routines for handling a strings */ - -char *Strsafe(); - -void Strsafe_init(/* void */); -int Strsafe_insert(/* char * */); -char *Strsafe_find(/* char * */); - -/* Routines for handling symbols of the grammar */ - -struct symbol *Symbol_new(); -int Symbolcmpp(/* struct symbol **, struct symbol ** */); -void Symbol_init(/* void */); -int Symbol_insert(/* struct symbol *, char * */); -struct symbol *Symbol_find(/* char * */); -struct symbol *Symbol_Nth(/* int */); -int Symbol_count(/* */); -struct symbol **Symbol_arrayof(/* */); - -/* Routines to manage the state table */ - -int Configcmp(/* struct config *, struct config * */); -struct state *State_new(); -void State_init(/* void */); -int State_insert(/* struct state *, struct config * */); -struct state *State_find(/* struct config * */); -struct state **State_arrayof(/* */); - -/* Routines used for efficiency in Configlist_add */ - -void Configtable_init(/* void */); -int Configtable_insert(/* struct config * */); -struct config *Configtable_find(/* struct config * */); -void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -struct action *Action_new(){ - static struct action *freelist = 0; - struct action *new; - - if( freelist==0 ){ - int i; - int amt = 100; - freelist = (struct action *)malloc( sizeof(struct action)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; - freelist[amt-1].next = 0; - } - new = freelist; - freelist = freelist->next; - return new; -} - -/* Compare two actions */ -static int actioncmp(ap1,ap2) -struct action *ap1; -struct action *ap2; -{ - int rc; - rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ) rc = (int)ap1->type - (int)ap2->type; - if( rc==0 ){ - assert( ap1->type==REDUCE || ap1->type==RD_RESOLVED || ap1->type==CONFLICT); - assert( ap2->type==REDUCE || ap2->type==RD_RESOLVED || ap2->type==CONFLICT); - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -struct action *Action_sort(ap) -struct action *ap; -{ - ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp); - return ap; -} - -void Action_add(app,type,sp,arg) -struct action **app; -enum e_action type; -struct symbol *sp; -char *arg; -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if( type==SHIFT ){ - new->x.stp = (struct state *)arg; - }else{ - new->x.rp = (struct rule *)arg; - } -} -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ - acttab *p = malloc( sizeof(*p) ); - if( p==0 ){ - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action){ - if( p->nLookahead>=p->nLookaheadAlloc ){ - p->nLookaheadAlloc += 25; - p->aLookahead = realloc( p->aLookahead, - sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if( p->aLookahead==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if( p->nLookahead==0 ){ - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - }else{ - if( p->mxLookahead<lookahead ) p->mxLookahead = lookahead; - if( p->mnLookahead>lookahead ){ - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p){ - int i, j, k, n; - assert( p->nLookahead>0 ); - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if( p->nAction + n >= p->nActionAlloc ){ - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc( p->aAction, - sizeof(p->aAction[0])*p->nActionAlloc); - if( p->aAction==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; i<p->nActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; i<p->nAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( j<p->nLookahead ) continue; - for(j=0; j<p->nAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ - if( p->aAction[i].action!=p->mnAction ) continue; - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 || k>=p->nAction ) break; - if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; - if( p->aLookahead[j].action!=p->aAction[k].action ) break; - } - if( j<p->nLookahead ) continue; - n = 0; - for(j=0; j<p->nAction; j++){ - if( p->aAction[j].lookahead<0 ) continue; - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; - } - if( n==p->nLookahead ){ - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; j<p->nLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if( k>=p->nAction ) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - -/********************** From the file "assert.c" ****************************/ -/* -** A more efficient way of handling assertions. -*/ -void myassert(file,line) -char *file; -int line; -{ - fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file); - exit(1); -} -/********************** From the file "build.c" *****************************/ -/* -** Routines to construction the finite state machine for the LEMON -** parser generator. -*/ - -/* Find a precedence symbol of every rule in the grammar. -** -** Those rules which have a precedence symbol coded in the input -** grammar using the "[symbol]" construct will already have the -** rp->precsym field filled. Other rules take as their precedence -** symbol the first RHS symbol with a defined precedence. If there -** are not RHS symbols with a defined precedence, the precedence -** symbol field is left blank. -*/ -void FindRulePrecedences(xp) -struct lemon *xp; -{ - struct rule *rp; - for(rp=xp->rule; rp; rp=rp->next){ - if( rp->precsym==0 ){ - int i; - for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]->prec>=0 ){ - rp->precsym = rp->rhs[i]; - break; - } - } - } - } - return; -} - -/* Find all nonterminals which will generate the empty string. -** Then go back and compute the first sets of every nonterminal. -** The first set is the set of all terminal symbols which can begin -** a string generated by that nonterminal. -*/ -void FindFirstSets(lemp) -struct lemon *lemp; -{ - int i; - struct rule *rp; - int progress; - - for(i=0; i<lemp->nsymbol; i++){ - lemp->symbols[i]->lambda = B_FALSE; - } - for(i=lemp->nterminal; i<lemp->nsymbol; i++){ - lemp->symbols[i]->firstset = SetNew(); - } - - /* First compute all lambdas */ - do{ - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->lhs->lambda ) continue; - for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]->lambda==B_FALSE ) break; - } - if( i==rp->nrhs ){ - rp->lhs->lambda = B_TRUE; - progress = 1; - } - } - }while( progress ); - - /* Now compute all first sets */ - do{ - struct symbol *s1, *s2; - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - s1 = rp->lhs; - for(i=0; i<rp->nrhs; i++){ - s2 = rp->rhs[i]; - if( s2->type==TERMINAL ){ - progress += SetAdd(s1->firstset,s2->index); - break; - }else if( s1==s2 ){ - if( s1->lambda==B_FALSE ) break; - }else{ - progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==B_FALSE ) break; - } - } - } - }while( progress ); - return; -} - -/* Compute all LR(0) states for the grammar. Links -** are added to between some states so that the LR(1) follow sets -** can be computed later. -*/ -PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */ -void FindStates(lemp) -struct lemon *lemp; -{ - struct symbol *sp; - struct rule *rp; - - Configlist_init(); - - /* Find the start symbol */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ){ - ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); - lemp->errorcnt++; - sp = lemp->rule->lhs; - } - }else{ - sp = lemp->rule->lhs; - } - - /* Make sure the start symbol doesn't occur on the right-hand side of - ** any rule. Report an error if it does. (YACC would generate a new - ** start symbol in this case.) */ - for(rp=lemp->rule; rp; rp=rp->next){ - int i; - for(i=0; i<rp->nrhs; i++){ - if( rp->rhs[i]==sp ){ - ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); - lemp->errorcnt++; - } - } - } - - /* The basis configuration set for the first state - ** is all rules which have the start symbol as their - ** left-hand side */ - for(rp=sp->rule; rp; rp=rp->nextlhs){ - struct config *newcfp; - newcfp = Configlist_addbasis(rp,0); - SetAdd(newcfp->fws,0); - } - - /* Compute the first state. All other states will be - ** computed automatically during the computation of the first one. - ** The returned pointer to the first state is not used. */ - (void)getstate(lemp); - return; -} - -/* Return a pointer to a state which is described by the configuration -** list which has been built from calls to Configlist_add. -*/ -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */ -PRIVATE struct state *getstate(lemp) -struct lemon *lemp; -{ - struct config *cfp, *bp; - struct state *stp; - - /* Extract the sorted basis of the new state. The basis was constructed - ** by prior calls to "Configlist_addbasis()". */ - Configlist_sortbasis(); - bp = Configlist_basis(); - - /* Get a state with the same basis */ - stp = State_find(bp); - if( stp ){ - /* A state with the same basis already exists! Copy all the follow-set - ** propagation links from the state under construction into the - ** preexisting state, then return a pointer to the preexisting state */ - struct config *x, *y; - for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ - Plink_copy(&y->bplp,x->bplp); - Plink_delete(x->fplp); - x->fplp = x->bplp = 0; - } - cfp = Configlist_return(); - Configlist_eat(cfp); - }else{ - /* This really is a new state. Construct all the details */ - Configlist_closure(lemp); /* Compute the configuration closure */ - Configlist_sort(); /* Sort the configuration closure */ - cfp = Configlist_return(); /* Get a pointer to the config list */ - stp = State_new(); /* A new state structure */ - MemoryCheck(stp); - stp->bp = bp; /* Remember the configuration basis */ - stp->cfp = cfp; /* Remember the configuration closure */ - stp->index = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ - State_insert(stp,stp->bp); /* Add to the state table */ - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; -} - -/* Construct all successor states to the given state. A "successor" -** state is any state which can be reached by a shift action. -*/ -PRIVATE void buildshifts(lemp,stp) -struct lemon *lemp; -struct state *stp; /* The state from which successors are computed */ -{ - struct config *cfp; /* For looping thru the config closure of "stp" */ - struct config *bcfp; /* For the inner loop on config closure of "stp" */ - struct config *new; /* */ - struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ - struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ - struct state *newstp; /* A pointer to a successor state */ - - /* Each configuration becomes complete after it contibutes to a successor - ** state. Initially, all configurations are incomplete */ - for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; - - /* Loop through all configurations of the state "stp" */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ - if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ - Configlist_reset(); /* Reset the new config set */ - sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ - - /* For every configuration in the state "stp" which has the symbol "sp" - ** following its dot, add the same configuration to the basis set under - ** construction but with the dot shifted one symbol to the right. */ - for(bcfp=cfp; bcfp; bcfp=bcfp->next){ - if( bcfp->status==COMPLETE ) continue; /* Already used */ - if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ - bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( bsp!=sp ) continue; /* Must be same as for "cfp" */ - bcfp->status = COMPLETE; /* Mark this config as used */ - new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); - Plink_add(&new->bplp,bcfp); - } - - /* Get a pointer to the state described by the basis configuration set - ** constructed in the preceding loop */ - newstp = getstate(lemp); - - /* The state "newstp" is reached from the state "stp" by a shift action - ** on the symbol "sp" */ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); - } -} - -/* -** Construct the propagation links -*/ -void FindLinks(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp, *other; - struct state *stp; - struct plink *plp; - - /* Housekeeping detail: - ** Add to every propagate link a pointer back to the state to - ** which the link is attached. */ - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } - } - - /* Convert all backlinks into forward links. Only the forward - ** links are used in the follow-set computation. */ - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } - } - } -} - -/* Compute all followsets. -** -** A followset is the set of all symbols which can come immediately -** after a configuration. -*/ -void FindFollowSets(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp; - struct plink *plp; - int progress; - int change; - - for(i=0; i<lemp->nstate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } - } - - do{ - progress = 0; - for(i=0; i<lemp->nstate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } - } - cfp->status = COMPLETE; - } - } - }while( progress ); -} - -static int resolve_conflict(); - -/* Compute the reduce actions, and resolve conflicts. -*/ -void FindActions(lemp) -struct lemon *lemp; -{ - int i,j; - struct config *cfp; - struct state *stp; - struct symbol *sp; - struct rule *rp; - - /* Add all of the reduce actions - ** A reduce action is added for each element of the followset of - ** a configuration which has its dot at the extreme right. - */ - for(i=0; i<lemp->nstate; i++){ /* Loop over all states */ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; j<lemp->nterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } - } - } - } - } - - /* Add the accepting token */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; - }else{ - sp = lemp->rule->lhs; - } - /* Add to the first state (which is always the starting state of the - ** finite state machine) an action to ACCEPT if the lookahead is the - ** start nonterminal. */ - Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); - - /* Resolve conflicts */ - for(i=0; i<lemp->nstate; i++){ - struct action *ap, *nap; - struct state *stp; - stp = lemp->sorted[i]; - assert( stp->ap ); - stp->ap = Action_sort(stp->ap); - for(ap=stp->ap; ap && ap->next; ap=ap->next){ - for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ - /* The two actions "ap" and "nap" have the same lookahead. - ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); - } - } - } - - /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE; - for(i=0; i<lemp->nstate; i++){ - struct action *ap; - for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE; - } - } - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->canReduce ) continue; - ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); - lemp->errorcnt++; - } -} - -/* Resolve a conflict between the two given actions. If the -** conflict can't be resolve, return non-zero. -** -** NO LONGER TRUE: -** To resolve a conflict, first look to see if either action -** is on an error rule. In that case, take the action which -** is not associated with the error rule. If neither or both -** actions are associated with an error rule, then try to -** use precedence to resolve the conflict. -** -** If either action is a SHIFT, then it must be apx. This -** function won't work if apx->type==REDUCE and apy->type==SHIFT. -*/ -static int resolve_conflict(apx,apy,errsym) -struct action *apx; -struct action *apy; -struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ -{ - struct symbol *spx, *spy; - int errcnt = 0; - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; - spy = apy->x.rp->precsym; - if( spy==0 || spx->prec<0 || spy->prec<0 ){ - /* Not enough precedence information. */ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ - apy->type = RD_RESOLVED; - }else if( spx->prec<spy->prec ){ - apx->type = SH_RESOLVED; - }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ - apy->type = RD_RESOLVED; /* associativity */ - }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ - apx->type = SH_RESOLVED; - }else{ - assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = CONFLICT; - errcnt++; - } - }else if( apx->type==REDUCE && apy->type==REDUCE ){ - spx = apx->x.rp->precsym; - spy = apy->x.rp->precsym; - if( spx==0 || spy==0 || spx->prec<0 || - spy->prec<0 || spx->prec==spy->prec ){ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ - apy->type = RD_RESOLVED; - }else if( spx->prec<spy->prec ){ - apx->type = RD_RESOLVED; - } - }else{ - assert( - apx->type==SH_RESOLVED || - apx->type==RD_RESOLVED || - apx->type==CONFLICT || - apy->type==SH_RESOLVED || - apy->type==RD_RESOLVED || - apy->type==CONFLICT - ); - /* The REDUCE/SHIFT case cannot happen because SHIFTs come before - ** REDUCEs on the list. If we reach this point it must be because - ** the parser conflict had already been resolved. */ - } - return errcnt; -} -/********************* From the file "configlist.c" *************************/ -/* -** Routines to processing a configuration list and building a state -** in the LEMON parser generator. -*/ - -static struct config *freelist = 0; /* List of free configurations */ -static struct config *current = 0; /* Top of list of configurations */ -static struct config **currentend = 0; /* Last on list of configs */ -static struct config *basis = 0; /* Top of list of basis configs */ -static struct config **basisend = 0; /* End of list of basis configs */ - -/* Return a pointer to a new configuration */ -PRIVATE struct config *newconfig(){ - struct config *new; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)malloc( sizeof(struct config)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; - freelist[amt-1].next = 0; - } - new = freelist; - freelist = freelist->next; - return new; -} - -/* The configuration "old" is no longer used */ -PRIVATE void deleteconfig(old) -struct config *old; -{ - old->next = freelist; - freelist = old; -} - -/* Initialized the configuration list builder */ -void Configlist_init(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_init(); - return; -} - -/* Initialized the configuration list builder */ -void Configlist_reset(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_clear(0); - return; -} - -/* Add another configuration to the configuration list */ -struct config *Configlist_add(rp,dot) -struct rule *rp; /* The rule */ -int dot; /* Index into the RHS of the rule where the dot goes */ -{ - struct config *cfp, model; - - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - Configtable_insert(cfp); - } - return cfp; -} - -/* Add a basis configuration to the configuration list */ -struct config *Configlist_addbasis(rp,dot) -struct rule *rp; -int dot; -{ - struct config *cfp, model; - - assert( basisend!=0 ); - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - *basisend = cfp; - basisend = &cfp->bp; - Configtable_insert(cfp); - } - return cfp; -} - -/* Compute the closure of the configuration list */ -void Configlist_closure(lemp) -struct lemon *lemp; -{ - struct config *cfp, *newcfp; - struct rule *rp, *newrp; - struct symbol *sp, *xsp; - int i, dot; - - assert( currentend!=0 ); - for(cfp=current; cfp; cfp=cfp->next){ - rp = cfp->rp; - dot = cfp->dot; - if( dot>=rp->nrhs ) continue; - sp = rp->rhs[dot]; - if( sp->type==NONTERMINAL ){ - if( sp->rule==0 && sp!=lemp->errsym ){ - ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", - sp->name); - lemp->errorcnt++; - } - for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ - newcfp = Configlist_add(newrp,0); - for(i=dot+1; i<rp->nrhs; i++){ - xsp = rp->rhs[i]; - if( xsp->type==TERMINAL ){ - SetAdd(newcfp->fws,xsp->index); - break; - }else{ - SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==B_FALSE ) break; - } - } - if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); - } - } - } - return; -} - -/* Sort the configuration list */ -void Configlist_sort(){ - current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); - currentend = 0; - return; -} - -/* Sort the basis configuration list */ -void Configlist_sortbasis(){ - basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); - basisend = 0; - return; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_return(){ - struct config *old; - old = current; - current = 0; - currentend = 0; - return old; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_basis(){ - struct config *old; - old = basis; - basis = 0; - basisend = 0; - return old; -} - -/* Free all elements of the given configuration list */ -void Configlist_eat(cfp) -struct config *cfp; -{ - struct config *nextcfp; - for(; cfp; cfp=nextcfp){ - nextcfp = cfp->next; - assert( cfp->fplp==0 ); - assert( cfp->bplp==0 ); - if( cfp->fws ) SetFree(cfp->fws); - deleteconfig(cfp); - } - return; -} -/***************** From the file "error.c" *********************************/ -/* -** Code for printing error message. -*/ - -/* Find a good place to break "msg" so that its length is at least "min" -** but no more than "max". Make the point as close to max as possible. -*/ -static int findbreak(msg,min,max) -char *msg; -int min; -int max; -{ - int i,spot; - char c; - for(i=spot=min; i<=max; i++){ - c = msg[i]; - if( c=='\t' ) msg[i] = ' '; - if( c=='\n' ){ msg[i] = ' '; spot = i; break; } - if( c==0 ){ spot = i; break; } - if( c=='-' && i<max-1 ) spot = i+1; - if( c==' ' ) spot = i; - } - return spot; -} - -/* -** The error message is split across multiple lines if necessary. The -** splits occur at a space, if there is a space available near the end -** of the line. -*/ -#define ERRMSGSIZE 10000 /* Hope this is big enough. No way to error check */ -#define LINEWIDTH 79 /* Max width of any output line */ -#define PREFIXLIMIT 30 /* Max width of the prefix on each line */ -void ErrorMsg(const char *filename, int lineno, const char *format, ...){ - char errmsg[ERRMSGSIZE]; - char prefix[PREFIXLIMIT+10]; - int errmsgsize; - int prefixsize; - int availablewidth; - va_list ap; - int end, restart, base; - - va_start(ap, format); - /* Prepare a prefix to be prepended to every output line */ - if( lineno>0 ){ - sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno); - }else{ - sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename); - } - prefixsize = strlen(prefix); - availablewidth = LINEWIDTH - prefixsize; - - /* Generate the error message */ - vsprintf(errmsg,format,ap); - va_end(ap); - errmsgsize = strlen(errmsg); - /* Remove trailing '\n's from the error message. */ - while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){ - errmsg[--errmsgsize] = 0; - } - - /* Print the error message */ - base = 0; - while( errmsg[base]!=0 ){ - end = restart = findbreak(&errmsg[base],0,availablewidth); - restart += base; - while( errmsg[restart]==' ' ) restart++; - fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]); - base = restart; - } -} -/**************** From the file "main.c" ************************************/ -/* -** Main program file for the LEMON parser generator. -*/ - -/* Report an out-of-memory condition and abort. This function -** is used mostly by the "MemoryCheck" macro in struct.h -*/ -void memory_error(){ - fprintf(stderr,"Out of memory. Aborting...\n"); - exit(1); -} - -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ - -/* This routine is called with the argument to each -D command-line option. -** Add the macro defined to the azDefine array. -*/ -static void handle_D_option(char *z){ - char **paz; - nDefine++; - azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine); - if( azDefine==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - paz = &azDefine[nDefine-1]; - *paz = malloc( strlen(z)+1 ); - if( *paz==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - strcpy(*paz, z); - for(z=*paz; *z && *z!='='; z++){} - *z = 0; -} - - -/* The main program. Parse the command line and do it... */ -int main(argc,argv) -int argc; -char **argv; -{ - static int version = 0; - static int rpflag = 0; - static int basisflag = 0; - static int compress = 0; - static int quiet = 0; - static int statistics = 0; - static int mhflag = 0; - static struct s_options options[] = { - {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, - {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, - {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, - {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, - {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"}, - {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, - {OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output."}, - {OPT_FLAG, "x", (char*)&version, "Print the version number."}, - {OPT_FLAG,0,0,0} - }; - int i; - struct lemon lem; - - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); - exit(0); - } - if( OptNArgs()!=1 ){ - fprintf(stderr,"Exactly one filename argument is required.\n"); - exit(1); - } - lem.errorcnt = 0; - - /* Initialize the machine */ - Strsafe_init(); - Symbol_init(); - State_init(); - lem.argv0 = argv[0]; - lem.filename = OptArg(0); - lem.basisflag = basisflag; - lem.has_fallback = 0; - lem.nconflict = 0; - lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0; - lem.vartype = 0; - lem.stacksize = 0; - lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest = - lem.tokenprefix = lem.outname = lem.extracode = 0; - lem.vardest = 0; - lem.tablesize = 0; - Symbol_new("$"); - lem.errsym = Symbol_new("error"); - - /* Parse the input file */ - Parse(&lem); - if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.rule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); - } - - /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); - Symbol_new("{default}"); - lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), - (int(*)())Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); - lem.nterminal = i; - - /* Generate a reprint of the grammar, if requested on the command line */ - if( rpflag ){ - Reprint(&lem); - }else{ - /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal); - - /* Find the precedence for every production rule (that has one) */ - FindRulePrecedences(&lem); - - /* Compute the lambda-nonterminals and the first-sets for every - ** nonterminal */ - FindFirstSets(&lem); - - /* Compute all LR(0) states. Also record follow-set propagation - ** links so that the follow-set can be computed later */ - lem.nstate = 0; - FindStates(&lem); - lem.sorted = State_arrayof(); - - /* Tie up loose ends on the propagation links */ - FindLinks(&lem); - - /* Compute the follow set of every reducible configuration */ - FindFollowSets(&lem); - - /* Compute the action tables */ - FindActions(&lem); - - /* Compress the action tables */ - if( compress==0 ) CompressTables(&lem); - - /* Generate a report of the parser generated. (the "y.output" file) */ - if( !quiet ) ReportOutput(&lem); - - /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); - - /* Produce a header file for use by the scanner. (This step is - ** omitted if the "-m" option is used because makeheaders will - ** generate the file for us.) */ - if( !mhflag ) ReportHeader(&lem); - } - if( statistics ){ - printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", - lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); - printf(" %d states, %d parser table entries, %d conflicts\n", - lem.nstate, lem.tablesize, lem.nconflict); - } - if( lem.nconflict ){ - fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); - } - exit(lem.errorcnt + lem.nconflict); - return (lem.errorcnt + lem.nconflict); -} -/******************** From the file "msort.c" *******************************/ -/* -** A generic merge-sort program. -** -** USAGE: -** Let "ptr" be a pointer to some structure which is at the head of -** a null-terminated list. Then to sort the list call: -** -** ptr = msort(ptr,&(ptr->next),cmpfnc); -** -** In the above, "cmpfnc" is a pointer to a function which compares -** two instances of the structure and returns an integer, as in -** strcmp. The second argument is a pointer to the pointer to the -** second element of the linked list. This address is used to compute -** the offset to the "next" field within the structure. The offset to -** the "next" field must be constant for all structures in the list. -** -** The function returns a new pointer which is the head of the list -** after sorting. -** -** ALGORITHM: -** Merge-sort. -*/ - -/* -** Return a pointer to the next structure in the linked list. -*/ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) - -/* -** Inputs: -** a: A sorted, null-terminated linked list. (May be null). -** b: A sorted, null-terminated linked list. (May be null). -** cmp: A pointer to the comparison function. -** offset: Offset in the structure to the "next" field. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** of both a and b. -** -** Side effects: -** The "next" pointers for elements in the lists a and b are -** changed. -*/ -static char *merge(a,b,cmp,offset) -char *a; -char *b; -int (*cmp)(); -int offset; -{ - char *ptr, *head; - - if( a==0 ){ - head = b; - }else if( b==0 ){ - head = a; - }else{ - if( (*cmp)(a,b)<0 ){ - ptr = a; - a = NEXT(a); - }else{ - ptr = b; - b = NEXT(b); - } - head = ptr; - while( a && b ){ - if( (*cmp)(a,b)<0 ){ - NEXT(ptr) = a; - ptr = a; - a = NEXT(a); - }else{ - NEXT(ptr) = b; - ptr = b; - b = NEXT(b); - } - } - if( a ) NEXT(ptr) = a; - else NEXT(ptr) = b; - } - return head; -} - -/* -** Inputs: -** list: Pointer to a singly-linked list of structures. -** next: Pointer to pointer to the second element of the list. -** cmp: A comparison function. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** orginally in list. -** -** Side effects: -** The "next" pointers for elements in list are changed. -*/ -#define LISTSIZE 30 -char *msort(list,next,cmp) -char *list; -char **next; -int (*cmp)(); -{ - unsigned long offset; - char *ep; - char *set[LISTSIZE]; - int i; - offset = (unsigned long)next - (unsigned long)list; - for(i=0; i<LISTSIZE; i++) set[i] = 0; - while( list ){ - ep = list; - list = NEXT(list); - NEXT(ep) = 0; - for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){ - ep = merge(ep,set[i],cmp,offset); - set[i] = 0; - } - set[i] = ep; - } - ep = 0; - for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset); - return ep; -} -/************************ From the file "option.c" **************************/ -static char **argv; -static struct s_options *op; -static FILE *errstream; - -#define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0) - -/* -** Print the command line with a carrot pointing to the k-th character -** of the n-th field. -*/ -static void errline(n,k,err) -int n; -int k; -FILE *err; -{ - int spcnt, i; - spcnt = 0; - if( argv[0] ) fprintf(err,"%s",argv[0]); - spcnt = strlen(argv[0]) + 1; - for(i=1; i<n && argv[i]; i++){ - fprintf(err," %s",argv[i]); - spcnt += strlen(argv[i]+1); - } - spcnt += k; - for(; argv[i]; i++) fprintf(err," %s",argv[i]); - if( spcnt<20 ){ - fprintf(err,"\n%*s^-- here\n",spcnt,""); - }else{ - fprintf(err,"\n%*shere --^\n",spcnt-7,""); - } -} - -/* -** Return the index of the N-th non-switch argument. Return -1 -** if N is out of range. -*/ -static int argindex(n) -int n; -{ - int i; - int dashdash = 0; - if( argv!=0 && *argv!=0 ){ - for(i=1; argv[i]; i++){ - if( dashdash || !ISOPT(argv[i]) ){ - if( n==0 ) return i; - n--; - } - if( strcmp(argv[i],"--")==0 ) dashdash = 1; - } - } - return -1; -} - -static char emsg[] = "Command line syntax error: "; - -/* -** Process a flag command line argument. -*/ -static int handleflags(i,err) -int i; -FILE *err; -{ - int v; - int errcnt = 0; - int j; - for(j=0; op[j].label; j++){ - if( strncmp(&argv[i][1],op[j].label,strlen(op[j].label))==0 ) break; - } - v = argv[i][0]=='-' ? 1 : 0; - if( op[j].label==0 ){ - if( err ){ - fprintf(err,"%sundefined option.\n",emsg); - errline(i,1,err); - } - errcnt++; - }else if( op[j].type==OPT_FLAG ){ - *((int*)op[j].arg) = v; - }else if( op[j].type==OPT_FFLAG ){ - (*(void(*)())(op[j].arg))(v); - }else if( op[j].type==OPT_FSTR ){ - (*(void(*)())(op[j].arg))(&argv[i][2]); - }else{ - if( err ){ - fprintf(err,"%smissing argument on switch.\n",emsg); - errline(i,1,err); - } - errcnt++; - } - return errcnt; -} - -/* -** Process a command line switch which has an argument. -*/ -static int handleswitch(i,err) -int i; -FILE *err; -{ - int lv = 0; - double dv = 0.0; - char *sv = 0, *end; - char *cp; - int j; - int errcnt = 0; - cp = strchr(argv[i],'='); - *cp = 0; - for(j=0; op[j].label; j++){ - if( strcmp(argv[i],op[j].label)==0 ) break; - } - *cp = '='; - if( op[j].label==0 ){ - if( err ){ - fprintf(err,"%sundefined option.\n",emsg); - errline(i,0,err); - } - errcnt++; - }else{ - cp++; - switch( op[j].type ){ - case OPT_FLAG: - case OPT_FFLAG: - if( err ){ - fprintf(err,"%soption requires an argument.\n",emsg); - errline(i,0,err); - } - errcnt++; - break; - case OPT_DBL: - case OPT_FDBL: - dv = strtod(cp,&end); - if( *end ){ - if( err ){ - fprintf(err,"%sillegal character in floating-point argument.\n",emsg); - errline(i,((unsigned long)end)-(unsigned long)argv[i],err); - } - errcnt++; - } - break; - case OPT_INT: - case OPT_FINT: - lv = strtol(cp,&end,0); - if( *end ){ - if( err ){ - fprintf(err,"%sillegal character in integer argument.\n",emsg); - errline(i,((unsigned long)end)-(unsigned long)argv[i],err); - } - errcnt++; - } - break; - case OPT_STR: - case OPT_FSTR: - sv = cp; - break; - } - switch( op[j].type ){ - case OPT_FLAG: - case OPT_FFLAG: - break; - case OPT_DBL: - *(double*)(op[j].arg) = dv; - break; - case OPT_FDBL: - (*(void(*)())(op[j].arg))(dv); - break; - case OPT_INT: - *(int*)(op[j].arg) = lv; - break; - case OPT_FINT: - (*(void(*)())(op[j].arg))((int)lv); - break; - case OPT_STR: - *(char**)(op[j].arg) = sv; - break; - case OPT_FSTR: - (*(void(*)())(op[j].arg))(sv); - break; - } - } - return errcnt; -} - -int OptInit(a,o,err) -char **a; -struct s_options *o; -FILE *err; -{ - int errcnt = 0; - argv = a; - op = o; - errstream = err; - if( argv && *argv && op ){ - int i; - for(i=1; argv[i]; i++){ - if( argv[i][0]=='+' || argv[i][0]=='-' ){ - errcnt += handleflags(i,err); - }else if( strchr(argv[i],'=') ){ - errcnt += handleswitch(i,err); - } - } - } - if( errcnt>0 ){ - fprintf(err,"Valid command line options for \"%s\" are:\n",*a); - OptPrint(); - exit(1); - } - return 0; -} - -int OptNArgs(){ - int cnt = 0; - int dashdash = 0; - int i; - if( argv!=0 && argv[0]!=0 ){ - for(i=1; argv[i]; i++){ - if( dashdash || !ISOPT(argv[i]) ) cnt++; - if( strcmp(argv[i],"--")==0 ) dashdash = 1; - } - } - return cnt; -} - -char *OptArg(n) -int n; -{ - int i; - i = argindex(n); - return i>=0 ? argv[i] : 0; -} - -void OptErr(n) -int n; -{ - int i; - i = argindex(n); - if( i>=0 ) errline(i,0,errstream); -} - -void OptPrint(){ - int i; - int max, len; - max = 0; - for(i=0; op[i].label; i++){ - len = strlen(op[i].label) + 1; - switch( op[i].type ){ - case OPT_FLAG: - case OPT_FFLAG: - break; - case OPT_INT: - case OPT_FINT: - len += 9; /* length of "<integer>" */ - break; - case OPT_DBL: - case OPT_FDBL: - len += 6; /* length of "<real>" */ - break; - case OPT_STR: - case OPT_FSTR: - len += 8; /* length of "<string>" */ - break; - } - if( len>max ) max = len; - } - for(i=0; op[i].label; i++){ - switch( op[i].type ){ - case OPT_FLAG: - case OPT_FFLAG: - fprintf(errstream," -%-*s %s\n",max,op[i].label,op[i].message); - break; - case OPT_INT: - case OPT_FINT: - fprintf(errstream," %s=<integer>%*s %s\n",op[i].label, - (int)(max-strlen(op[i].label)-9),"",op[i].message); - break; - case OPT_DBL: - case OPT_FDBL: - fprintf(errstream," %s=<real>%*s %s\n",op[i].label, - (int)(max-strlen(op[i].label)-6),"",op[i].message); - break; - case OPT_STR: - case OPT_FSTR: - fprintf(errstream," %s=<string>%*s %s\n",op[i].label, - (int)(max-strlen(op[i].label)-8),"",op[i].message); - break; - } - } -} -/*********************** From the file "parse.c" ****************************/ -/* -** Input file parser for the LEMON parser generator. -*/ - -/* The state of the parser */ -struct pstate { - char *filename; /* Name of the input file */ - int tokenlineno; /* Linenumber at which current token starts */ - int errorcnt; /* Number of errors so far */ - char *tokenstart; /* Text of current token */ - struct lemon *gp; /* Global state vector */ - enum e_state { - INITIALIZE, - WAITING_FOR_DECL_OR_RULE, - WAITING_FOR_DECL_KEYWORD, - WAITING_FOR_DECL_ARG, - WAITING_FOR_PRECEDENCE_SYMBOL, - WAITING_FOR_ARROW, - IN_RHS, - LHS_ALIAS_1, - LHS_ALIAS_2, - LHS_ALIAS_3, - RHS_ALIAS_1, - RHS_ALIAS_2, - PRECEDENCE_MARK_1, - PRECEDENCE_MARK_2, - RESYNC_AFTER_RULE_ERROR, - RESYNC_AFTER_DECL_ERROR, - WAITING_FOR_DESTRUCTOR_SYMBOL, - WAITING_FOR_DATATYPE_SYMBOL, - WAITING_FOR_FALLBACK_ID - } state; /* The state of the parser */ - struct symbol *fallback; /* The fallback token */ - struct symbol *lhs; /* Left-hand side of current rule */ - char *lhsalias; /* Alias for the LHS */ - int nrhs; /* Number of right-hand side symbols seen */ - struct symbol *rhs[MAXRHS]; /* RHS symbols */ - char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */ - struct rule *prevrule; /* Previous rule parsed */ - char *declkeyword; /* Keyword of a declaration */ - char **declargslot; /* Where the declaration argument should be put */ - int *decllnslot; /* Where the declaration linenumber is put */ - enum e_assoc declassoc; /* Assign this association to decl arguments */ - int preccounter; /* Assign this precedence to decl arguments */ - struct rule *firstrule; /* Pointer to first rule in the grammar */ - struct rule *lastrule; /* Pointer to the most recently parsed rule */ -}; - -/* Parse a single token */ -static void parseonetoken(psp) -struct pstate *psp; -{ - char *x; - x = Strsafe(psp->tokenstart); /* Save the token permanently */ -#if 0 - printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno, - x,psp->state); -#endif - switch( psp->state ){ - case INITIALIZE: - psp->prevrule = 0; - psp->preccounter = 0; - psp->firstrule = psp->lastrule = 0; - psp->gp->nrule = 0; - /* Fall thru to next case */ - case WAITING_FOR_DECL_OR_RULE: - if( x[0]=='%' ){ - psp->state = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ - psp->lhs = Symbol_new(x); - psp->nrhs = 0; - psp->lhsalias = 0; - psp->state = WAITING_FOR_ARROW; - }else if( x[0]=='{' ){ - if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"There is not prior rule opon which to attach the code \ -fragment which begins on this line."); - psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->line = psp->tokenlineno; - psp->prevrule->code = &x[1]; - } - }else if( x[0]=='[' ){ - psp->state = PRECEDENCE_MARK_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Token \"%s\" should be either \"%%\" or a nonterminal name.", - x); - psp->errorcnt++; - } - break; - case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The precedence symbol must be a terminal."); - psp->errorcnt++; - }else if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "There is no prior rule to assign precedence \"[%s]\".",x); - psp->errorcnt++; - }else if( psp->prevrule->precsym!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->precsym = Symbol_new(x); - } - psp->state = PRECEDENCE_MARK_2; - break; - case PRECEDENCE_MARK_2: - if( x[0]!=']' ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"]\" on precedence mark."); - psp->errorcnt++; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - break; - case WAITING_FOR_ARROW: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else if( x[0]=='(' ){ - psp->state = LHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Expected to see a \":\" following the LHS symbol \"%s\".", - psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->lhsalias = x; - psp->state = LHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the LHS \"%s\"\n", - x,psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = LHS_ALIAS_3; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_3: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"->\" following: \"%s(%s)\".", - psp->lhs->name,psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case IN_RHS: - if( x[0]=='.' ){ - struct rule *rp; - rp = (struct rule *)malloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); - if( rp==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't allocate enough memory for this rule."); - psp->errorcnt++; - psp->prevrule = 0; - }else{ - int i; - rp->ruleline = psp->tokenlineno; - rp->rhs = (struct symbol**)&rp[1]; - rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]); - for(i=0; i<psp->nrhs; i++){ - rp->rhs[i] = psp->rhs[i]; - rp->rhsalias[i] = psp->alias[i]; - } - rp->lhs = psp->lhs; - rp->lhsalias = psp->lhsalias; - rp->nrhs = psp->nrhs; - rp->code = 0; - rp->precsym = 0; - rp->index = psp->gp->nrule++; - rp->nextlhs = rp->lhs->rule; - rp->lhs->rule = rp; - rp->next = 0; - if( psp->firstrule==0 ){ - psp->firstrule = psp->lastrule = rp; - }else{ - psp->lastrule->next = rp; - psp->lastrule = rp; - } - psp->prevrule = rp; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ - if( psp->nrhs>=MAXRHS ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbol on RHS or rule beginning at \"%s\".", - x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - }else{ - psp->rhs[psp->nrhs] = Symbol_new(x); - psp->alias[psp->nrhs] = 0; - psp->nrhs++; - } - }else if( x[0]=='(' && psp->nrhs>0 ){ - psp->state = RHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal character on RHS of rule: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->alias[psp->nrhs-1] = x; - psp->state = RHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", - x,psp->rhs[psp->nrhs-1]->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ - psp->declkeyword = x; - psp->declargslot = 0; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - if( strcmp(x,"name")==0 ){ - psp->declargslot = &(psp->gp->name); - }else if( strcmp(x,"include")==0 ){ - psp->declargslot = &(psp->gp->include); - psp->decllnslot = &psp->gp->includeln; - }else if( strcmp(x,"code")==0 ){ - psp->declargslot = &(psp->gp->extracode); - psp->decllnslot = &psp->gp->extracodeln; - }else if( strcmp(x,"token_destructor")==0 ){ - psp->declargslot = &psp->gp->tokendest; - psp->decllnslot = &psp->gp->tokendestln; - }else if( strcmp(x,"default_destructor")==0 ){ - psp->declargslot = &psp->gp->vardest; - psp->decllnslot = &psp->gp->vardestln; - }else if( strcmp(x,"token_prefix")==0 ){ - psp->declargslot = &psp->gp->tokenprefix; - }else if( strcmp(x,"syntax_error")==0 ){ - psp->declargslot = &(psp->gp->error); - psp->decllnslot = &psp->gp->errorln; - }else if( strcmp(x,"parse_accept")==0 ){ - psp->declargslot = &(psp->gp->accept); - psp->decllnslot = &psp->gp->acceptln; - }else if( strcmp(x,"parse_failure")==0 ){ - psp->declargslot = &(psp->gp->failure); - psp->decllnslot = &psp->gp->failureln; - }else if( strcmp(x,"stack_overflow")==0 ){ - psp->declargslot = &(psp->gp->overflow); - psp->decllnslot = &psp->gp->overflowln; - }else if( strcmp(x,"extra_argument")==0 ){ - psp->declargslot = &(psp->gp->arg); - }else if( strcmp(x,"token_type")==0 ){ - psp->declargslot = &(psp->gp->tokentype); - }else if( strcmp(x,"default_type")==0 ){ - psp->declargslot = &(psp->gp->vartype); - }else if( strcmp(x,"stack_size")==0 ){ - psp->declargslot = &(psp->gp->stacksize); - }else if( strcmp(x,"start_symbol")==0 ){ - psp->declargslot = &(psp->gp->start); - }else if( strcmp(x,"left")==0 ){ - psp->preccounter++; - psp->declassoc = LEFT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"right")==0 ){ - psp->preccounter++; - psp->declassoc = RIGHT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"nonassoc")==0 ){ - psp->preccounter++; - psp->declassoc = NONE; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"destructor")==0 ){ - psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; - }else if( strcmp(x,"type")==0 ){ - psp->state = WAITING_FOR_DATATYPE_SYMBOL; - }else if( strcmp(x,"fallback")==0 ){ - psp->fallback = 0; - psp->state = WAITING_FOR_FALLBACK_ID; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Unknown declaration keyword: \"%%%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal declaration keyword: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->destructor; - psp->decllnslot = &sp->destructorln; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->datatype; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_PRECEDENCE_SYMBOL: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ - struct symbol *sp; - sp = Symbol_new(x); - if( sp->prec>=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol \"%s\" has already be given a precedence.",x); - psp->errorcnt++; - }else{ - sp->prec = psp->preccounter; - sp->assoc = psp->declassoc; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't assign a precedence to \"%s\".",x); - psp->errorcnt++; - } - break; - case WAITING_FOR_DECL_ARG: - if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){ - if( *(psp->declargslot)!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The argument \"%s\" to declaration \"%%%s\" is not the first.", - x[0]=='\"' ? &x[1] : x,psp->declkeyword); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - *(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x; - if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno; - psp->state = WAITING_FOR_DECL_OR_RULE; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal argument to %%%s: %s",psp->declkeyword,x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_FALLBACK_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%fallback argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->fallback==0 ){ - psp->fallback = sp; - }else if( sp->fallback ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "More than one fallback assigned to token %s", x); - psp->errorcnt++; - }else{ - sp->fallback = psp->fallback; - psp->gp->has_fallback = 1; - } - } - break; - case RESYNC_AFTER_RULE_ERROR: -/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; -** break; */ - case RESYNC_AFTER_DECL_ERROR: - if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; - if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; - break; - } -} - -/* Run the proprocessor over the input file text. The global variables -** azDefine[0] through azDefine[nDefine-1] contains the names of all defined -** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and -** comments them out. Text in between is also commented out as appropriate. -*/ -static preprocess_input(char *z){ - int i, j, k, n; - int exclude = 0; - int start; - int lineno = 1; - int start_lineno; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) lineno++; - if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ - if( exclude ){ - exclude--; - if( exclude==0 ){ - for(j=start; j<i; j++) if( z[j]!='\n' ) z[j] = ' '; - } - } - for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; - }else if( (strncmp(&z[i],"%ifdef",6)==0 && isspace(z[i+6])) - || (strncmp(&z[i],"%ifndef",7)==0 && isspace(z[i+7])) ){ - if( exclude ){ - exclude++; - }else{ - for(j=i+7; isspace(z[j]); j++){} - for(n=0; z[j+n] && !isspace(z[j+n]); n++){} - exclude = 1; - for(k=0; k<nDefine; k++){ - if( strncmp(azDefine[k],&z[j],n)==0 && strlen(azDefine[k])==n ){ - exclude = 0; - break; - } - } - if( z[i+3]=='n' ) exclude = !exclude; - if( exclude ){ - start = i; - start_lineno = lineno; - } - } - for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; - } - } - if( exclude ){ - fprintf(stderr,"unterminated %%ifdef starting on line %d\n", start_lineno); - exit(1); - } -} - -/* In spite of its name, this function is really a scanner. It read -** in the entire input file (all at once) then tokenizes it. Each -** token is passed to the function "parseonetoken" which builds all -** the appropriate data structures in the global state vector "gp". -*/ -void Parse(gp) -struct lemon *gp; -{ - struct pstate ps; - FILE *fp; - char *filebuf; - int filesize; - int lineno; - int c; - char *cp, *nextcp; - int startline = 0; - - ps.gp = gp; - ps.filename = gp->filename; - ps.errorcnt = 0; - ps.state = INITIALIZE; - - /* Begin by reading the input file */ - fp = fopen(ps.filename,"rb"); - if( fp==0 ){ - ErrorMsg(ps.filename,0,"Can't open this file for reading."); - gp->errorcnt++; - return; - } - fseek(fp,0,2); - filesize = ftell(fp); - rewind(fp); - filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); - gp->errorcnt++; - return; - } - if( fread(filebuf,1,filesize,fp)!=filesize ){ - ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", - filesize); - free(filebuf); - gp->errorcnt++; - return; - } - fclose(fp); - filebuf[filesize] = 0; - - /* Make an initial pass through the file to handle %ifdef and %ifndef */ - preprocess_input(filebuf); - - /* Now scan the text of the input file */ - lineno = 1; - for(cp=filebuf; (c= *cp)!=0; ){ - if( c=='\n' ) lineno++; /* Keep track of the line number */ - if( isspace(c) ){ cp++; continue; } /* Skip all white space */ - if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ - cp+=2; - while( (c= *cp)!=0 && c!='\n' ) cp++; - continue; - } - if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ - cp+=2; - while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c ) cp++; - continue; - } - ps.tokenstart = cp; /* Mark the beginning of the token */ - ps.tokenlineno = lineno; /* Linenumber on which token begins */ - if( c=='\"' ){ /* String literals */ - cp++; - while( (c= *cp)!=0 && c!='\"' ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c==0 ){ - ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( c=='{' ){ /* A block of C code */ - int level; - cp++; - for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ - if( c=='\n' ) lineno++; - else if( c=='{' ) level++; - else if( c=='}' ) level--; - else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ - int prevc; - cp = &cp[2]; - prevc = 0; - while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ - if( c=='\n' ) lineno++; - prevc = c; - cp++; - } - }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ - cp = &cp[2]; - while( (c= *cp)!=0 && c!='\n' ) cp++; - if( c ) lineno++; - }else if( c=='\'' || c=='\"' ){ /* String a character literals */ - int startchar, prevc; - startchar = c; - prevc = 0; - for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ - if( c=='\n' ) lineno++; - if( prevc=='\\' ) prevc = 0; - else prevc = c; - } - } - } - if( c==0 ){ - ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( isalnum(c) ){ /* Identifiers */ - while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ - cp += 3; - nextcp = cp; - }else{ /* All other (one character) operators */ - cp++; - nextcp = cp; - } - c = *cp; - *cp = 0; /* Null terminate the token */ - parseonetoken(&ps); /* Parse the token */ - *cp = c; /* Restore the buffer */ - cp = nextcp; - } - free(filebuf); /* Release the buffer after parsing */ - gp->rule = ps.firstrule; - gp->errorcnt = ps.errorcnt; -} -/*************************** From the file "plink.c" *********************/ -/* -** Routines processing configuration follow-set propagation links -** in the LEMON parser generator. -*/ -static struct plink *plink_freelist = 0; - -/* Allocate a new plink */ -struct plink *Plink_new(){ - struct plink *new; - - if( plink_freelist==0 ){ - int i; - int amt = 100; - plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt ); - if( plink_freelist==0 ){ - fprintf(stderr, - "Unable to allocate memory for a new follow-set propagation link.\n"); - exit(1); - } - for(i=0; i<amt-1; i++) plink_freelist[i].next = &plink_freelist[i+1]; - plink_freelist[amt-1].next = 0; - } - new = plink_freelist; - plink_freelist = plink_freelist->next; - return new; -} - -/* Add a plink to a plink list */ -void Plink_add(plpp,cfp) -struct plink **plpp; -struct config *cfp; -{ - struct plink *new; - new = Plink_new(); - new->next = *plpp; - *plpp = new; - new->cfp = cfp; -} - -/* Transfer every plink on the list "from" to the list "to" */ -void Plink_copy(to,from) -struct plink **to; -struct plink *from; -{ - struct plink *nextpl; - while( from ){ - nextpl = from->next; - from->next = *to; - *to = from; - from = nextpl; - } -} - -/* Delete every plink on the list */ -void Plink_delete(plp) -struct plink *plp; -{ - struct plink *nextpl; - - while( plp ){ - nextpl = plp->next; - plp->next = plink_freelist; - plink_freelist = plp; - plp = nextpl; - } -} -/*********************** From the file "report.c" **************************/ -/* -** Procedures for generating reports and tables in the LEMON parser generator. -*/ - -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. -*/ -PRIVATE char *file_makename(lemp,suffix) -struct lemon *lemp; -char *suffix; -{ - char *name; - char *cp; - - name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 ); - if( name==0 ){ - fprintf(stderr,"Can't allocate space for a filename.\n"); - exit(1); - } - strcpy(name,lemp->filename); - cp = strrchr(name,'.'); - if( cp ) *cp = 0; - strcat(name,suffix); - return name; -} - -/* Open a file with a name based on the name of the input file, -** but with a different (specified) suffix, and return a pointer -** to the stream */ -PRIVATE FILE *file_open(lemp,suffix,mode) -struct lemon *lemp; -char *suffix; -char *mode; -{ - FILE *fp; - - if( lemp->outname ) free(lemp->outname); - lemp->outname = file_makename(lemp, suffix); - fp = fopen(lemp->outname,mode); - if( fp==0 && *mode=='w' ){ - fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); - lemp->errorcnt++; - return 0; - } - return fp; -} - -/* Duplicate the input file without comments and without actions -** on rules */ -void Reprint(lemp) -struct lemon *lemp; -{ - struct rule *rp; - struct symbol *sp; - int i, j, maxlen, len, ncolumns, skip; - printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); - maxlen = 10; - for(i=0; i<lemp->nsymbol; i++){ - sp = lemp->symbols[i]; - len = strlen(sp->name); - if( len>maxlen ) maxlen = len; - } - ncolumns = 76/(maxlen+5); - if( ncolumns<1 ) ncolumns = 1; - skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; - for(i=0; i<skip; i++){ - printf("//"); - for(j=i; j<lemp->nsymbol; j+=skip){ - sp = lemp->symbols[j]; - assert( sp->index==j ); - printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); - } - printf("\n"); - } - for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); -/* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; i<rp->nrhs; i++){ - printf(" %s",rp->rhs[i]->name); -/* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } - printf("."); - if( rp->precsym ) printf(" [%s]",rp->precsym->name); -/* if( rp->code ) printf("\n %s",rp->code); */ - printf("\n"); - } -} - -void ConfigPrint(fp,cfp) -FILE *fp; -struct config *cfp; -{ - struct rule *rp; - int i; - rp = cfp->rp; - fprintf(fp,"%s ::=",rp->lhs->name); - for(i=0; i<=rp->nrhs; i++){ - if( i==cfp->dot ) fprintf(fp," *"); - if( i==rp->nrhs ) break; - fprintf(fp," %s",rp->rhs[i]->name); - } -} - -/* #define TEST */ -#ifdef TEST -/* Print a set */ -PRIVATE void SetPrint(out,set,lemp) -FILE *out; -char *set; -struct lemon *lemp; -{ - int i; - char *spacer; - spacer = ""; - fprintf(out,"%12s[",""); - for(i=0; i<lemp->nterminal; i++){ - if( SetFind(set,i) ){ - fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); - spacer = " "; - } - } - fprintf(out,"]\n"); -} - -/* Print a plink chain */ -PRIVATE void PlinkPrint(out,plp,tag) -FILE *out; -struct plink *plp; -char *tag; -{ - while( plp ){ - fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->index); - ConfigPrint(out,plp->cfp); - fprintf(out,"\n"); - plp = plp->next; - } -} -#endif - -/* Print an action to the given file descriptor. Return FALSE if -** nothing was actually printed. -*/ -int PrintAction(struct action *ap, FILE *fp, int indent){ - int result = 1; - switch( ap->type ){ - case SHIFT: - fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->index); - break; - case REDUCE: - fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); - break; - case ACCEPT: - fprintf(fp,"%*s accept",indent,ap->sp->name); - break; - case ERROR: - fprintf(fp,"%*s error",indent,ap->sp->name); - break; - case CONFLICT: - fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); - break; - case SH_RESOLVED: - case RD_RESOLVED: - case NOT_USED: - result = 0; - break; - } - return result; -} - -/* Generate the "y.output" log file */ -void ReportOutput(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct config *cfp; - struct action *ap; - FILE *fp; - - fp = file_open(lemp,".out","wb"); - if( fp==0 ) return; - fprintf(fp," \b"); - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - fprintf(fp,"State %d:\n",stp->index); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#ifdef TEST - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - } - fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } - fprintf(fp,"\n"); - } - fclose(fp); - return; -} - -/* Search for the file "name" which is in the same directory as -** the exacutable */ -PRIVATE char *pathsearch(argv0,name,modemask) -char *argv0; -char *name; -int modemask; -{ - char *pathlist; - char *path,*cp; - char c; - extern int access(); - -#ifdef __WIN32__ - cp = strrchr(argv0,'\\'); -#else - cp = strrchr(argv0,'/'); -#endif - if( cp ){ - c = *cp; - *cp = 0; - path = (char *)malloc( strlen(argv0) + strlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); - *cp = c; - }else{ - extern char *getenv(); - pathlist = getenv("PATH"); - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - path = (char *)malloc( strlen(pathlist)+strlen(name)+2 ); - if( path!=0 ){ - while( *pathlist ){ - cp = strchr(pathlist,':'); - if( cp==0 ) cp = &pathlist[strlen(pathlist)]; - c = *cp; - *cp = 0; - sprintf(path,"%s/%s",pathlist,name); - *cp = c; - if( c==0 ) pathlist = ""; - else pathlist = &cp[1]; - if( access(path,modemask)==0 ) break; - } - } - } - return path; -} - -/* Given an action, compute the integer value for that action -** which is to be put in the action table of the generated machine. -** Return negative if no action should be generated. -*/ -PRIVATE int compute_action(lemp,ap) -struct lemon *lemp; -struct action *ap; -{ - int act; - switch( ap->type ){ - case SHIFT: act = ap->x.stp->index; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate; break; - case ERROR: act = lemp->nstate + lemp->nrule; break; - case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; - default: act = -1; break; - } - return act; -} - -#define LINESIZE 1000 -/* The next cluster of routines are for reading the template file -** and writing the results to the generated parser */ -/* The first function transfers data from "in" to "out" until -** a line is seen which begins with "%%". The line number is -** tracked. -** -** if name!=0, then any word that begin with "Parse" is changed to -** begin with *name instead. -*/ -PRIVATE void tplt_xfer(name,in,out,lineno) -char *name; -FILE *in; -FILE *out; -int *lineno; -{ - int i, iStart; - char line[LINESIZE]; - while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ - (*lineno)++; - iStart = 0; - if( name ){ - for(i=0; line[i]; i++){ - if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 - && (i==0 || !isalpha(line[i-1])) - ){ - if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); - fprintf(out,"%s",name); - i += 4; - iStart = i+1; - } - } - } - fprintf(out,"%s",&line[iStart]); - } -} - -/* The next function finds the template file and opens it, returning -** a pointer to the opened file. */ -PRIVATE FILE *tplt_open(lemp) -struct lemon *lemp; -{ - static char templatename[] = "lempar.c"; - char buf[1000]; - FILE *in; - char *tpltname; - char *cp; - - cp = strrchr(lemp->filename,'.'); - if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); - }else{ - sprintf(buf,"%s.lt",lemp->filename); - } - if( access(buf,004)==0 ){ - tpltname = buf; - }else if( access(templatename,004)==0 ){ - tpltname = templatename; - }else{ - tpltname = pathsearch(lemp->argv0,templatename,0); - } - if( tpltname==0 ){ - fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", - templatename); - lemp->errorcnt++; - return 0; - } - in = fopen(tpltname,"rb"); - if( in==0 ){ - fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - lemp->errorcnt++; - return 0; - } - return in; -} - -/* Print a #line directive line to the output file. */ -PRIVATE void tplt_linedir(out,lineno,filename) -FILE *out; -int lineno; -char *filename; -{ - fprintf(out,"#line %d \"",lineno); - while( *filename ){ - if( *filename == '\\' ) putc('\\',out); - putc(*filename,out); - filename++; - } - fprintf(out,"\"\n"); -} - -/* Print a string to the file and keep the linenumber up to date */ -PRIVATE void tplt_print(out,lemp,str,strln,lineno) -FILE *out; -struct lemon *lemp; -char *str; -int strln; -int *lineno; -{ - if( str==0 ) return; - tplt_linedir(out,strln,lemp->filename); - (*lineno)++; - while( *str ){ - if( *str=='\n' ) (*lineno)++; - putc(*str,out); - str++; - } - if( str[-1]!='\n' ){ - putc('\n',out); - (*lineno)++; - } - tplt_linedir(out,*lineno+2,lemp->outname); - (*lineno)+=2; - return; -} - -/* -** The following routine emits code for the destructor for the -** symbol sp -*/ -void emit_destructor_code(out,sp,lemp,lineno) -FILE *out; -struct symbol *sp; -struct lemon *lemp; -int *lineno; -{ - char *cp = 0; - - int linecnt = 0; - if( sp->type==TERMINAL ){ - cp = lemp->tokendest; - if( cp==0 ) return; - tplt_linedir(out,lemp->tokendestln,lemp->filename); - fprintf(out,"{"); - }else if( sp->destructor ){ - cp = sp->destructor; - tplt_linedir(out,sp->destructorln,lemp->filename); - fprintf(out,"{"); - }else if( lemp->vardest ){ - cp = lemp->vardest; - if( cp==0 ) return; - tplt_linedir(out,lemp->vardestln,lemp->filename); - fprintf(out,"{"); - }else{ - assert( 0 ); /* Cannot happen */ - } - for(; *cp; cp++){ - if( *cp=='$' && cp[1]=='$' ){ - fprintf(out,"(yypminor->yy%d)",sp->dtnum); - cp++; - continue; - } - if( *cp=='\n' ) linecnt++; - fputc(*cp,out); - } - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - return; -} - -/* -** Return TRUE (non-zero) if the given symbol has a destructor. -*/ -int has_destructor(sp, lemp) -struct symbol *sp; -struct lemon *lemp; -{ - int ret; - if( sp->type==TERMINAL ){ - ret = lemp->tokendest!=0; - }else{ - ret = lemp->vardest!=0 || sp->destructor!=0; - } - return ret; -} - -/* -** Append text to a dynamically allocated string. If zText is 0 then -** reset the string to be empty again. Always return the complete text -** of the string (which is overwritten with each call). -** -** n bytes of zText are stored. If n==0 then all of zText up to the first -** \000 terminator is stored. zText can contain up to two instances of -** %d. The values of p1 and p2 are written into the first and second -** %d. -** -** If n==-1, then the previous character is overwritten. -*/ -PRIVATE char *append_str(char *zText, int n, int p1, int p2){ - static char *z = 0; - static int alloced = 0; - static int used = 0; - int c; - char zInt[40]; - - if( zText==0 ){ - used = 0; - return z; - } - if( n<=0 ){ - if( n<0 ){ - used += n; - assert( used>=0 ); - } - n = strlen(zText); - } - if( n+sizeof(zInt)*2+used >= alloced ){ - alloced = n + sizeof(zInt)*2 + used + 200; - z = realloc(z, alloced); - } - if( z==0 ) return ""; - while( n-- > 0 ){ - c = *(zText++); - if( c=='%' && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); - p1 = p2; - strcpy(&z[used], zInt); - used += strlen(&z[used]); - zText++; - n--; - }else{ - z[used++] = c; - } - } - z[used] = 0; - return z; -} - -/* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. -*/ -PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ - char *cp, *xp; - int i; - char lhsused = 0; /* True if the LHS element has been used */ - char used[MAXRHS]; /* True for each RHS element which is used */ - - for(i=0; i<rp->nrhs; i++) used[i] = 0; - lhsused = 0; - - append_str(0,0,0,0); - for(cp=rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ - char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); - saved = *xp; - *xp = 0; - if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ - append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); - cp = xp; - lhsused = 1; - }else{ - for(i=0; i<rp->nrhs; i++){ - if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ - if( cp!=rp->code && cp[-1]=='@' ){ - /* If the argument is of the form @X then substituted - ** the token number of X, not the value of X */ - append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); - }else{ - append_str("yymsp[%d].minor.yy%d",0, - i-rp->nrhs+1,rp->rhs[i]->dtnum); - } - cp = xp; - used[i] = 1; - break; - } - } - } - *xp = saved; - } - append_str(cp, 1, 0, 0); - } /* End loop */ - - /* Check to make sure the LHS has been used */ - if( rp->lhsalias && !lhsused ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label \"%s\" for \"%s(%s)\" is never used.", - rp->lhsalias,rp->lhs->name,rp->lhsalias); - lemp->errorcnt++; - } - - /* Generate destructor code for RHS symbols which are not used in the - ** reduce code */ - for(i=0; i<rp->nrhs; i++){ - if( rp->rhsalias[i] && !used[i] ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label %s for \"%s(%s)\" is never used.", - rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); - lemp->errorcnt++; - }else if( rp->rhsalias[i]==0 ){ - if( has_destructor(rp->rhs[i],lemp) ){ - append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", 0, - rp->rhs[i]->index,i-rp->nrhs+1); - }else{ - /* No destructor defined for this term */ - } - } - } - cp = append_str(0,0,0,0); - rp->code = Strsafe(cp); -} - -/* -** Generate code which executes when the rule "rp" is reduced. Write -** the code to "out". Make sure lineno stays up-to-date. -*/ -PRIVATE void emit_code(out,rp,lemp,lineno) -FILE *out; -struct rule *rp; -struct lemon *lemp; -int *lineno; -{ - char *cp; - int linecnt = 0; - - /* Generate code to do the reduce action */ - if( rp->code ){ - tplt_linedir(out,rp->line,lemp->filename); - fprintf(out,"{%s",rp->code); - for(cp=rp->code; *cp; cp++){ - if( *cp=='\n' ) linecnt++; - } /* End loop */ - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - } /* End if( rp->code ) */ - - return; -} - -/* -** Print the definition of the union used for the parser's data stack. -** This union contains fields for every possible data type for tokens -** and nonterminals. In the process of computing and printing this -** union, also set the ".dtnum" field of every terminal and nonterminal -** symbol. -*/ -void print_stack_union(out,lemp,plineno,mhflag) -FILE *out; /* The output stream */ -struct lemon *lemp; /* The main info structure for this parser */ -int *plineno; /* Pointer to the line number */ -int mhflag; /* True if generating makeheaders output */ -{ - int lineno = *plineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ - char *stddt; /* Standardized name for a datatype */ - int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ - char *name; /* Name of the parser */ - - /* Allocate and initialize types[] and allocate stddt[] */ - arraysize = lemp->nsymbol * 2; - types = (char**)malloc( arraysize * sizeof(char*) ); - for(i=0; i<arraysize; i++) types[i] = 0; - maxdtlength = 0; - if( lemp->vartype ){ - maxdtlength = strlen(lemp->vartype); - } - for(i=0; i<lemp->nsymbol; i++){ - int len; - struct symbol *sp = lemp->symbols[i]; - if( sp->datatype==0 ) continue; - len = strlen(sp->datatype); - if( len>maxdtlength ) maxdtlength = len; - } - stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - - /* Build a hash table of datatypes. The ".dtnum" field of each symbol - ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is - ** used for terminal symbols. If there is no %default_type defined then - ** 0 is also used as the .dtnum value for nonterminals which do not specify - ** a datatype using the %type directive. - */ - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - char *cp; - if( sp==lemp->errsym ){ - sp->dtnum = arraysize+1; - continue; - } - if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ - sp->dtnum = 0; - continue; - } - cp = sp->datatype; - if( cp==0 ) cp = lemp->vartype; - j = 0; - while( isspace(*cp) ) cp++; - while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; - stddt[j] = 0; - hash = 0; - for(j=0; stddt[j]; j++){ - hash = hash*53 + stddt[j]; - } - hash = (hash & 0x7fffffff)%arraysize; - while( types[hash] ){ - if( strcmp(types[hash],stddt)==0 ){ - sp->dtnum = hash + 1; - break; - } - hash++; - if( hash>=arraysize ) hash = 0; - } - if( types[hash]==0 ){ - sp->dtnum = hash + 1; - types[hash] = (char*)malloc( strlen(stddt)+1 ); - if( types[hash]==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - strcpy(types[hash],stddt); - } - } - - /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ - name = lemp->name ? lemp->name : "Parse"; - lineno = *plineno; - if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } - fprintf(out,"#define %sTOKENTYPE %s\n",name, - lemp->tokentype?lemp->tokentype:"void*"); lineno++; - if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - fprintf(out,"typedef union {\n"); lineno++; - fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; - for(i=0; i<arraysize; i++){ - if( types[i]==0 ) continue; - fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; - free(types[i]); - } - fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; - free(stddt); - free(types); - fprintf(out,"} YYMINORTYPE;\n"); lineno++; - *plineno = lineno; -} - -/* -** Return the name of a C datatype able to represent values between -** lwr and upr, inclusive. -*/ -static const char *minimum_size_type(int lwr, int upr){ - if( lwr>=0 ){ - if( upr<=255 ){ - return "unsigned char"; - }else if( upr<65535 ){ - return "unsigned short int"; - }else{ - return "unsigned int"; - } - }else if( lwr>=-127 && upr<=127 ){ - return "signed char"; - }else if( lwr>=-32767 && upr<32767 ){ - return "short"; - }else{ - return "int"; - } -} - -/* -** Each state contains a set of token transaction and a set of -** nonterminal transactions. Each of these sets makes an instance -** of the following structure. An array of these structures is used -** to order the creation of entries in the yy_action[] table. -*/ -struct axset { - struct state *stp; /* A pointer to a state */ - int isTkn; /* True to use tokens. False for non-terminals */ - int nAction; /* Number of actions */ -}; - -/* -** Compare to axset structures for sorting purposes -*/ -static int axset_compare(const void *a, const void *b){ - struct axset *p1 = (struct axset*)a; - struct axset *p2 = (struct axset*)b; - return p2->nAction - p1->nAction; -} - -/* Generate C source code for the parser */ -void ReportTable(lemp, mhflag) -struct lemon *lemp; -int mhflag; /* Output in makeheaders format if true */ -{ - FILE *out, *in; - char line[LINESIZE]; - int lineno; - struct state *stp; - struct action *ap; - struct rule *rp; - struct acttab *pActtab; - int i, j, n; - char *name; - int mnTknOfst, mxTknOfst; - int mnNtOfst, mxNtOfst; - struct axset *ax; - - in = tplt_open(lemp); - if( in==0 ) return; - out = file_open(lemp,".c","wb"); - if( out==0 ){ - fclose(in); - return; - } - lineno = 1; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno); - if( mhflag ){ - char *name = file_makename(lemp, ".h"); - fprintf(out,"#include \"%s\"\n", name); lineno++; - free(name); - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate #defines for all tokens */ - if( mhflag ){ - char *prefix; - fprintf(out,"#if INTERFACE\n"); lineno++; - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - for(i=1; i<lemp->nterminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - lineno++; - } - fprintf(out,"#endif\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the defines */ - fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+5)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; - fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; - print_stack_union(out,lemp,&lineno,mhflag); - if( lemp->stacksize ){ - if( atoi(lemp->stacksize)<=0 ){ - ErrorMsg(lemp->filename,0, -"Illegal stack size: [%s]. The stack size should be an integer constant.", - lemp->stacksize); - lemp->errorcnt++; - lemp->stacksize = "100"; - } - fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; - }else{ - fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; - } - if( mhflag ){ - fprintf(out,"#if INTERFACE\n"); lineno++; - } - name = lemp->name ? lemp->name : "Parse"; - if( lemp->arg && lemp->arg[0] ){ - int i; - i = strlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; - fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", - name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", - name,&lemp->arg[i],&lemp->arg[i]); lineno++; - }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; - fprintf(out,"#define %sARG_FETCH\n",name); lineno++; - fprintf(out,"#define %sARG_STORE\n",name); lineno++; - } - if( mhflag ){ - fprintf(out,"#endif\n"); lineno++; - } - fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; - fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; - if( lemp->has_fallback ){ - fprintf(out,"#define YYFALLBACK 1\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the action table and its associates: - ** - ** yy_action[] A single table containing all actions. - ** yy_lookahead[] A table containing the lookahead for each entry in - ** yy_action. Used to detect hash collisions. - ** yy_shift_ofst[] For each state, the offset into yy_action for - ** shifting terminals. - ** yy_reduce_ofst[] For each state, the offset into yy_action for - ** shifting non-terminals after a reduce. - ** yy_default[] Default action for each state. - */ - - /* Compute the actions on all states and count them up */ - ax = malloc( sizeof(ax[0])*lemp->nstate*2 ); - if( ax==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - stp->nTknAct = stp->nNtAct = 0; - stp->iDflt = lemp->nstate + lemp->nrule; - stp->iTknOfst = NO_OFFSET; - stp->iNtOfst = NO_OFFSET; - for(ap=stp->ap; ap; ap=ap->next){ - if( compute_action(lemp,ap)>=0 ){ - if( ap->sp->index<lemp->nterminal ){ - stp->nTknAct++; - }else if( ap->sp->index<lemp->nsymbol ){ - stp->nNtAct++; - }else{ - stp->iDflt = compute_action(lemp, ap); - } - } - } - ax[i*2].stp = stp; - ax[i*2].isTkn = 1; - ax[i*2].nAction = stp->nTknAct; - ax[i*2+1].stp = stp; - ax[i*2+1].isTkn = 0; - ax[i*2+1].nAction = stp->nNtAct; - } - mxTknOfst = mnTknOfst = 0; - mxNtOfst = mnNtOfst = 0; - - /* Compute the action table. In order to try to keep the size of the - ** action table to a minimum, the heuristic of placing the largest action - ** sets first is used. - */ - qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); - for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){ - stp = ax[i].stp; - if( ax[i].isTkn ){ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index>=lemp->nterminal ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iTknOfst = acttab_insert(pActtab); - if( stp->iTknOfst<mnTknOfst ) mnTknOfst = stp->iTknOfst; - if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; - }else{ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index<lemp->nterminal ) continue; - if( ap->sp->index==lemp->nsymbol ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iNtOfst = acttab_insert(pActtab); - if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst; - if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; - } - } - free(ax); - - /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - n = acttab_size(pActtab); - for(i=j=0; i<n; i++){ - int action = acttab_yyaction(pActtab, i); - if( action<0 ) action = lemp->nsymbol + lemp->nrule + 2; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", action); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_lookahead table */ - fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; - for(i=j=0; i<n; i++){ - int la = acttab_yylookahead(pActtab, i); - if( la<0 ) la = lemp->nsymbol; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; - fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; i<n; i++){ - int ofst; - stp = lemp->sorted[i]; - ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; - fprintf(out, "static const %s yy_reduce_ofst[] = {\n", - minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; i<n; i++){ - int ofst; - stp = lemp->sorted[i]; - ofst = stp->iNtOfst; - if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the default action table */ - fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; - n = lemp->nstate; - for(i=j=0; i<n; i++){ - stp = lemp->sorted[i]; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDflt); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of fallback tokens. - */ - if( lemp->has_fallback ){ - for(i=0; i<lemp->nterminal; i++){ - struct symbol *p = lemp->symbols[i]; - if( p->fallback==0 ){ - fprintf(out, " 0, /* %10s => nothing */\n", p->name); - }else{ - fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, - p->name, p->fallback->name); - } - lineno++; - } - } - tplt_xfer(lemp->name, in, out, &lineno); - - /* Generate a table containing the symbolic name of every symbol - */ - for(i=0; i<lemp->nsymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } - } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate a table containing a text string that describes every - ** rule in the rule set of the grammer. This information is used - ** when tracing REDUCE actions. - */ - for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); - fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name); - for(j=0; j<rp->nrhs; j++) fprintf(out," %s",rp->rhs[j]->name); - fprintf(out,"\",\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes every time a symbol is popped from - ** the stack while processing errors or while destroying the parser. - ** (In other words, generate the %destructor actions) - */ - if( lemp->tokendest ){ - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type!=TERMINAL ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - } - for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++); - if( i<lemp->nsymbol ){ - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - - /* Combine duplicate destructors into a single case */ - for(j=i+1; j<lemp->nsymbol; j++){ - struct symbol *sp2 = lemp->symbols[j]; - if( sp2 && sp2->type!=TERMINAL && sp2->destructor - && sp2->dtnum==sp->dtnum - && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d:\n",sp2->index); lineno++; - sp2->destructor = 0; - } - } - - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - for(i=0; i<lemp->nsymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes whenever the parser stack overflows */ - tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of rule information - ** - ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. - */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which execution during each REDUCE action */ - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code ) translate_code(lemp, rp); - } - for(rp=lemp->rule; rp; rp=rp->next){ - struct rule *rp2; - if( rp->code==0 ) continue; - fprintf(out," case %d:\n",rp->index); lineno++; - for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ - fprintf(out," case %d:\n",rp2->index); lineno++; - rp2->code = 0; - } - } - emit_code(out,rp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes if a parse fails */ - tplt_print(out,lemp,lemp->failure,lemp->failureln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when a syntax error occurs */ - tplt_print(out,lemp,lemp->error,lemp->errorln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when the parser accepts its input */ - tplt_print(out,lemp,lemp->accept,lemp->acceptln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Append any addition code the user desires */ - tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno); - - fclose(in); - fclose(out); - return; -} - -/* Generate a header file for the parser */ -void ReportHeader(lemp) -struct lemon *lemp; -{ - FILE *out, *in; - char *prefix; - char line[LINESIZE]; - char pattern[LINESIZE]; - int i; - - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - in = file_open(lemp,".h","rb"); - if( in ){ - for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - if( strcmp(line,pattern) ) break; - } - fclose(in); - if( i==lemp->nterminal ){ - /* No change in the file. Don't rewrite it. */ - return; - } - } - out = file_open(lemp,".h","wb"); - if( out ){ - for(i=1; i<lemp->nterminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - } - fclose(out); - } - return; -} - -/* Reduce the size of the action tables, if possible, by making use -** of defaults. -** -** In this version, we take the most frequent REDUCE action and make -** it the default. Only default a reduce if there are more than one. -*/ -void CompressTables(lemp) -struct lemon *lemp; -{ - struct state *stp; - struct action *ap, *ap2; - struct rule *rp, *rp2, *rbest; - int nbest, n; - int i; - - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; - nbest = 0; - rbest = 0; - - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type!=REDUCE ) continue; - rp = ap->x.rp; - if( rp==rbest ) continue; - n = 1; - for(ap2=ap->next; ap2; ap2=ap2->next){ - if( ap2->type!=REDUCE ) continue; - rp2 = ap2->x.rp; - if( rp2==rbest ) continue; - if( rp2==rp ) n++; - } - if( n>nbest ){ - nbest = n; - rbest = rp; - } - } - - /* Do not make a default if the number of rules to default - ** is not at least 2 */ - if( nbest<2 ) continue; - - - /* Combine matching REDUCE actions into a single default */ - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) break; - } - assert( ap ); - ap->sp = Symbol_new("{default}"); - for(ap=ap->next; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; - } - stp->ap = Action_sort(stp->ap); - } -} - -/***************** From the file "set.c" ************************************/ -/* -** Set manipulation routines for the LEMON parser generator. -*/ - -static int size = 0; - -/* Set the set size */ -void SetSize(n) -int n; -{ - size = n+1; -} - -/* Allocate a new set */ -char *SetNew(){ - char *s; - int i; - s = (char*)malloc( size ); - if( s==0 ){ - extern void memory_error(); - memory_error(); - } - for(i=0; i<size; i++) s[i] = 0; - return s; -} - -/* Deallocate a set */ -void SetFree(s) -char *s; -{ - free(s); -} - -/* Add a new element to the set. Return TRUE if the element was added -** and FALSE if it was already there. */ -int SetAdd(s,e) -char *s; -int e; -{ - int rv; - rv = s[e]; - s[e] = 1; - return !rv; -} - -/* Add every element of s2 to s1. Return TRUE if s1 changes. */ -int SetUnion(s1,s2) -char *s1; -char *s2; -{ - int i, progress; - progress = 0; - for(i=0; i<size; i++){ - if( s2[i]==0 ) continue; - if( s1[i]==0 ){ - progress = 1; - s1[i] = 1; - } - } - return progress; -} -/********************** From the file "table.c" ****************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -PRIVATE int strhash(x) -char *x; -{ - int h = 0; - while( *x) h = h*13 + *(x++); - return h; -} - -/* Works like strdup, sort of. Save a string in malloced memory, but -** keep strings in a table so that the same string is not in more -** than one place. -*/ -char *Strsafe(y) -char *y; -{ - char *z; - - z = Strsafe_find(y); - if( z==0 && (z=malloc( strlen(y)+1 ))!=0 ){ - strcpy(z,y); - Strsafe_insert(z); - } - MemoryCheck(z); - return z; -} - -/* There is one instance of the following structure for each -** associative array of type "x1". -*/ -struct s_x1 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x1node *tbl; /* The data stored here */ - struct s_x1node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x1". -*/ -typedef struct s_x1node { - char *data; /* The data */ - struct s_x1node *next; /* Next entry with the same hash */ - struct s_x1node **from; /* Previous link */ -} x1node; - -/* There is only one instance of the array, which is the following */ -static struct s_x1 *x1a; - -/* Allocate a new associative array */ -void Strsafe_init(){ - if( x1a ) return; - x1a = (struct s_x1*)malloc( sizeof(struct s_x1) ); - if( x1a ){ - x1a->size = 1024; - x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); - if( x1a->tbl==0 ){ - free(x1a); - x1a = 0; - }else{ - int i; - x1a->ht = (x1node**)&(x1a->tbl[1024]); - for(i=0; i<1024; i++) x1a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Strsafe_insert(data) -char *data; -{ - x1node *np; - int h; - int ph; - - if( x1a==0 ) return 0; - ph = strhash(data); - h = ph & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x1a->count>=x1a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x1 array; - array.size = size = x1a->size*2; - array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x1node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x1a->count; i++){ - x1node *oldnp, *newnp; - oldnp = &(x1a->tbl[i]); - h = strhash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x1a->tbl); - *x1a = array; - } - /* Insert the new data */ - h = ph & (x1a->size-1); - np = &(x1a->tbl[x1a->count++]); - np->data = data; - if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); - np->next = x1a->ht[h]; - x1a->ht[h] = np; - np->from = &(x1a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -char *Strsafe_find(key) -char *key; -{ - int h; - x1node *np; - - if( x1a==0 ) return 0; - h = strhash(key) & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return a pointer to the (terminal or nonterminal) symbol "x". -** Create a new symbol if this is the first time "x" has been seen. -*/ -struct symbol *Symbol_new(x) -char *x; -{ - struct symbol *sp; - - sp = Symbol_find(x); - if( sp==0 ){ - sp = (struct symbol *)malloc( sizeof(struct symbol) ); - MemoryCheck(sp); - sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; - sp->prec = -1; - sp->assoc = UNK; - sp->firstset = 0; - sp->lambda = B_FALSE; - sp->destructor = 0; - sp->datatype = 0; - Symbol_insert(sp,sp->name); - } - return sp; -} - -/* Compare two symbols for working purposes -** -** Symbols that begin with upper case letters (terminals or tokens) -** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. -** -** We find experimentally that leaving the symbols in their original -** order (the order they appeared in the grammar file) gives the -** smallest parser tables in SQLite. -*/ -int Symbolcmpp(struct symbol **a, struct symbol **b){ - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - return i1-i2; -} - -/* There is one instance of the following structure for each -** associative array of type "x2". -*/ -struct s_x2 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x2node *tbl; /* The data stored here */ - struct s_x2node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x2". -*/ -typedef struct s_x2node { - struct symbol *data; /* The data */ - char *key; /* The key */ - struct s_x2node *next; /* Next entry with the same hash */ - struct s_x2node **from; /* Previous link */ -} x2node; - -/* There is only one instance of the array, which is the following */ -static struct s_x2 *x2a; - -/* Allocate a new associative array */ -void Symbol_init(){ - if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); - if( x2a ){ - x2a->size = 128; - x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); - if( x2a->tbl==0 ){ - free(x2a); - x2a = 0; - }else{ - int i; - x2a->ht = (x2node**)&(x2a->tbl[128]); - for(i=0; i<128; i++) x2a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Symbol_insert(data,key) -struct symbol *data; -char *key; -{ - x2node *np; - int h; - int ph; - - if( x2a==0 ) return 0; - ph = strhash(key); - h = ph & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x2a->count>=x2a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x2 array; - array.size = size = x2a->size*2; - array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x2node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x2a->count; i++){ - x2node *oldnp, *newnp; - oldnp = &(x2a->tbl[i]); - h = strhash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x2a->tbl); - *x2a = array; - } - /* Insert the new data */ - h = ph & (x2a->size-1); - np = &(x2a->tbl[x2a->count++]); - np->key = key; - np->data = data; - if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); - np->next = x2a->ht[h]; - x2a->ht[h] = np; - np->from = &(x2a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct symbol *Symbol_find(key) -char *key; -{ - int h; - x2node *np; - - if( x2a==0 ) return 0; - h = strhash(key) & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return the n-th data. Return NULL if n is out of range. */ -struct symbol *Symbol_Nth(n) -int n; -{ - struct symbol *data; - if( x2a && n>0 && n<=x2a->count ){ - data = x2a->tbl[n-1].data; - }else{ - data = 0; - } - return data; -} - -/* Return the size of the array */ -int Symbol_count() -{ - return x2a ? x2a->count : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof() -{ - struct symbol **array; - int i,size; - if( x2a==0 ) return 0; - size = x2a->count; - array = (struct symbol **)malloc( sizeof(struct symbol *)*size ); - if( array ){ - for(i=0; i<size; i++) array[i] = x2a->tbl[i].data; - } - return array; -} - -/* Compare two configurations */ -int Configcmp(a,b) -struct config *a; -struct config *b; -{ - int x; - x = a->rp->index - b->rp->index; - if( x==0 ) x = a->dot - b->dot; - return x; -} - -/* Compare two states */ -PRIVATE int statecmp(a,b) -struct config *a; -struct config *b; -{ - int rc; - for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ - rc = a->rp->index - b->rp->index; - if( rc==0 ) rc = a->dot - b->dot; - } - if( rc==0 ){ - if( a ) rc = 1; - if( b ) rc = -1; - } - return rc; -} - -/* Hash a state */ -PRIVATE int statehash(a) -struct config *a; -{ - int h=0; - while( a ){ - h = h*571 + a->rp->index*37 + a->dot; - a = a->bp; - } - return h; -} - -/* Allocate a new state structure */ -struct state *State_new() -{ - struct state *new; - new = (struct state *)malloc( sizeof(struct state) ); - MemoryCheck(new); - return new; -} - -/* There is one instance of the following structure for each -** associative array of type "x3". -*/ -struct s_x3 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x3node *tbl; /* The data stored here */ - struct s_x3node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x3". -*/ -typedef struct s_x3node { - struct state *data; /* The data */ - struct config *key; /* The key */ - struct s_x3node *next; /* Next entry with the same hash */ - struct s_x3node **from; /* Previous link */ -} x3node; - -/* There is only one instance of the array, which is the following */ -static struct s_x3 *x3a; - -/* Allocate a new associative array */ -void State_init(){ - if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); - if( x3a ){ - x3a->size = 128; - x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); - if( x3a->tbl==0 ){ - free(x3a); - x3a = 0; - }else{ - int i; - x3a->ht = (x3node**)&(x3a->tbl[128]); - for(i=0; i<128; i++) x3a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int State_insert(data,key) -struct state *data; -struct config *key; -{ - x3node *np; - int h; - int ph; - - if( x3a==0 ) return 0; - ph = statehash(key); - h = ph & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x3a->count>=x3a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x3 array; - array.size = size = x3a->size*2; - array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x3node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x3a->count; i++){ - x3node *oldnp, *newnp; - oldnp = &(x3a->tbl[i]); - h = statehash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x3a->tbl); - *x3a = array; - } - /* Insert the new data */ - h = ph & (x3a->size-1); - np = &(x3a->tbl[x3a->count++]); - np->key = key; - np->data = data; - if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); - np->next = x3a->ht[h]; - x3a->ht[h] = np; - np->from = &(x3a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct state *State_find(key) -struct config *key; -{ - int h; - x3node *np; - - if( x3a==0 ) return 0; - h = statehash(key) & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct state **State_arrayof() -{ - struct state **array; - int i,size; - if( x3a==0 ) return 0; - size = x3a->count; - array = (struct state **)malloc( sizeof(struct state *)*size ); - if( array ){ - for(i=0; i<size; i++) array[i] = x3a->tbl[i].data; - } - return array; -} - -/* Hash a configuration */ -PRIVATE int confighash(a) -struct config *a; -{ - int h=0; - h = h*571 + a->rp->index*37 + a->dot; - return h; -} - -/* There is one instance of the following structure for each -** associative array of type "x4". -*/ -struct s_x4 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x4node *tbl; /* The data stored here */ - struct s_x4node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x4". -*/ -typedef struct s_x4node { - struct config *data; /* The data */ - struct s_x4node *next; /* Next entry with the same hash */ - struct s_x4node **from; /* Previous link */ -} x4node; - -/* There is only one instance of the array, which is the following */ -static struct s_x4 *x4a; - -/* Allocate a new associative array */ -void Configtable_init(){ - if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); - if( x4a ){ - x4a->size = 64; - x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); - if( x4a->tbl==0 ){ - free(x4a); - x4a = 0; - }else{ - int i; - x4a->ht = (x4node**)&(x4a->tbl[64]); - for(i=0; i<64; i++) x4a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Configtable_insert(data) -struct config *data; -{ - x4node *np; - int h; - int ph; - - if( x4a==0 ) return 0; - ph = confighash(data); - h = ph & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x4a->count>=x4a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x4 array; - array.size = size = x4a->size*2; - array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x4node**)&(array.tbl[size]); - for(i=0; i<size; i++) array.ht[i] = 0; - for(i=0; i<x4a->count; i++){ - x4node *oldnp, *newnp; - oldnp = &(x4a->tbl[i]); - h = confighash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x4a->tbl); - *x4a = array; - } - /* Insert the new data */ - h = ph & (x4a->size-1); - np = &(x4a->tbl[x4a->count++]); - np->data = data; - if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); - np->next = x4a->ht[h]; - x4a->ht[h] = np; - np->from = &(x4a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct config *Configtable_find(key) -struct config *key; -{ - int h; - x4node *np; - - if( x4a==0 ) return 0; - h = confighash(key) & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Remove all data from the table. Pass each data to the function "f" -** as it is removed. ("f" may be null to avoid this step.) */ -void Configtable_clear(f) -int(*f)(/* struct config * */); -{ - int i; - if( x4a==0 || x4a->count==0 ) return; - if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data); - for(i=0; i<x4a->size; i++) x4a->ht[i] = 0; - x4a->count = 0; - return; -} diff --git a/external/badvpn_dns/lime/lime.bootstrap b/external/badvpn_dns/lime/lime.bootstrap deleted file mode 100644 index 63791c7..0000000 --- a/external/badvpn_dns/lime/lime.bootstrap +++ /dev/null @@ -1,31 +0,0 @@ -There is nothing to see here. Go and look at the file called "metagrammar". - -: $$ = new lime(); -grammar pragma toklist stop : $$->pragma($2, $3); -grammar rewrite stop : $2->update($$); -to grammar -: {$$=array();} -toklist sym : $$[] = $2; -toklist lit : $$[] = $2; -to toklist -sym '=' rhs : $$ = new lime_rewrite($1); $$->add_rhs($3); -rewrite '|' rhs : $$->add_rhs($3); -to rewrite -list : $$ = new lime_rhs($1, ''); -list action : $$ = new lime_rhs($1, $2); -to rhs -action : $$ = new lime_action($1, NULL); -action lambda : $$ = new lime_action($1, $2); -sym : $$ = new lime_glyph($1, NULL); -sym lambda : $$ = new lime_glyph($1, $2); -lit : $$ = new lime_glyph($1, NULL); -to slot -: $$ = new lime_rhs(); -rhs slot : $$->add($2); -to rhs -'{' code '}' : $$ = $2; -to action -: -code php : $$.=$2; -code '{' code '}' : $$.='{'.$3.'}'; -to code diff --git a/external/badvpn_dns/lime/lime.php b/external/badvpn_dns/lime/lime.php deleted file mode 100644 index b049225..0000000 --- a/external/badvpn_dns/lime/lime.php +++ /dev/null @@ -1,910 +0,0 @@ -<?php -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -define('LIME_DIR', dirname(__FILE__)); - -function emit($str) { fputs(STDERR, $str."\n"); } - -class Bug extends Exception {} -function bug($gripe='Bug found.') { throw new Bug($gripe); } -function bug_if($falacy, $gripe='Bug found.') { if ($falacy) throw new Bug($gripe); } -function bug_unless($assertion, $gripe='Bug found.') { if (!$assertion) throw new Bug($gripe); } - -include_once(LIME_DIR.'/parse_engine.php'); -include_once(LIME_DIR.'/set.so.php'); -include_once(LIME_DIR.'/flex_token_stream.php'); - -function lime_token_reference($pos) { return '$tokens['.$pos.']'; } -function lime_token_reference_callback($foo) { return lime_token_reference($foo[1]-1); } - -class cf_action { - function __construct($code) { $this->code=$code; } -} -class step { - /* - Base class for parse table instructions. The main idea is to make the - subclasses responsible for conflict resolution among themselves. It also - forms a sort of interface to the parse table. - */ - function __construct($sym) { - bug_unless($sym instanceof sym); - $this->sym = $sym; - } - function glyph() { return $this->sym->name; } -} -class error extends step { - function sane() { return false; } - function instruction() { bug("This should not happen."); } - function decide($that) { return $this; /* An error shall remain one. */ } -} -class shift extends step { - function __construct($sym, $q) { - parent::__construct($sym); - $this->q = $q; - } - function sane() { return true; } - function instruction() { return "s $this->q"; } - function decide($that) { - # shift-shift conflicts are impossible. - # shift-accept conflicts are a bug. - # so we can infer: - bug_unless($that instanceof reduce); - - # That being said, the resolution is a matter of precedence. - $shift_prec = $this->sym->right_prec; - $reduce_prec = $that->rule->prec; - - # If we don't have defined precedence levels for both options, - # then we default to shifting: - if (!($shift_prec and $reduce_prec)) return $this; - - # Otherwise, use the step with higher precedence. - if ($shift_prec > $reduce_prec) return $this; - if ($reduce_prec > $shift_prec) return $that; - - # The "nonassoc" works by giving equal precedence to both options, - # which means to put an error instruction in the parse table. - return new error($this->sym); - } -} -class reduce extends step { - function __construct($sym, $rule) { - bug_unless($rule instanceof rule); - parent::__construct($sym); - $this->rule = $rule; - } - function sane() { return true; } - function instruction() { return 'r '.$this->rule->id; } - function decide($that) { - # This means that the input grammar has a reduce-reduce conflict. - # Such things are considered an error in the input. - throw new RRC($this, $that); - #exit(1); - # BISON would go with the first encountered reduce thus: - # return $this; - } -} -class accept extends step { - function __construct($sym) { parent::__construct($sym); } - function sane() { return true; } - function instruction() { return 'a '.$this->sym->name; } -} -class RRC extends Exception { - function __construct($a, $b) { - parent::__construct("Reduce-Reduce Conflict"); - $this->a = $a; - $this->b = $b; - } - function make_noise() { - emit(sprintf( - "Reduce-Reduce Conflict:\n%s\n%s\nLookahead is (%s)", - $this->a->rule->text(), - $this->b->rule->text(), - $this->a->glyph() - )); - } -} -class state { - function __construct($id, $key, $close) { - $this->id = $id; - $this->key = $key; - $this->close = $close; # config key -> object - ksort($this->close); - $this->action = array(); - } - function dump() { - echo " * ".$this->id.' / '.$this->key."\n"; - foreach ($this->close as $config) $config->dump(); - } - function add_shift($sym, $state) { - $this->add_instruction(new shift($sym, $state->id)); - } - function add_reduce($sym, $rule) { - $this->add_instruction(new reduce($sym, $rule)); - } - function add_accept($sym) { - $this->add_instruction(new accept($sym)); - } - function add_instruction($step) { - bug_unless($step instanceof step); - $this->action[] = $step; - } - function find_reductions($lime) { - # rightmost configurations followset yields reduce. - foreach($this->close as $c) { - if ($c->rightmost) { - foreach ($c->follow->all() as $glyph) $this->add_reduce($lime->sym($glyph), $c->rule); - } - } - } - function resolve_conflicts() { - # For each possible lookahead, find one (and only one) step to take. - $table = array(); - foreach ($this->action as $step) { - $glyph = $step->glyph(); - if (isset($table[$glyph])) { - # There's a conflict. The shifts all came first, which - # simplifies the coding for the step->decide() methods. - try { - $table[$glyph] = $table[$glyph]->decide($step); - } catch (RRC $e) { - emit("State $this->id:"); - $e->make_noise(); - } - } else { - # This glyph is yet unprocessed, so the step at hand is - # our best current guess at what the grammar indicates. - $table[$glyph] = $step; - } - } - - # Now that we have the correct steps chosen, this routine is oddly - # also responsible for turning that table into the form that will - # eventually be passed to the parse engine. (So FIXME?) - $out = array(); - foreach ($table as $glyph => $step) { - if ($step->sane()) $out[$glyph] = $step->instruction(); - } - return $out; - } - function segment_config() { - # Filter $this->close into categories based on the symbol_after_the_dot. - $f = array(); - foreach ($this->close as $c) { - $p = $c->symbol_after_the_dot; - if (!$p) continue; - $f[$p->name][] = $c; - } - return $f; - } -} -class sym { - function __construct($name, $id) { - $this->name=$name; - $this->id=$id; - $this->term = true; # Until proven otherwise. - $this->rule = array(); - $this->config = array(); - $this->lambda = false; - $this->first = new set(); - $this->left_prec = $this->right_prec = 0; - } - function summary() { - $out = ''; - foreach ($this->rule as $rule) $out .= $rule->text()."\n"; - return $out; - } -} -class rule { - function __construct($id, $sym, $rhs, $code, $look, $replace) { - $this->id = $id; - $this->sym = $sym; - $this->rhs = $rhs; - $this->code = $code; - $this->look = $look; - bug_unless(is_int($look)); - $this->replace = $replace; - #$this->prec_sym = $prec_sym; - $this->prec = 0; - $this->first = array(); - $this->epsilon = count($rhs); - } - function lhs_glyph() { return $this->sym->name; } - function determine_precedence() { - # We may eventually expand to allow explicit prec_symbol declarations. - # Until then, we'll go with the rightmost terminal, which is what - # BISON does. People probably expect that. The leftmost terminal - # is a reasonable alternative behaviour, but I don't see the big - # deal just now. - - #$prec_sym = $this->prec_sym; - #if (!$prec_sym) - $prec_sym = $this->rightmost_terminal(); - if (!$prec_sym) return; - $this->prec = $prec_sym->left_prec; - } - private function rightmost_terminal() { - $symbol = NULL; - $rhs = $this->rhs; - while ($rhs) { - $symbol = array_pop($rhs); - if ($symbol->term) break; - } - return $symbol; - } - function text() { - $t = "($this->id) ".$this->lhs_glyph().' :='; - foreach($this->rhs as $s) $t .= ' '.$s->name; - return $t; - } - function table(lime_language $lang) { - return array( - 'symbol' => $this->lhs_glyph(), - 'len' => $this->look, - 'replace' => $this->replace, - 'code' => $lang->fixup($this->code), - 'text' => $this->text(), - ); - } - function lambda() { - foreach ($this->rhs as $sym) if (!$sym->lambda) return false; - return true; - } - function find_first() { - $dot = count($this->rhs); - $last = $this->first[$dot] = new set(); - while ($dot) { - $dot--; - $symbol_after_the_dot = $this->rhs[$dot]; - $first = $symbol_after_the_dot->first->all(); - bug_if(empty($first) and !$symbol_after_the_dot->lambda); - $set = new set($first); - if ($symbol_after_the_dot->lambda) { - $set->union($last); - if ($this->epsilon == $dot+1) $this->epsilon = $dot; - } - $last = $this->first[$dot] = $set; - } - } - function teach_symbol_of_first_set() { - $go = false; - foreach ($this->rhs as $sym) { - if ($this->sym->first->union($sym->first)) $go = true; - if (!$sym->lambda) break; - } - return $go; - } - function lambda_from($dot) { - return $this->epsilon <= $dot; - } - function leftmost($follow) { - return new config($this, 0, $follow); - } - function dotted_text($dot) { - $out = $this->lhs_glyph().' :='; - $idx = -1; - foreach($this->rhs as $idx => $s) { - if ($idx == $dot) $out .= ' .'; - $out .= ' '.$s->name; - } - if ($dot > $idx) $out .= ' .'; - return $out; - } -} -class config { - function __construct($rule, $dot, $follow) { - $this->rule=$rule; - $this->dot = $dot; - $this->key = "$rule->id.$dot"; - $this->rightmost = count($rule->rhs) <= $dot; - $this->symbol_after_the_dot = $this->rightmost ? null : $rule->rhs[$dot]; - $this->_blink = array(); - $this->follow = new set($follow); - $this->_flink= array(); - bug_unless($this->rightmost or count($rule)); - } - function text() { - $out = $this->rule->dotted_text($this->dot); - $out .= ' [ '.implode(' ', $this->follow->all()).' ]'; - return $out; - } - function blink($config) { - $this->_blink[] = $config; - } - function next() { - bug_if($this->rightmost); - $c = new config($this->rule, $this->dot+1, array()); - # Anything in the follow set for this config will also be in the next. - # However, we link it backwards because we might wind up selecting a - # pre-existing state, and the housekeeping is easier in the first half - # of the program. We'll fix it before doing the propagation. - $c->blink($this); - return $c; - } - function copy_links_from($that) { - foreach($that->_blink as $c) $this->blink($c); - } - function lambda() { - return $this->rule->lambda_from($this->dot); - } - function simple_follow() { - return $this->rule->first[$this->dot+1]->all(); - } - function epsilon_follows() { - return $this->rule->lambda_from($this->dot+1); - } - function fixlinks() { - foreach ($this->_blink as $that) $that->_flink[] = $this; - $this->blink = array(); - } - function dump() { - echo " * "; - echo $this->key.' : '; - echo $this->rule->dotted_text($this->dot); - echo $this->follow->text(); - foreach ($this->_flink as $c) echo $c->key.' / '; - echo "\n"; - } -} -class lime { - var $parser_class = 'parser'; - function __construct() { - $this->p_next = 1; - $this->sym = array(); - $this->rule = array(); - $this->start_symbol_set = array(); - $this->state = array(); - $this->stop = $this->sym('#'); - #$err = $this->sym('error'); - $err->term = false; - $this->lang = new lime_language_php(); - } - function language() { return $this->lang; } - function build_parser() { - $this->add_start_rule(); - foreach ($this->rule as $r) $r->determine_precedence(); - $this->find_sym_lamdba(); - $this->find_sym_first(); - foreach ($this->rule as $rule) $rule->find_first(); - $initial = $this->find_states(); - $this->fixlinks(); - # $this->dump_configurations(); - $this->find_follow_sets(); - foreach($this->state as $s) $s->find_reductions($this); - $i = $this->resolve_conflicts(); - $a = $this->rule_table(); - $qi = $initial->id; - return $this->lang->ptab_to_class($this->parser_class, compact('a', 'qi', 'i')); - } - function rule_table() { - $s = array(); - foreach ($this->rule as $i => $r) { - $s[$i] = $r->table($this->lang); - } - return $s; - } - function add_rule($symbol, $rhs, $code) { - $this->add_raw_rule($symbol, $rhs, $code, count($rhs), true); - } - function trump_up_bogus_lhs($real) { - return "'$real'".count($this->rule); - } - function add_raw_rule($lhs, $rhs, $code, $look, $replace) { - $sym = $this->sym($lhs); - $sym->term=false; - if (empty($rhs)) $sym->lambda = true; - $rs = array(); - foreach ($rhs as $str) $rs[] = $this->sym($str); - $rid = count($this->rule); - $r = new rule($rid, $sym, $rs, $code, $look, $replace); - $this->rule[$rid] = $r; - $sym->rule[] = $r; - } - function sym($str) { - if (!isset($this->sym[$str])) $this->sym[$str] = new sym($str, count($this->sym)); - return $this->sym[$str]; - } - function summary() { - $out = ''; - foreach ($this->sym as $sym) if (!$sym->term) $out .= $sym->summary(); - return $out; - } - private function find_sym_lamdba() { - do { - $go = false; - foreach ($this->sym as $sym) if (!$sym->lambda) { - foreach ($sym->rule as $rule) if ($rule->lambda()) { - $go = true; - $sym->lambda = true; - } - } - } while ($go); - } - private function teach_terminals_first_set() { - foreach ($this->sym as $sym) if ($sym->term) $sym->first->add($sym->name); - } - private function find_sym_first() { - $this->teach_terminals_first_set(); - do { - $go = false; - foreach ($this->rule as $r) if ($r->teach_symbol_of_first_set()) $go = true; - } while ($go); - } - function add_start_rule() { - $rewrite = new lime_rewrite("'start'"); - $rhs = new lime_rhs(); - $rhs->add(new lime_glyph($this->deduce_start_symbol()->name, NULL)); - #$rhs->add(new lime_glyph($this->stop->name, NULL)); - $rewrite->add_rhs($rhs); - $rewrite->update($this); - } - private function deduce_start_symbol() { - $candidate = current($this->start_symbol_set); - # Did the person try to set a start symbol at all? - if (!$candidate) return $this->first_rule_lhs(); - # Do we actually have such a symbol on the left of a rule? - if ($candidate->terminal) return $this->first_rule_lhs(); - # Ok, it's a decent choice. We need to return the symbol entry. - return $this->sym($candidate); - } - private function first_rule_lhs() { - reset($this->rule); - $r = current($this->rule); - return $r->sym; - } - function find_states() { - /* - Build an initial state. This is a recursive process which digs out - the LR(0) state graph. - */ - $start_glyph = "'start'"; - $sym = $this->sym($start_glyph); - $basis = array(); - foreach($sym->rule as $rule) { - $c = $rule->leftmost(array('#')); - $basis[$c->key] = $c; - } - $initial = $this->get_state($basis); - $initial->add_accept($sym); - return $initial; - } - function get_state($basis) { - $key = array_keys($basis); - sort($key); - $key = implode(' ', $key); - if (isset($this->state[$key])) { - # Copy all the links around... - $state = $this->state[$key]; - foreach($basis as $config) $state->close[$config->key]->copy_links_from($config); - return $state; - } else { - $close = $this->state_closure($basis); - $this->state[$key] = $state = new state(count($this->state), $key, $close); - $this->build_shifts($state); - return $state; - } - } - private function state_closure($q) { - # $q is a list of config. - $close = array(); - while ($config = array_pop($q)) { - if (isset($close[$config->key])) { - $close[$config->key]->copy_links_from($config); - $close[$config->key]->follow->union($config->follow); - continue; - } - $close[$config->key] = $config; - - $symbol_after_the_dot = $config->symbol_after_the_dot; - if (!$symbol_after_the_dot) continue; - - if (! $symbol_after_the_dot->term) { - foreach ($symbol_after_the_dot->rule as $r) { - $station = $r->leftmost($config->simple_follow()); - if ($config->epsilon_follows()) $station->blink($config); - $q[] = $station; - } - # The following turned out to be wrong. Don't do it. - #if ($symbol_after_the_dot->lambda) { - # $q[] = $config->next(); - #} - } - - } - return $close; - } - function build_shifts($state) { - foreach ($state->segment_config() as $glyph => $segment) { - $basis = array(); - foreach ($segment as $preshift) { - $postshift = $preshift->next(); - $basis[$postshift->key] = $postshift; - } - $dest = $this->get_state($basis); - $state->add_shift($this->sym($glyph), $dest); - } - } - function fixlinks() { - foreach ($this->state as $s) foreach ($s->close as $c) $c->fixlinks(); - } - function find_follow_sets() { - $q = array(); - foreach ($this->state as $s) foreach ($s->close as $c) $q[] = $c; - while ($q) { - $c = array_shift($q); - foreach ($c->_flink as $d) { - if ($d->follow->union($c->follow)) $q[] = $d; - } - } - } - private function set_assoc($ss, $l, $r) { - $p = ($this->p_next++)*2; - foreach ($ss as $glyph) { - $s = $this->sym($glyph); - $s->left_prec = $p+$l; - $s->right_prec = $p+$r; - } - } - function left_assoc($ss) { $this->set_assoc($ss, 1, 0); } - function right_assoc($ss) { $this->set_assoc($ss, 0, 1); } - function non_assoc($ss) { $this->set_assoc($ss, 0, 0); } - private function resolve_conflicts() { - # For each state, try to find one and only one - # thing to do for any given lookahead. - $i = array(); - foreach ($this->state as $s) $i[$s->id] = $s->resolve_conflicts(); - return $i; - } - function dump_configurations() { - foreach ($this->state as $q) $q->dump(); - } - function dump_first_sets() { - foreach ($this->sym as $s) { - echo " * "; - echo $s->name.' : '; - echo $s->first->text(); - echo "\n"; - } - } - function add_rule_with_actions($lhs, $rhs) { - # First, make sure this thing is well-formed. - if(!is_object(end($rhs))) $rhs[] = new cf_action(''); - # Now, split it into chunks based on the actions. - $look = -1; - $subrule = array(); - $subsymbol = ''; - while (count($rhs)) { - $it = array_shift($rhs); - $look ++; - if (is_string($it)) { - $subrule[] = $it; - } else { - $code = $it->code; - # It's an action. - # Is it the last one? - if (count($rhs)) { - # no. - $subsymbol = $this->trump_up_bogus_lhs($lhs); - $this->add_raw_rule($subsymbol, $subrule, $code, $look, false); - $subrule = array($subsymbol); - } else { - # yes. - $this->add_raw_rule($lhs, $subrule, $code, $look, true); - } - } - } - } - function pragma($type, $args) { - switch ($type) { - case 'left': - $this->left_assoc($args); - break; - - case 'right': - $this->right_assoc($args); - break; - - case 'nonassoc': - $this->non_assoc($args); - break; - - case 'start': - $this->start_symbol_set = $args; - break; - - case 'class': - $this->parser_class = $args[0]; - break; - - default: - emit(sprintf("Bad Parser Pragma: (%s)", $type)); - exit(1); - } - } -} -class lime_language {} -class lime_language_php extends lime_language { - private function result_code($expr) { return "\$result = $expr;\n"; } - function default_result() { return $this->result_code('reset($tokens)'); } - function result_pos($pos) { return $this->result_code(lime_token_reference($pos)); } - function bind($name, $pos) { return "\$$name =& \$tokens[$pos];\n"; } - function fixup($code) { - $code = preg_replace_callback('/\\$(\d+)/', 'lime_token_reference_callback', $code); - $code = preg_replace('/\\$\\$/', '$result', $code); - return $code; - } - function to_php($code) { - return $code; - } - function ptab_to_class($parser_class, $ptab) { - $code = "class $parser_class extends lime_parser {\n"; - $code .= 'var $qi = '.var_export($ptab['qi'], true).";\n"; - $code .= 'var $i = '.var_export($ptab['i'], true).";\n"; - - - $rc = array(); - $method = array(); - $rules = array(); - foreach($ptab['a'] as $k => $a) { - $symbol = preg_replace('/[^\w]/', '', $a['symbol']); - $rn = ++$rc[$symbol]; - $mn = "reduce_${k}_${symbol}_${rn}"; - $method[$k] = $mn; - $comment = "#\n# $a[text]\n#\n"; - $php = $this->to_php($a['code']); - $code .= "function $mn(".LIME_CALL_PROTOCOL.") {\n$comment$php\n}\n\n"; - - - unset($a['code']); - unset($a['text']); - $rules[$k] = $a; - } - - $code .= 'var $method = '.var_export($method, true).";\n"; - $code .= 'var $a = '.var_export($rules, true).";\n"; - - - - $code .= "}\n"; - #echo $code; - return $code; - } -} -class lime_rhs { - function __construct() { - /** - Construct and add glyphs and actions in whatever order. - Then, add this to a lime_rewrite. - - Don't call install_rule. - The rewrite will do that for you when you "update" with it. - */ - $this->rhs = array(); - } - function add($slot) { - bug_unless($slot instanceof lime_slot); - $this->rhs[] = $slot; - } - function install_rule(lime $lime, $lhs) { - # This is the part that has to break the rule into subrules if necessary. - $rhs = $this->rhs; - # First, make sure this thing is well-formed. - if (!(end($rhs) instanceof lime_action)) $rhs[] = new lime_action('', NULL); - # Now, split it into chunks based on the actions. - - $lang = $lime->language(); - $result_code = $lang->default_result(); - $look = -1; - $subrule = array(); - $subsymbol = ''; - $preamble = ''; - while (count($rhs)) { - $it = array_shift($rhs); - $look ++; - if ($it instanceof lime_glyph) { - $subrule[] = $it->data; - } elseif ($it instanceof lime_action) { - $code = $it->data; - # It's an action. - # Is it the last one? - if (count($rhs)) { - # no. - $subsymbol = $lime->trump_up_bogus_lhs($lhs); - $action = $lang->default_result().$preamble.$code; - $lime->add_raw_rule($subsymbol, $subrule, $action, $look, false); - $subrule = array($subsymbol); - } else { - # yes. - $action = $result_code.$preamble.$code; - $lime->add_raw_rule($lhs, $subrule, $action, $look, true); - } - } else { - impossible(); - } - if ($it->name == '$') $result_code = $lang->result_pos($look); - elseif ($it->name) $preamble .= $lang->bind($it->name, $look); - } - } -} -class lime_rewrite { - function __construct($glyph) { - /** - Construct one of these with the name of the lhs. - Add some rhs-es to it. - Finally, "update" the lime you're building. - */ - $this->glyph = $glyph; - $this->rhs = array(); - } - function add_rhs($rhs) { - bug_unless($rhs instanceof lime_rhs); - $this->rhs[] = $rhs; - } - function update(lime $lime) { - foreach ($this->rhs as $rhs) { - $rhs->install_rule($lime, $this->glyph); - - } - } -} -class lime_slot { - /** - This keeps track of one position in an rhs. - We specialize to handle actions and glyphs. - If there is a name for the slot, we store it here. - Later on, this structure will be consulted in the formation of - actual production rules. - */ - function __construct($data, $name) { - $this->data = $data; - $this->name = $name; - } - function preamble($pos) { - if (strlen($this->name) > 0) { - return "\$$this->name =& \$tokens[$pos];\n"; - } - } -} -class lime_glyph extends lime_slot {} -class lime_action extends lime_slot {} -function lime_bootstrap() { - - /* - - This function isn't too terribly interesting to the casual observer. - You're probably better off looking at parse_lime_grammar() instead. - - Ok, if you insist, I'll explain. - - The input to Lime is a CFG parser definition. That definition is - written in some language. (The Lime language, to be exact.) - Anyway, I have to parse the Lime language and compile it into a - very complex data structure from which a parser is eventually - built. What better way than to use Lime itself to parse its own - language? Well, it's almost that simple, but not quite. - - The Lime language is fairly potent, but a restricted subset of - its features was used to write a metagrammar. Then, I hand-translated - that metagrammar into another form which is easy to snarf up. - In the process of reading that simplified form, this function - builds the same sort of data structure that later gets turned into - a parser. The last step is to run the parser generation algorithm, - eval() the resulting PHP code, and voila! With no hard work, I can - suddenly read and comprehend the full range of the Lime language - without ever having written an algorithm to do so. It feels like magic. - - */ - - $bootstrap = LIME_DIR."/lime.bootstrap"; - $lime = new lime(); - $lime->parser_class = 'lime_metaparser'; - $rhs = array(); - bug_unless(is_readable($bootstrap)); - foreach(file($bootstrap) as $l) { - $a = explode(":", $l, 2); - if (count($a) == 2) { - list($pattern, $code) = $a; - $sl = new lime_rhs(); - $pattern = trim($pattern); - if (strlen($pattern)>0) { - foreach (explode(' ', $pattern) as $glyph) $sl->add(new lime_glyph($glyph, NULL)); - } - $sl->add(new lime_action($code, NULL)); - $rhs[] = $sl; - } else { - $m = preg_match('/^to (\w+)$/', $l, $r); - if ($m == 0) continue; - $g = $r[1]; - $rw = new lime_rewrite($g); - foreach($rhs as $b) $rw->add_rhs($b); - $rw->update($lime); - $rhs = array(); - } - } - $parser_code = $lime->build_parser(); - eval($parser_code); -} - -class voodoo_scanner extends flex_scanner { - /* - - The voodoo is in the way I do lexical processing on grammar definition - files. They contain embedded bits of PHP, and it's important to keep - track of things like strings, comments, and matched braces. It seemed - like an ideal problem to solve with GNU flex, so I wrote a little - scanner in flex and C to dig out the tokens for me. Of course, I need - the tokens in PHP, so I designed a simple binary wrapper for them which - also contains line-number information, guaranteed to help out if you - write a grammar which surprises the parser in any manner. - - */ - function executable() { return LIME_DIR.'/lime_scan_tokens'; } -} - -function parse_lime_grammar($path) { - /* - - This is a good function to read because it teaches you how to interface - with a Lime parser. I've tried to isolate out the bits that aren't - instructive in that regard. - - */ - if (!class_exists('lime_metaparser')) lime_bootstrap(); - - $parse_engine = new parse_engine(new lime_metaparser()); - $scanner = new voodoo_scanner($path); - try { - # The result of parsing a Lime grammar is a Lime object. - $lime = $scanner->feed($parse_engine); - # Calling its build_parser() method gets the output PHP code. - return $lime->build_parser(); - } catch (parse_error $e) { - die ($e->getMessage()." in $path line $scanner->lineno.\n"); - } -} - - -if ($_SERVER['argv']) { - $code = ''; - array_shift($_SERVER['argv']); # Strip out the program name. - foreach ($_SERVER['argv'] as $path) { - $code .= parse_lime_grammar($path); - } - - echo "<?php\n\n"; -?> - -/* - -DON'T EDIT THIS FILE! - -This file was automatically generated by the Lime parser generator. -The real source code you should be looking at is in one or more -grammar files in the Lime format. - -THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar -file that your error happened, because there are enough comments to -help you debug your grammar. - -If you ignore this warning, you're shooting yourself in the brain, -not the foot. - -*/ - -<?php - echo $code; -} diff --git a/external/badvpn_dns/lime/lime_scan_tokens.l b/external/badvpn_dns/lime/lime_scan_tokens.l deleted file mode 100644 index d4aae9a..0000000 --- a/external/badvpn_dns/lime/lime_scan_tokens.l +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -%{ -void out(char*t, char*v); -void lit(); -void tok(char*t); -void php(); -%} - -%option stack -%option yylineno -%option main - -%x code -%x dquote -%x squote - -CHAR \n|. - -ALPHA [a-zA-Z] -DIGIT [0-9] -ALNUM {ALPHA}|{DIGIT} -WORD {ALNUM}|_ -STOP "." - -SYM {ALPHA}{WORD}*'* -LIT '.' - -ESC ""{CHAR} -SCHAR [^']|ESC -DCHAR [^"]|ESC -COM "//"|"#" - -CC [^*\n] -CX "*"+{CC}+ -CT "*"+"/" -BLOCKCMT "/*"({CC}|{CX})*{CT} - -%x pragma - - -%% - -[[:space:]]+ {} -#.* {} - -{STOP} out("stop", "."); -{SYM} tok("sym"); -{LIT} tok("lit"); -"/"{WORD}+ | -"/$" out("lambda", yytext+1); -"%"{WORD}+ { - out("pragma", yytext+1); - yy_push_state(pragma); -} - -<*>"{" { - lit(); - yy_push_state(code); -} - -. lit(); - - -<pragma>{ -\n { - out("stop", "."); - yy_pop_state(); -} -[[:space:]] {} -{SYM} tok("sym"); -{LIT} tok("lit"); -. lit(); -} - -<code>{ -"}" { - lit(); - yy_pop_state(); -} -'{SCHAR}*' php(); -"{DCHAR}*" php(); -{COM}.* php(); -{BLOCKCMT} php(); -[^{}'"#/]+ php(); -. php(); -} - -%% - -void lit() { - char lit[] = "'.'"; - lit[1] = *yytext; - out(lit, yytext); -} - -void tok(char*t) { - out(t, yytext); -} - -void php() { - out("php", yytext); -} - -void out(char*type, char*value) { - printf("%d\001%s\001%s", yylineno, type, value); - fputc(0, stdout); -} diff --git a/external/badvpn_dns/lime/metagrammar b/external/badvpn_dns/lime/metagrammar deleted file mode 100644 index 5d057c0..0000000 --- a/external/badvpn_dns/lime/metagrammar +++ /dev/null @@ -1,58 +0,0 @@ -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# This is the grammar for all other grammar files that will work with the -# Lime LALR(1) Context-Free Grammar Parser Generator. -# You can read this to get an idea how things work, but this file is not -# actually used in the system. Rather, it's an implementation guide for the -# file "lime.bootstrap". - -%class lime_metaparser -%start grammar - -grammar -= {$$ = new lime();} -| grammar/$ pragma/p toklist/t stop {$$->pragma($p, $t);} -| grammar/$ rewrite/r stop {$r->update($$);} -. - -rewrite -= sym/s '=' rhs/r {$$ = new lime_rewrite($s); $$->add_rhs($r);} -| rewrite/$ '|' rhs/r {$$->add_rhs($r);} -. - -slot -= action/a {$$ = new lime_action($a, NULL);} -| action/a lambda/l {$$ = new lime_action($a, $l);} -| sym/s {$$ = new lime_glyph($s, NULL);} -| sym/s lambda/l {$$ = new lime_glyph($s, $l);} -| lit/l {$$ = new lime_glyph($l, NULL);} -. - -rhs -= {$$ = new lime_rhs();} -| rhs/$ slot/s {$$->add($s);} -. - -action = '{' code/$ '}' . - -toklist = {$$=array();} -| toklist/$ sym/s {$$[] = $s;} -| toklist/$ lit/l {$$[] = $l;} -. - -code = {} -| code/$ php/p {$$.=$p;} -| code/$ '{' code/c '}' {$$.='{'.$c.'}';} -. diff --git a/external/badvpn_dns/lime/parse_engine.php b/external/badvpn_dns/lime/parse_engine.php deleted file mode 100644 index fd54cc4..0000000 --- a/external/badvpn_dns/lime/parse_engine.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -define('LIME_CALL_PROTOCOL', '$tokens, &$result'); - -abstract class lime_parser { -} - -class parse_error extends Exception {} # If this happens, the input doesn't match the grammar. -class parse_bug extends Exception {} # If this happens, I made a mistake. - -class parse_unexpected_token extends parse_error { - function __construct($type, $state) { - parent::__construct("Unexpected token of type ($type)"); - $this->type = $type; - $this->state = $state; - } -} -class parse_premature_eof extends parse_error { - function __construct() { - parent::__construct("Premature EOF"); - } -} - - -class parse_stack { - function __construct($qi) { - $this->q = $qi; - $this->qs = array(); - $this->ss = array(); - } - function shift($q, $semantic) { - $this->ss[] = $semantic; - $this->qs[] = $this->q; - $this->q = $q; - # echo "Shift $q -- $semantic<br/>\n"; - } - function top_n($n) { - if (!$n) return array(); - return array_slice($this->ss, 0-$n); - } - function pop_n($n) { - if (!$n) return array(); - $qq = array_splice($this->qs, 0-$n); - $this->q = $qq[0]; - return array_splice($this->ss, 0-$n); - } - function occupied() { return !empty($this->ss); } - function index($n) { - if ($n) $this->q = $this->qs[count($this->qs)-$n]; - } - function text() { - return $this->q." : ".implode(' . ', array_reverse($this->qs)); - } -} -class parse_engine { - function __construct($parser) { - $this->parser = $parser; - $this->qi = $parser->qi; - $this->rule = $parser->a; - $this->step = $parser->i; - #$this->prepare_callables(); - $this->reset(); - #$this->debug = false; - } - function reset() { - $this->accept = false; - $this->stack = new parse_stack($this->qi); - } - private function enter_error_tolerant_state() { - while ($this->stack->occupied()) { - if ($this->has_step_for('error')) return true; - $this->drop(); - }; - return false; - } - private function drop() { $this->stack->pop_n(1); } - function eat_eof() { - {/* - - So that I don't get any brilliant misguided ideas: - - The "accept" step happens when we try to eat a start symbol. - That happens because the reductions up the stack at the end - finally (and symetrically) tell the parser to eat a symbol - representing what they've just shifted off the end of the stack - and reduced. However, that doesn't put the parser into any - special different state. Therefore, it's back at the start - state. - - That being said, the parser is ready to reduce an EOF to the - empty program, if given a grammar that allows them. - - So anyway, if you literally tell the parser to eat an EOF - symbol, then after it's done reducing and accepting the prior - program, it's going to think it has another symbol to deal with. - That is the EOF symbol, which means to reduce the empty program, - accept it, and then continue trying to eat the terminal EOF. - - This infinte loop quickly runs out of memory. - - That's why the real EOF algorithm doesn't try to pretend that - EOF is a terminal. Like the invented start symbol, it's special. - - Instead, we pretend to want to eat EOF, but never actually - try to get it into the parse stack. (It won't fit.) In short, - we look up what reduction is indicated at each step in the - process of rolling up the parse stack. - - The repetition is because one reduction is not guaranteed to - cascade into another and clean up the entire parse stack. - Rather, it will instead shift each partial production as it - is forced to completion by the EOF lookahead. - */} - - # We must reduce as if having read the EOF symbol - do { - # and we have to try at least once, because if nothing - # has ever been shifted, then the stack will be empty - # at the start. - list($opcode, $operand) = $this->step_for('#'); - switch ($opcode) { - case 'r': $this->reduce($operand); break; - case 'e': $this->premature_eof(); break; - default: throw new parse_bug(); break; - } - } while ($this->stack->occupied()); - {/* - If the sentence is well-formed according to the grammar, then - this will eventually result in eating a start symbol, which - causes the "accept" instruction to fire. Otherwise, the - step('#') method will indicate an error in the syntax, which - here means a premature EOF. - - Incedentally, some tremendous amount of voodoo with the parse - stack might help find the beginning of some unfinished - production that the sentence was cut off during, but as a - general rule that would require deeper knowledge. - */} - if (!$this->accept) throw new parse_bug(); - return $this->semantic; - } - private function premature_eof() { - $seen = array(); - while ($this->enter_error_tolerant_state()) { - if (isset($seen[$this->state()])) { - // This means that it's pointless to try here. - // We're guaranteed that the stack is occupied. - $this->drop(); - continue; - } - $seen[$this->state()] = true; - - $this->eat('error', NULL); - if ($this->has_step_for('#')) { - // Good. We can continue as normal. - return; - } else { - // That attempt to resolve the error condition - // did not work. There's no point trying to - // figure out how much to slice off the stack. - // The rest of the algorithm will make it happen. - } - } - throw new parse_premature_eof(); - } - private function current_row() { return $this->step[$this->state()]; } - private function step_for($type) { - $row = $this->current_row(); - if (!isset($row[$type])) return array('e', $this->stack->q); - return explode(' ', $row[$type]); - } - private function has_step_for($type) { - $row = $this->current_row(); - return isset($row[$type]); - } - private function state() { return $this->stack->q; } - function eat($type, $semantic) { - # assert('$type == trim($type)'); - # if ($this->debug) echo "Trying to eat a ($type)\n"; - list($opcode, $operand) = $this->step_for($type); - switch ($opcode) { - case 's': - # if ($this->debug) echo "shift $type to state $operand\n"; - $this->stack->shift($operand, $semantic); - # echo $this->stack->text()." shift $type<br/>\n"; - break; - - case 'r': - $this->reduce($operand); - $this->eat($type, $semantic); - # Yes, this is tail-recursive. It's also the simplest way. - break; - - case 'a': - if ($this->stack->occupied()) throw new parse_bug('Accept should happen with empty stack.'); - $this->accept = true; - #if ($this->debug) echo ("Accept\n\n"); - $this->semantic = $semantic; - break; - - case 'e': - # This is thought to be the uncommon, exceptional path, so - # it's OK that this algorithm will cause the stack to - # flutter while the parse engine waits for an edible token. - # if ($this->debug) echo "($type) causes a problem.\n"; - if ($this->enter_error_tolerant_state()) { - $this->eat('error', NULL); - if ($this->has_step_for($type)) $this->eat($type, $semantic); - } else { - # If that didn't work, give up: - throw new parse_error("Parse Error: ($type)($semantic) not expected"); - } - break; - - default: - throw new parse_bug("Bad parse table instruction ".htmlspecialchars($opcode)); - } - } - private function reduce($rule_id) { - $rule = $this->rule[$rule_id]; - $len = $rule['len']; - $semantic = $this->perform_action($rule_id, $this->stack->top_n($len)); - #echo $semantic.br(); - if ($rule['replace']) $this->stack->pop_n($len); - else $this->stack->index($len); - $this->eat($rule['symbol'], $semantic); - } - private function perform_action($rule_id, $slice) { - # we have this weird calling convention.... - $result = null; - $method = $this->parser->method[$rule_id]; - #if ($this->debug) echo "rule $id: $method\n"; - $this->parser->$method($slice, $result); - return $result; - } -} diff --git a/external/badvpn_dns/lime/set.so.php b/external/badvpn_dns/lime/set.so.php deleted file mode 100644 index ef87c6c..0000000 --- a/external/badvpn_dns/lime/set.so.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/* -File: set.so.php -License: GPL -Purpose: We should really have a "set" data type. It's too useful. -*/ - -class set { - function __construct($list=array()) { $this->data = array_count_values($list); } - function has($item) { return isset($this->data[$item]); } - function add($item) { $this->data[$item] = true; } - function del($item) { unset($this->data[$item]); return $item;} - function all() { return array_keys($this->data); } - function one() { return key($this->data); } - function count() { return count($this->data); } - function pop() { return $this->del($this->one()); } - function union($that) { - $progress = false; - foreach ($that->all() as $item) if (!$this->has($item)) { - $this->add($item); - $progress = true; - } - return $progress; - } - function text() { - return ' { '.implode(' ', $this->all()).' } '; - } -} diff --git a/external/badvpn_dns/lwip/CHANGELOG b/external/badvpn_dns/lwip/CHANGELOG deleted file mode 100644 index 685b568..0000000 --- a/external/badvpn_dns/lwip/CHANGELOG +++ /dev/null @@ -1,3396 +0,0 @@ -HISTORY - -(CVS HEAD) - - * [Enter new changes just after this line - do not remove this line] - - ++ New features: - - 2012-03-25: Simon Goldschmidt (idea by Mason) - * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h - which are a simple wrapper to the correct lwIP include files. - - 2012-01-16: Simon Goldschmidt - * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP - - 2011-12-17: Simon Goldschmidt - * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) - (fixes bug #35061) - - 2011-09-27: Simon Goldschmidt - * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) - (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) - - 2011-09-21: Simon Goldschmidt - * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on - send (TCP only, bug #33820) - - 2011-09-21: Simon Goldschmidt - * init.c: Converted runtime-sanity-checks into compile-time checks that can - be disabled (since runtime checks can often not be seen on embedded targets) - - 2011-09-11: Simon Goldschmidt - * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file - to get a clear separation of which functions an application or port may use - (task #11281) - - 2011-09-11: Simon Goldschmidt - * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize - initial local TCP/UDP ports (so that different port ranges are used after - a reboot; bug #33818; this one added tcp_init/udp_init functions again) - - 2011-09-03: Simon Goldschmidt - * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) - - 2011-08-24: Simon Goldschmidt - * opt.h, netif.h/.c: added netif remove callback (bug #32397) - - 2011-07-26: Simon Goldschmidt - * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter - function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) - - 2011-07-21: Simon Goldschmidt (patch by hanhui) - * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: - Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. - Also added code to allow ip_forward() to forward non-broadcast packets to - the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). - - 2011-07-21: Simon Goldschmidt - * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes - ioctl/FIONREAD return the size of the next pending datagram. - - 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) - * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that - pcb->state != LISTEN - - 2011-05-25: Simon Goldschmidt - * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, - combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 - and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP - code so that the code is more readable. - - 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) - * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to - Ivan! (this is work in progress: we're just post release anyway :-) - - 2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage) - * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static - memory message - - - ++ Bugfixes: - - 2013-01-15: Simon Goldschmidt - * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order - - 2013-01-15: Simon Goldschmidt - * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning - - 2013-01-14: Simon Goldschmidt - * dns.c: fixed bug #37705 Possible memory corruption in DNS query - - 2013-01-11: Simon Goldschmidt - * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it - - 2012-09-26: Simon Goldschmidt - * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7843 Fix corner case with dhcp timeouts - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet - - 2012-08-22: Simon Goldschmidt - * memp.c: fixed bug #37166: memp_sanity check loops itself - - 2012-08-13: Simon Goldschmidt - * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start - dereferences NULL - - 2012-08-13: Simon Goldschmidt - * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps - configured but no interfaces available - - 2012-08-13: Simon Goldschmidt - * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time - - 2012-05-11: Simon Goldschmidt (patch by Marty) - * memp.c: fixed bug #36412: memp.c does not compile when - MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 - - 2012-05-08: Simon Goldschmidt - * tcp_out.c: fixed bug #36380: unsent_oversize mismatch in 1.4.1RC1 (this was - a debug-check issue only) - - 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) - * ppp.c: fixed bug #36283 (PPP struct used on header size computation and - not packed) - - 2012-05-03: Simon Goldschmidt (patch by David Empson) - * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with - zero length) - - 2012-03-27: Simon Goldschmidt - * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c - - 2012-03-27: Simon Goldschmidt (patch by Mason) - * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the - send MSS - - 2012-03-25: Simon Goldschmidt - * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed - for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 - - 2012-03-25: Simon Goldschmidt - * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space - pollution in api_msg.c and netifapi.c - - 2012-03-22: Simon Goldschmidt - * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward - - 2012-03-20: Simon Goldschmidt (patch by Mason) - * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list - - 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) - * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, - possible bug on little endian system - - 2012-02-23: Simon Goldschmidt - * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt - * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() - (bug #35541: PPP Memory Leak) - - 2012-02-16: Simon Goldschmidt - * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt (patch by Stéphane Lesage) - * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed - - 2012-02-15: Simon Goldschmidt - * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with - MEMP_MEM_MALLOC==1 - - 2012-02-12: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on - MSS > pcb->snd_wnd (by not creating segments bigger than half the window) - - 2012-02-11: Simon Goldschmidt - * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait - queue while closing - - 2012-01-22: Simon Goldschmidt - * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) - - 2012-01-21: Simon Goldschmidt - * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb - - 2012-01-20: Simon Goldschmidt - * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths - - 2012-01-20: Simon Goldschmidt - * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy - - 2011-11-25: Simon Goldschmidt - * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt - tcp_active_pcbs in some cases - - 2011-11-23: Simon Goldschmidt - * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with - '#ifndef sys_msleep' - - 2011-11-22: Simon Goldschmidt - * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when - netif is brought down - - 2011-10-28: Simon Goldschmidt - * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks - - 2011-10-23: Simon Goldschmidt - * mem.c: fixed bug #34429: possible memory corruption with - LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 - - 2011-10-18: Simon Goldschmidt - * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard - error value - - 2011-10-18: Simon Goldschmidt - * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small - windows (bug #34176 select after non-blocking send times out) - - 2011-10-18: Simon Goldschmidt - * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't - consider netif->mtu, causes slow network - - 2011-10-18: Simon Goldschmidt - * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code - - 2011-10-18: Simon Goldschmidt - * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS - - 2011-10-17: Simon Goldschmidt - * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api - - 2011-10-13: Simon Goldschmidt - * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no - zero window is received) by starting the persist timer when a zero window is - received, not when we have more data queued for sending than fits into the - window - - 2011-10-13: Simon Goldschmidt - * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex - - 2011-10-13: Simon Goldschmidt - * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is - used and not all protocols are enabled - - 2011-10-12: Simon Goldschmidt - * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 - - 2011-10-09: Simon Goldschmidt - * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect - byte value when pcb->unacked != NULL - - 2011-10-09: Simon Goldschmidt - * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong - - 2011-09-27: Simon Goldschmidt - * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... - - 2011-09-27: Simon Goldschmidt - * tcp_in.c: fixed bug #28288: Data after FIN in oos queue - - 2011-09-27: Simon Goldschmidt - * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf - - 2011-09-24: Simon Goldschmidt - * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 - - 2011-09-23: Simon Goldschmidt - * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for - the last packet including FIN can lose data - - 2011-09-22: Simon Goldschmidt - * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into - account - - 2011-09-21: Simon Goldschmidt - * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks - in init.c - - 2011-09-20: Simon Goldschmidt - * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) - - 2011-09-11: Simon Goldschmidt - * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs - (bug #34019) - - 2011-09-09: Simon Goldschmidt - * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if - udp port matches - - 2011-09-03: Simon Goldschmidt - * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet - is aggregated and sent to application - - 2011-09-01: Simon Goldschmidt - * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared - to other options - - 2011-09-01: Simon Goldschmidt - * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno - - 2011-08-24: Simon Goldschmidt - * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard - - 2011-08-24: Simon Goldschmidt - * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling - accept() on UDP connections - - 2011-08-24: Simon Goldschmidt - * sockets.h: fixed bug #34057 socklen_t should be a typedef - - 2011-08-24: Simon Goldschmidt - * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) - - 2011-08-24: Simon Goldschmidt - * dhcp.c: fixed bug #34122 dhcp: hostname can overflow - - 2011-08-24: Simon Goldschmidt - * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr - - 2011-08-22: Simon Goldschmidt - * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This - merely prevents nagle from not transmitting fast after closing.) - - 2011-07-22: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns - always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now - lwip_send() sends as much as possible for non-blocking sockets - - 2011-07-22: Simon Goldschmidt - * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented - for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level. - - 2011-07-21: Simon Goldschmidt - * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by - sending an ARP request when an ARP entry is used in the last minute before - it would time out. - - 2011-07-04: Simon Goldschmidt - * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. - - 2011-06-26: Simon Goldschmidt - * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by - updating its documentation only. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an - unaligned pointer. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" - - - -(STABLE-1.4.0) - - ++ New features: - - 2011-03-27: Simon Goldschmidt - * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and - calculate it in tcp_zero_window_probe (the only place where it was used). - - 2010-11-21: Simon Goldschmidt - * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif - (fixes bug #31525). - - 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) - * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for - IP_MULTICAST_LOOP at socket- and raw-API level. - - 2010-06-16: Simon Goldschmidt - * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow - link-layer-addressed UDP traffic to be received while a netif is down (just - like DHCP during configuration) - - 2010-05-22: Simon Goldschmidt - * many many files: bug #27352: removed packing from ip_addr_t, the packed - version is now only used in protocol headers. Added global storage for - current src/dest IP address while in input functions. - - 2010-05-16: Simon Goldschmidt - * def.h: task #10391: Add preprocessor-macros for compile-time htonl - calculation (and use them throughout the stack where applicable) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool - instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own - MEMP pool instead of the heap - - 2010-05-13: Simon Goldschmidt - * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added - new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast - packets to more than one pcb. - - 2010-05-02: Simon Goldschmidt - * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending - UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-04-30: Simon Goldschmidt - * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that - take a precalculated checksum, added pbuf_fill_chksum() to copy data - into a pbuf and at the same time calculating the checksum for that data - - 2010-04-29: Simon Goldschmidt - * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying - 2-byte-aligned IP addresses and MAC addresses - - 2010-04-28: Patch by Bill Auerbach - * ip.c: Inline generating IP checksum to save a function call - - 2010-04-14: Simon Goldschmidt - * tcpip.h/.c, timers.c: Added an overridable define to get informed when the - tcpip_thread processes messages or timeouts to implement a watchdog. - - 2010-03-28: Simon Goldschmidt - * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing - fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-03-27: Simon Goldschmidt - * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ - etharp_query to prevent unnecessary function calls (inspired by - patch #7135). - - 2010-03-20: Simon Goldschmidt - * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code - since the linker cannot do this automatically to save space. - - 2010-03-20: Simon Goldschmidt - * opt.h, etharp.c/.h: Added support for static ARP table entries - - 2010-03-14: Simon Goldschmidt - * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum - when creating TCP segments, not when (re-)transmitting them. - - 2010-03-07: Simon Goldschmidt - * sockets.c: bug #28775 (select/event_callback: only check select_cb_list - on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. - This should speed up receiving data on sockets as the select code in - event_callback is only executed when select is waiting. - - 2010-03-06: Simon Goldschmidt - * tcp_out.c: task #7013 (Create option to have all packets delivered to - netif->output in one piece): Always copy to try to create single pbufs - in tcp_write. - - 2010-03-06: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv - by not allocating a netbuf): added function netconn_recv_tcp_pbuf() - for tcp netconns to receive pbufs, not netbufs; use that function - for tcp sockets. - - 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt - * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: - Work on tcp_enqueue: Don't waste memory when chaining segments, - added option TCP_OVERSIZE to prevent creating many small pbufs when - calling tcp_write with many small blocks of data. Instead, pbufs are - allocated larger than needed and the space is used for later calls to - tcp_write. - - 2010-02-21: Simon Goldschmidt - * stats.c/.h: Added const char* name to mem- and memp-stats for easier - debugging. - - 2010-02-21: Simon Goldschmidt - * tcp.h (and usages), added tcp_impl.h: Splitted API and internal - implementation of tcp to make API usage cleare to application programmers - - 2010-02-14: Simon Goldschmidt/Stephane Lesage - * ip_addr.h: Improved some defines working on ip addresses, added faster - macro to copy addresses that cannot be NULL - - 2010-02-13: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- - blocking send operation) - - 2010-02-12: Simon Goldschmidt - * sockets.c/.h: Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - 2010-02-12: Simon Goldschmidt - * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated - memory): added autoip_set_struct() and dhcp_set_struct() to let autoip - and dhcp work with user-allocated structs instead of callin mem_malloc - - 2010-02-12: Simon Goldschmidt/Jeff Barber - * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has - SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT - - 2010-02-12: Simon Goldschmidt - * sys layer: task #10139 (Prefer statically allocated memory): converted - mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; - converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX - to let sys.h use binary semaphores instead of mutexes - as before) - - 2010-02-09: Simon Goldschmidt (Simon Kallweit) - * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 - (Restart system timeout handling) - - 2010-02-09: Simon Goldschmidt - * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into - netif.c) - loopif does not have to be created by the port any more, - just define LWIP_HAVE_LOOPIF to 1. - - 2010-02-08: Simon Goldschmidt - * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa - inet_ntoa_r/ipaddr_ntoa_r - - 2010-02-08: Simon Goldschmidt - * netif.h: Added netif_s/get_igmp_mac_filter() macros - - 2010-02-05: Simon Goldschmidt - * netif.h: Added function-like macros to get/set the hostname on a netif - - 2010-02-04: Simon Goldschmidt - * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to - make changing the actual implementation behind the typedef easier. - - 2010-02-01: Simon Goldschmidt - * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool - for allocating memory when getaddrinfo() is called. - - 2010-01-31: Simon Goldschmidt - * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse - them once instead of parsing for every option. This also removes - the need for mem_malloc from dhcp_recv and makes it possible to - correctly retrieve the BOOTP file. - - 2010-01-30: simon Goldschmidt - * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect - the sockets array. - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, api_msg.c, sockets.c: Added except set support in select - (patch #6860) - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: - Add non-blocking support for connect (partly from patch #6860), - plus many cleanups in socket & netconn API. - - 2010-01-27: Simon Goldschmidt - * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding - to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 - - 2010-01-26: Simon Goldschmidt - * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. - - 2010-01-14: Simon Goldschmidt - * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback - by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() - - 2010-01-13: Simon Goldschmidt - * mem.c: The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - (patch #6966 and bug #26133) - - 2010-01-10: Simon Goldschmidt (Bill Auerbach) - * opt.h, memp.c: patch #6822 (Add option to place memory pools in - separate arrays) - - 2010-01-10: Simon Goldschmidt - * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define - LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) - - 2009-12-31: Simon Goldschmidt - * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h - added timers.c/.h: Separated timer implementation from semaphore/mbox - implementation, moved timer implementation to timers.c/.h, timers are - now only called from tcpip_thread or by explicitly checking them. - (TASK#7235) - - 2009-12-27: Simon Goldschmidt - * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option - LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) - - - ++ Bugfixes: - - 2011-04-20: Simon Goldschmidt - * sys_arch.txt: sys_arch_timeouts() is not needed any more. - - 2011-04-13: Simon Goldschmidt - * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by - using ports in the IANA private/dynamic range (49152 through 65535). - - 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: - * etharp.h/.c: Fixed broken VLAN support. - - 2011-03-27: Simon Goldschmidt - * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp - pcbs) by checking if the pcb was bound (local_port != 0). - - 2011-03-27: Simon Goldschmidt - * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) - - 2011-03-27: Simon Goldschmidt - * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and - raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. - - 2011-03-27: Simon Goldschmidt - * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route - is present never times out) by starting retransmission timer before checking - route. - - 2011-03-22: Simon Goldschmidt - * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only - calling sio_read_abort() if the file descriptor is valid. - - 2011-03-14: Simon Goldschmidt - * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect - more than once can render a socket useless) since it mainly involves changing - "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. - - 2011-03-13: Simon Goldschmidt - * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing - err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: - use EALRADY instead of -1 - - 2011-03-13: Simon Goldschmidt - * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the - connection has been aborted by err_tcp (since this is not a normal closing - procedure). - - 2011-03-13: Simon Goldschmidt - * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind - with pcb->state != CLOSED - - 2011-02-17: Simon Goldschmidt - * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in - documentation - - 2011-02-17: Simon Goldschmidt - * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. - - 2011-01-24: Simon Goldschmidt - * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems - - 2010-12-02: Simon Goldschmidt - * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. - - 2010-11-23: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for - LWIP_SO_RCVBUF and ioctl/FIONREAD. - - 2010-11-23: Simon Goldschmidt - * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at - least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. - - 2010-11-23: Simon Goldschmidt - * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after - refusing 'refused_data' again. - - 2010-11-22: Simon Goldschmidt - * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS - after a successful nonblocking connection. - - 2010-11-22: Simon Goldschmidt - * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr - must be sent link-local - - 2010-11-22: Simon Goldschmidt - * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for - LWIP_TIMERS==0 - - 2010-11-20: Simon Goldschmidt - * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number - - 2010-11-20: Simon Goldschmidt - * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to - resemble other stacks. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else - no-copy TCP writes will never succeed. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does - not match documentation: return ERR_ARG instead of ERR_VAL if not - initialized or wrong argument. - - 2010-10-20: Simon Goldschmidt - * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 - - 2010-10-05: Simon Goldschmidt - * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when - replugging the network cable after an AutoIP address was assigned. - - 2010-08-10: Simon Goldschmidt - * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs - - 2010-08-03: Simon Goldschmidt - * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) - - 2010-08-01: Simon Goldschmidt (patch by Greg Renda) - * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big - endian architectures) - - 2010-07-28: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP - disabled. - - 2010-07-27: Simon Goldschmidt - * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no - harm but never did anything - - 2010-07-21: Simon Goldschmidt - * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not - add IP options) - - 2010-07-16: Kieran Mansley - * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator - - 2010-07-10: Simon Goldschmidt - * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options - - 2010-06-30: Simon Goldschmidt - * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in - netconn_delete) - - 2010-06-28: Kieran Mansley - * timers.c remove unportable printing of C function pointers - - 2010-06-24: Simon Goldschmidt - * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag - NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading - - 2010-06-24: Simon Goldschmidt - * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly - implemented shutdown at socket level. - - 2010-06-21: Simon Goldschmidt - * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has - problems with zero-copy DMA MACs) by adding custom pbufs and implementing - custom pbufs that reference other (original) pbufs. Additionally set - IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. - - 2010-06-15: Simon Goldschmidt - * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses - - 2010-06-14: Simon Goldschmidt - * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses - - 2010-06-12: Simon Goldschmidt - * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop - state - - 2010-05-17: Simon Goldschmidt - * netdb.c: Correctly NULL-terminate h_addr_list - - 2010-05-16: Simon Goldschmidt - * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent - "symbol already defined" i.e. when linking to winsock - - 2010-05-05: Simon Goldschmidt - * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may - overflow) - - 2010-04-21: Simon Goldschmidt - * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening - connection) - - 2010-03-28: Luca Ceresoli - * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers - - 2010-03-27: Luca Ceresoli - * mib2.c: patch #7130: remove meaningless const qualifiers - - 2010-03-26: Simon Goldschmidt - * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too - - 2010-03-26: Simon Goldschmidt - * various files: Fixed compiling with different options disabled (TCP/UDP), - triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled - - 2010-03-25: Simon Goldschmidt - * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly - - 2010-03-25: Simon Goldschmidt - * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side - overrunning our rcv_wnd in ooseq case. - - 2010-03-22: Simon Goldschmidt - * tcp.c: tcp_listen() did not copy the pcb's prio. - - 2010-03-19: Simon Goldschmidt - * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set - - 2010-03-14: Simon Goldschmidt - * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports - where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h - and basing PBUF_LINK_HLEN on it. - - 2010-03-08: Simon Goldschmidt - * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections - when assiging routable address): when checking incoming packets and - aborting existing connection on address change, filter out link-local - addresses. - - 2010-03-06: Simon Goldschmidt - * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING - - 2010-03-06: Simon Goldschmidt - * ipv4/ip.c: Don't try to forward link-local addresses - - 2010-03-06: Simon Goldschmidt - * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- - addresses to gw - - 2010-03-05: Simon Goldschmidt - * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type - and state. - - 2010-03-05: Simon Goldschmidt - * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split - into multiple calls to tcp_write. - - 2010-02-21: Simon Goldschmidt - * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep - the implementation of DNS_USES_STATIC_BUF==1) - - 2010-02-20: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement - close() vs. shutdown(). Now the application does not get any more - recv callbacks after calling tcp_close(). Added tcp_shutdown(). - - 2010-02-19: Simon Goldschmidt - * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent - confusion with realloc() - - 2010-02-15: Simon Goldschmidt/Stephane Lesage - * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK - (fixes bug #28899) - - 2010-02-14: Simon Goldschmidt - * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with - LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and - admin-status of a netif are up - - 2010-02-14: Simon Goldschmidt - * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet - reception and is not really necessary - - 2010-02-14: Simon Goldschmidt - * etharp.c/.h: Fixed ARP input processing: only add a new entry if a - request was directed as us (RFC 826, Packet Reception), otherwise - only update existing entries; internalized some functions - - 2010-02-14: Simon Goldschmidt - * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be - disabled on netif used for PPPoE) by adding a new netif flag - (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet - device but prevents usage of ARP (so that ethernet_input can be used - for PPPoE). - - 2010-02-12: Simon Goldschmidt - * netif.c: netif_set_link_up/down: only do something if the link state - actually changes - - 2010-02-12: Simon Goldschmidt/Stephane Lesage - * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking - connect) - - 2010-02-12: Simon Goldschmidt - * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) - - 2010-02-09: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 - (recv() makes receive window update for data that wasn't received by - application) - - 2010-02-09: Simon Goldschmidt/Stephane Lesage - * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out - or any netconn_recv() error) - - 2010-02-09: Simon Goldschmidt - * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) - - 2010-02-09: Simon Goldschmidt - * netif.c: For loopback packets, adjust the stats- and snmp-counters - for the loopback netif. - - 2010-02-08: Simon Goldschmidt - * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity - since they are not used anywhere else. - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats - (patch from bug #28798) - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and - another bug when LWIP_RAND() returns zero. - - 2010-02-04: Simon Goldschmidt - * nearly every file: Use macros defined in ip_addr.h (some of them new) - to work with IP addresses (preparation for bug #27352 - Change ip_addr - from struct to typedef (u32_t) - and better code). - - 2010-01-31: Simon Goldschmidt - * netif.c: Don't call the link-callback from netif_set_up/down() since - this invalidly retriggers DHCP. - - 2010-01-29: Simon Goldschmidt - * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the - portability file inet.h and its contents from the stack: moved htonX- - functions to def.h (and the new def.c - they are not ipv4 dependent), - let inet.h depend on ip_addr.h and not the other way round. - This fixes bug #28732. - - 2010-01-28: Kieran Mansley - * tcp.c: Ensure ssthresh >= 2*MSS - - 2010-01-27: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv - callback can lead to accessing unallocated memory. As a consequence, - ERR_ABRT means the application has called tcp_abort()! - - 2010-01-25: Simon Goldschmidt - * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY - not implemented in SNMP): write-only or not-accessible are still - returned by getnext (though not by get) - - 2010-01-24: Simon Goldschmidt - * snmp: Renamed the private mib node from 'private' to 'mib_private' to - not use reserved C/C++ keywords - - 2010-01-23: Simon Goldschmidt - * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less - than 1 ms - - 2010-01-21: Simon Goldschmidt - * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called - if tcp_enqueue fails) both in raw- and netconn-API - - 2010-01-19: Simon Goldschmidt - * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp - - 2010-01-18: Iordan Neshev/Simon Goldschmidt - * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some - bugfix backports from 2.4.x. - - 2010-01-18: Simon Goldschmidt - * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong - - 2010-01-17: Simon Goldschmidt - * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): - task #10102: "netconn: clean up conn->err threading issues" by adding - error return value to struct api_msg_msg - - 2010-01-17: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() - to return err_t (bugs #27709 and #28087) - - 2010-01-14: Simon Goldschmidt - * ...: Use typedef for function prototypes throughout the stack. - - 2010-01-13: Simon Goldschmidt - * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive - window = 0) by correctly draining recvmbox/acceptmbox - - 2010-01-11: Simon Goldschmidt - * pap.c: Fixed bug #13315 (PPP PAP authentication can result in - erroneous callbacks) by copying the code from recent pppd - - 2010-01-10: Simon Goldschmidt - * raw.c: Fixed bug #28506 (raw_bind should filter received packets) - - 2010-01-10: Simon Goldschmidt - * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) - - 2010-01-08: Simon Goldschmidt - * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) - - 2010-01-08: Simon Goldschmidt - * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string - passed to dns_local_addhost() might be volatile - - 2010-01-07: Simon Goldschmidt - * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too - - 2010-01-06: Simon Goldschmidt - * netdb.h: Fixed bug #28496: missing include guards in netdb.h - - 2009-12-31: Simon Goldschmidt - * many ppp files: Reorganised PPP source code from ucip structure to pppd - structure to easily compare our code against the pppd code (around v2.3.1) - - 2009-12-27: Simon Goldschmidt - * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted - unit test - - -(STABLE-1.3.2) - - ++ New features: - - 2009-10-27 Simon Goldschmidt/Stephan Lesage - * netifapi.c/.h: Added netifapi_netif_set_addr() - - 2009-10-07 Simon Goldschmidt/Fabian Koch - * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to - support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) - - 2009-08-26 Simon Goldschmidt/Simon Kallweit - * slipif.c/.h: bug #26397: SLIP polling support - - 2009-08-25 Simon Goldschmidt - * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), - New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. - - 2009-08-25 Simon Goldschmidt - * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) - - 2009-08-24 Jakob Stoklund Olesen - * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond - to netif_set_link_up(). - - 2009-08-23 Simon Goldschmidt - * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state - to a human-readable string. - - ++ Bugfixes: - - 2009-12-24: Kieran Mansley - * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing - (BUG#28241) - - 2009-12-06: Simon Goldschmidt - * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can - be statically allocated (like in ucip) - - 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) - * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT - - 2009-12-03: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit - could have non-zero length - - 2009-12-02: Simon Goldschmidt - * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting - tcp_input_pcb until after calling the pcb's callbacks - - 2009-11-29: Simon Goldschmidt - * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- - sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code - - 2009-11-29: Simon Goldschmidt - * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by - queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty - - 2009-11-26: Simon Goldschmidt - * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending - segment - - 2009-11-26: Simon Goldschmidt - * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle - algorithm at PCB level - - 2009-11-22: Simon Goldschmidt - * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent - - 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) - * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when - reusing time-wait pcb - - 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) - * sockets.c: Fixed bug #28062: Data received directly after accepting - does not wake up select - - 2009-11-11: Simon Goldschmidt - * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) - - 2009-10-30: Simon Goldschmidt - * opt.h: Increased default value for TCP_MSS to 536, updated default - value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. - - 2009-10-28: Kieran Mansley - * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code - to follow algorithm from TCP/IP Illustrated - - 2009-10-27: Kieran Mansley - * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK - - 2009-10-25: Simon Goldschmidt - * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if - pcb->recv is NULL to keep rcv_wnd correct) - - 2009-10-25: Simon Goldschmidt - * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state - - 2009-10-23: Simon Goldschmidt (David Empson) - * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes - - 2009-10-21: Simon Goldschmidt - * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and - trailing 1 byte len (SYN/FIN) - - 2009-10-21: Simon Goldschmidt - * tcp_out.c: Fixed bug #27315: zero window probe and FIN - - 2009-10-19: Simon Goldschmidt - * dhcp.c/.h: Minor code simplification (don't store received pbuf, change - conditional code to assert where applicable), check pbuf length before - testing for valid reply - - 2009-10-19: Simon Goldschmidt - * dhcp.c: Removed most calls to udp_connect since they aren't necessary - when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. - - 2009-10-16: Simon Goldschmidt - * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop - valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is - enabled - - 2009-10-15: Simon Goldschmidt (Oleg Tyshev) - * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit - - 2009-10-15: Simon Goldschmidt - * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() - timeout - - 2009-10-15: Simon Goldschmidt - * autoip.c: Fixed bug #27704: autoip starts with wrong address - LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead - of network byte order - - 2009-10-11 Simon Goldschmidt (Jörg Kesten) - * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments - which are not consecutive when retransmitting unacked segments - - 2009-10-09 Simon Goldschmidt - * opt.h: Fixed default values of some stats to only be enabled if used - Fixes bug #27338: sys_stats is defined when NO_SYS = 1 - - 2009-08-30 Simon Goldschmidt - * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK - function" by checking for loopback before calling ip_frag - - 2009-08-25 Simon Goldschmidt - * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27078: Possible memory leak in pppInit() - - 2009-08-23 Simon Goldschmidt - * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result - is error. - - 2009-08-23 Simon Goldschmidt - * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF - Fixed wrong parenthesis, added check in init.c - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms - - 2009-08-23 Simon Goldschmidt - * many ppp files: bug #27267: Added include to string.h where needed - - 2009-08-23 Simon Goldschmidt - * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) - - -(STABLE-1.3.1) - - ++ New features: - - 2009-05-10 Simon Goldschmidt - * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option - LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only - one pbuf to help MACs that don't support scatter-gather DMA. - - 2009-05-09 Simon Goldschmidt - * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming - ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - - 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen - * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive - extended info about the currently received packet. - - 2009-04-27 Simon Goldschmidt - * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 - - 2009-04-25 Simon Goldschmidt - * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next - bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). - - 2009-04-21 Simon Goldschmidt - * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static - hosts table. New configuration options DNS_LOCAL_HOSTLIST and - DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined - as an external function for lookup. - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for - TCP timestamp options, off by default. Rework tcp_enqueue() to - take option flags rather than specified option data - - 2009-02-18 Simon Goldschmidt - * cc.h: Added printf formatter for size_t: SZT_F - - 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) - * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast - pings - - 2009-02-12 Simon Goldschmidt - * init.h: Added LWIP_VERSION to get the current version of the stack - - 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) - * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead - of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc - is otherwise used) - - 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) - * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() - is only used by UDPLITE at present, so conditionalise it. - - 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) - * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP - "seed" address. This should reduce AUTOIP conflicts if - LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. - - 2008-10-02 Jonathan Larmour and Rishi Khan - * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking - socket. - - 2008-06-30 Simon Goldschmidt - * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from - interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows - mem_free to run between mem_malloc iterations. Added illegal counter for - mem stats. - - 2008-06-27 Simon Goldschmidt - * stats.h/.c, some other files: patch #6483: stats module improvement: - Added defines to display each module's statistic individually, added stats - defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. - - 2008-06-17 Simon Goldschmidt - * err.h: patch #6459: Made err_t overridable to use a more efficient type - (define LWIP_ERR_T in cc.h) - - 2008-06-17 Simon Goldschmidt - * slipif.c: patch #6480: Added a configuration option for slipif for symmetry - to loopif - - 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) - * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly - modified version of patch # 6370: Moved loopif code to netif.c so that - loopback traffic is supported on all netifs (all local IPs). - Added option to limit loopback packets for each netifs. - - - ++ Bugfixes: - 2009-08-12 Kieran Mansley - * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when - out of window or out of order properly - - 2009-08-12 Kieran Mansley - * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 - - 2009-07-28 Simon Goldschmidt - * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s - - 2009-07-27 Kieran Mansley - * api.h api_msg.h netdb.h sockets.h: add missing #include directives - - 2009-07-09 Kieran Mansley - * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for - recv_avail and don't increment counters until message successfully - sent to mbox - - 2009-06-25 Kieran Mansley - * api_msg.c api.h: BUG26722: initialise netconn write variables - in netconn_alloc - - 2009-06-25 Kieran Mansley - * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set - - 2009-06-25 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct - simultaneous close behaviour, and make snd_nxt have the same meaning - as in the RFCs. - - 2009-05-12 Simon Goldschmidt - * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on - arp_table / uses etharp_query" by adding etharp_gratuitous() - - 2009-05-12 Simon Goldschmidt - * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options - to the IP header (used by igmp_ip_output_if) - - 2009-05-06 Simon Goldschmidt - * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if - defined) for SWAP_BYTES_IN_WORD to speed up checksumming. - - 2009-05-05 Simon Goldschmidt - * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() - to crash - - 2009-05-04 Simon Goldschmidt - * init.c: snmp was not initialized in lwip_init() - - 2009-05-04 Frédéric Bernon - * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. - - 2009-05-03 Simon Goldschmidt - * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full - (and unsent->next == NULL) - - 2009-05-02 Simon Goldschmidt - * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after - 1.3.0 in CVS only) - fixes compilation of ppp_oe.c - - 2009-05-02 Simon Goldschmidt - * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields - - 2009-05-01 Simon Goldschmidt - * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets - - 2009-05-01 Simon Goldschmidt - * ppp.c: bug #24228: Memory corruption with PPP and DHCP - - 2009-04-29 Frédéric Bernon - * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the - SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception - of broadcast packets even when this option wasn't set. Port maintainers - which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. - If you want this option also filter broadcast on recv operations, you also - have to set IP_SOF_BROADCAST_RECV=1 in opt.h. - - 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen - * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and - DHCP/AUTOIP cooperation - - 2009-04-25 Simon Goldschmidt, Oleg Tyshev - * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd - Fixed by sorting the unsent and unacked queues (segments are inserted at the - right place in tcp_output and tcp_rexmit). - - 2009-04-25 Simon Goldschmidt - * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation - when debugging": memp_sizes contained the wrong sizes (including sanity - regions); memp pools for MEM_USE_POOLS were too small - - 2009-04-24 Simon Goldschmidt, Frédéric Bernon - * inet.c: patch #6765: Fix a small problem with the last changes (incorrect - behavior, with with ip address string not ended by a '\0', a space or a - end of line) - - 2009-04-19 Simon Goldschmidt - * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, - pcb->err is called, not pcb->connected (with an error code). - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with - no-copy-tcpwrite": deallocate option data, only concat segments with same flags - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated - in the header pbuf, not the data pbuf) - - 2009-04-18 Simon Goldschmidt - * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() - - 2009-04-15 Simon Goldschmidt - * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp - - 2009-04-15 Simon Goldschmidt - * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in - - 2009-04-15 Simon Goldschmidt - * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function - ip_hinted_output() (for smaller code mainly) - - 2009-04-15 Simon Goldschmidt - * inet.c: patch #6765: Supporting new line characters in inet_aton() - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; - Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu - is big enough in dhcp_start - - 2009-04-15 Simon Goldschmidt - * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak - - 2009-04-15 Simon Goldschmidt - * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY - - 2009-04-15 Simon Goldschmidt - * sockets.c: bug #26121: set_errno can be overridden - - 2009-04-09 Kieran Mansley (patch from Luca Ceresoli <lucaceresoli>) - * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when - LWIP_TCP==0 - - 2009-04-09 Kieran Mansley (patch from Roy Lee <roylee17>) - * tcp.h: Patch#6802 Add do-while-clauses to those function like - macros in tcp.h - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window - updates are calculated and sent (BUG20515) - - * tcp_in.c: cope with SYN packets received during established states, - and retransmission of initial SYN. - - * tcp_out.c: set push bit correctly when tcp segments are merged - - 2009-03-27 Kieran Mansley - * tcp_out.c set window correctly on probes (correcting change made - yesterday) - - 2009-03-26 Kieran Mansley - * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping - connections where no reset required (bug #25622) - - * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes - (bug #20779) - - 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) - * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be - too small depending on MEM_ALIGNMENT - - 2009-02-16 Simon Goldschmidt - * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; - converted size argument of netconn_write to 'size_t' - - 2009-02-16 Simon Goldschmidt - * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host - by moving accept callback function pointer to TCP_PCB_COMMON - - 2009-02-12 Simon Goldschmidt - * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" - option) - - 2009-02-11 Simon Goldschmidt - * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) - - 2009-02-11 Simon Goldschmidt - * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: - RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) - - 2009-02-10 Simon Goldschmidt - * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: - Accepts_pending is decrease on a corresponding listen pcb when a connection - in state SYN_RCVD is close. - - 2009-01-28 Jonathan Larmour - * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run - out of pool pbufs. - - 2008-12-19 Simon Goldschmidt - * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 - - 2008-12-10 Tamas Somogyi, Frédéric Bernon - * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and - port uses deleted netbuf. - - 2008-10-18 Simon Goldschmidt - * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length - in tcp_parseopt - - 2008-10-15 Simon Goldschmidt - * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers - by packing the struct ip_reass_helper. - - 2008-10-03 David Woodhouse, Jonathan Larmour - * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. - - 2008-10-02 Jonathan Larmour - * dns.c: Hard-code structure sizes, to avoid issues on some compilers where - padding is included. - - 2008-09-30 Jonathan Larmour - * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an - assertion check that addrlen isn't NULL. - - 2008-09-30 Jonathan Larmour - * tcp.c: Fix bug #24227, wrong error message in tcp_bind. - - 2008-08-26 Simon Goldschmidt - * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and - inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h - - 2008-08-14 Simon Goldschmidt - * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when - tcp_close returns != ERR_OK) - - 2008-07-08 Frédéric Bernon - * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters - in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). - - 2008-06-24 Jonathan Larmour - * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused - if tcp_seg_copy fails. - - 2008-06-17 Simon Goldschmidt - * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) - and created defines for swapping bytes and folding u32 to u16. - - 2008-05-30 Kieran Mansley - * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd - rather than rcv_ann_wnd when deciding if packets are in-window. - Contributed by arasmussen@consultant.datasys.swri.edu - - 2008-05-30 Kieran Mansley - * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow - passing as function pointers when MEM_LIBC_MALLOC is defined. - - 2008-05-09 Jonathan Larmour - * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to - stop it being treated as a fatal error. - - 2008-04-15 Simon Goldschmidt - * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP - (flag now cleared) - - 2008-03-27 Simon Goldschmidt - * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free - from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 - in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs - or heap memory from interrupt context - - 2008-03-26 Simon Goldschmidt - * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote - host sent a zero mss as TCP option. - - -(STABLE-1.3.0) - - ++ New features: - - 2008-03-10 Jonathan Larmour - * inet_chksum.c: Allow choice of one of the sample algorithms to be - made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. - - 2008-01-22 Frédéric Bernon - * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in - TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. - - 2008-01-14 Frédéric Bernon - * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable - to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the - tcp_recv callback (see rawapi.txt). - - 2008-01-14 Frédéric Bernon, Marc Chaland - * ip.c: Integrate patch #6369" ip_input : checking before realloc". - - 2008-01-12 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::sem per netconn::op_completed like suggested for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-12 Frédéric Bernon - * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, - DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues - sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 - "Add return value to sys_mbox_post". tcpip_callback is always defined as - "blocking" ("block" parameter = 1). - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-05 Frédéric Bernon - * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: - Introduce changes for task #7490 "Add return value to sys_mbox_post" with some - modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which - indicate the number of pointers query by the mailbox. There is three defines - in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the - netconn::acceptmbox. Port maintainers, you can decide to just add this new - parameter in your implementation, but to ignore it to keep the previous behavior. - The new sys_mbox_trypost function return a value to know if the mailbox is - full or if the message is posted. Take a look to sys_arch.txt for more details. - This new function is used in tcpip_input (so, can be called in an interrupt - context since the function is not blocking), and in recv_udp and recv_raw. - - 2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, - tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the - "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add - documentation in the rawapi.txt file. - - 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer - - 2007-12-31 Frédéric Bernon, Luca Ceresoli - * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets - in autoip". The change in etharp_raw could be removed, since all calls to - etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be - wrong in the future. - - 2007-12-30 Frédéric Bernon, Tom Evans - * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address - Filtering" reported by Tom Evans. - - 2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, - sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API - applications have to call 'tcp_accepted(pcb)' in their accept callback to - keep accepting new connections. - - 2007-12-13 Frédéric Bernon - * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" - by err_t type. Add a new err_t code "ERR_INPROGRESS". - - 2007-12-12 Frédéric Bernon - * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles - are the one which have ram usage. - - 2007-12-05 Frédéric Bernon - * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static - set of variables (=0) or a local one (=1). In this last case, your port should - provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" - which have to do a copy of "h" and return a pointer ont the "per-thread" copy. - - 2007-12-03 Simon Goldschmidt - * ip.c: ip_input: check if a packet is for inp first before checking all other - netifs on netif_list (speeds up packet receiving in most cases) - - 2007-11-30 Simon Goldschmidt - * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access - UDP: move a (connected) pcb selected for input to the front of the list of - pcbs so that it is found faster next time. Same for RAW pcbs that have eaten - a packet. - - 2007-11-28 Simon Goldschmidt - * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS - - 2007-11-25 Simon Goldschmidt - * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy - algorithm. - - 2007-11-24 Simon Goldschmidt - * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c - to the new file netdb.c; included lwip_getaddrinfo. - - 2007-11-21 Simon Goldschmidt - * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss - based on the MTU of the netif used to send. Enabled by default. Disable by - setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. - - 2007-11-19 Frédéric Bernon - * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name - received match the name query), implement DNS_USES_STATIC_BUF (the place where - copy dns payload to parse the response), return an error if there is no place - for a new query, and fix some minor problems. - - 2007-11-16 Simon Goldschmidt - * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c - removed files: core/inet.c, core/inet6.c - Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into - inet and chksum part; changed includes in all lwIP files as appropriate - - 2007-11-16 Simon Goldschmidt - * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential - dns resolver function for netconn api (netconn_gethostbyname) and socket api - (gethostbyname/gethostbyname_r). - - 2007-11-15 Jim Pettinato, Frédéric Bernon - * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name - requests with RAW api interface. Initialization is done in lwip_init() with - build time options. DNS timer is added in tcpip_thread context. DHCP can set - DNS server ip addresses when options are received. You need to set LWIP_DNS=1 - in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get - some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" - list with points to improve. - - 2007-11-06 Simon Goldschmidt - * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly - enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status - for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. - - 2007-11-06 Simon Goldschmidt - * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include - core header files in api.h (ip/tcp/udp/raw.h) to hide the internal - implementation from netconn api applications. - - 2007-11-03 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & - RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled - by default). Netconn API users can use the netconn_recv_bufsize macro to access - it. This is a first release which have to be improve for TCP. Note it used the - netconn::recv_avail which need to be more "thread-safe" (note there is already - the problem for FIONREAD with lwip_ioctl/ioctlsocket). - - 2007-11-01 Frédéric Bernon, Marc Chaland - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: - Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api - layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api - layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. - Note that previous "copy" parameter for "write" APIs is now called "apiflags". - - 2007-10-24 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than - TCP_EVENT_xxx macros to get a code more readable. It could also help to remove - some code (like we have talk in "patch #5919 : Create compile switch to remove - select code"), but it could be done later. - - 2007-10-08 Simon Goldschmidt - * many files: Changed initialization: many init functions are not needed any - more since we now rely on the compiler initializing global and static - variables to zero! - - 2007-10-06 Simon Goldschmidt - * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY - to enqueue the received pbufs so that multiple packets can be reassembled - simultaneously and no static reassembly buffer is needed. - - 2007-10-05 Simon Goldschmidt - * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so - all netifs (or ports) can use it. - - 2007-10-05 Frédéric Bernon - * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the - common function to reduce a little bit the footprint (for all functions using - only the "netif" parameter). - - 2007-10-03 Frédéric Bernon - * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, - netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce - a little bit the footprint (for all functions using only the "netif" parameter). - - 2007-09-15 Frédéric Bernon - * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF - option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for - netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for - IP_MULTICAST_TTL and IP_MULTICAST_IF. - - 2007-09-10 Frédéric Bernon - * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles - even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() - each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can - decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but - call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() - or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. - This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside - snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only - when it's queried (any direct call to "sysuptime" is changed by a call to - snmp_get_sysuptime). - - 2007-09-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, - and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags - if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). - igmp_report_groups() is now called inside netif_set_link_up() (need to have - LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait - the next query message to receive the matching multicast streams). - - 2007-09-08 Frédéric Bernon - * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains - IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). - Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). - Enable to access to these fields with LWIP_TCP=0. - - 2007-09-05 Frédéric Bernon - * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, - ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option - LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). - Be careful, disabling ICMP make your product non-compliant to RFC1122, but - help to reduce footprint, and to reduce "visibility" on the Internet. - - 2007-09-05 Frédéric Bernon, Bill Florac - * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list - for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new - parameters have to be provided: a task name, and a task stack size. For this - one, since it's platform dependant, you could define the best one for you in - your lwipopts.h. For port maintainers, you can just add these new parameters - in your sys_arch.c file, and but it's not mandatory, use them in your OS - specific functions. - - 2007-09-05 Frédéric Bernon - * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings - inside init.c for task #7142 "Sanity check user-configurable values". - - 2007-09-04 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by - memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the - value). It will avoid potential fragmentation problems, use a counter to know - how many times a group is used on an netif, and free it when all applications - leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity - check if LWIP_IGMP!=0). - - 2007-09-03 Frédéric Bernon - * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". - Initialize igmp_mac_filter to NULL in netif_add (this field should be set in - the netif's "init" function). Use the "imr_interface" field (for socket layer) - and/or the "interface" field (for netconn layer), for join/leave operations. - The igmp_join/leavegroup first parameter change from a netif to an ipaddr. - This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). - - 2007-08-30 Frédéric Bernon - * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions - from api/api_lib". Now netbuf API is independant of netconn, and can be used - with other API (application based on raw API, or future "socket2" API). Ports - maintainers just have to add src/api/netbuf.c in their makefile/projects. - - 2007-08-30 Frédéric Bernon, Jonathan Larmour - * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check - user-configurable values". - - 2007-08-29 Frédéric Bernon - * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. - igmp_start is call inside netif_add. Now, igmp initialization is in the same - spirit than the others modules. Modify some IGMP debug traces. - - 2007-08-29 Frédéric Bernon - * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" - Add lwip_init function to regroup all modules initializations, and to provide - a place to add code for task #7142 "Sanity check user-configurable values". - Ports maintainers should remove direct initializations calls from their code, - and add init.c in their makefiles. Note that lwip_init() function is called - inside tcpip_init, but can also be used by raw api users since all calls are - disabled when matching options are disabled. Also note that their is new options - in opt.h, you should configure in your lwipopts.h (they are enabled per default). - - 2007-08-26 Marc Boucher - * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL - since they can under certain circumstances be called with an invalid conn - pointer after the connection has been closed (and conn has been freed). - - 2007-08-25 Frédéric Bernon (Artem Migaev's Patch) - * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". - Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. - - 2007-08-22 Frédéric Bernon - * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK - to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. - - 2007-08-22 Frédéric Bernon - * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & - ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the - name is tcpip_input (we keep the name of 1.2.0 function). - - 2007-08-17 Jared Grubb - * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool - settings into new memp_std.h and optional user file lwippools.h. This adds - more dynamic mempools, and allows the user to create an arbitrary number of - mempools for mem_malloc. - - 2007-08-16 Marc Boucher - * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; - otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely - close the connection. - - 2007-08-16 Marc Boucher - * sockets.c: lwip_accept(): check netconn_peer() error return. - - 2007-08-16 Marc Boucher - * mem.c, mem.h: Added mem_calloc(). - - 2007-08-16 Marc Boucher - * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) - for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG - and starving other message types. - Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API - - 2007-08-16 Marc Boucher - * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf - type and flgs (later renamed to flags). - Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. - Improved lwip_recvfrom(). TCP push now propagated. - - 2007-08-16 Marc Boucher - * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global - provided by etharp. - - 2007-08-16 Marc Boucher - * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, - etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: - Added PPPoE support and various PPP improvements. - - 2007-07-25 Simon Goldschmidt - * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, - making netbuf_copy_partial use this function. - - 2007-07-25 Simon Goldschmidt - * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with - 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and - other stacks. - - 2007-07-13 Jared Grubb (integrated by Frédéric Bernon) - * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add - a link callback in the netif struct, and functions to handle it. Be carefull - for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) - if you want to be sure to be compatible with future changes... - - 2007-06-30 Frédéric Bernon - * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. - - 2007-06-21 Simon Goldschmidt - * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both - LWIP_AUTOIP =0 and =1 to remove redundant code. - - 2007-06-21 Simon Goldschmidt - * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option - MEM_USE_POOLS to use 4 pools with different sized elements instead of a - heap. This both prevents memory fragmentation and gives a higher speed - at the cost of more memory consumption. Turned off by default. - - 2007-06-21 Simon Goldschmidt - * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of - netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into - int to be able to send a bigger buffer than 64K with one time (mainly - used from lwip_send). - - 2007-06-21 Simon Goldschmidt - * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write - into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. - - 2007-06-21 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in - netconn_write from api_lib.c to api_msg.c to also prevent multiple context- - changes on low memory or empty send-buffer. - - 2007-06-18 Simon Goldschmidt - * etharp.c, etharp.h: Changed etharp to use a defined hardware address length - of 6 to avoid loading netif->hwaddr_len every time (since this file is only - used for ethernet and struct eth_addr already had a defined length of 6). - - 2007-06-17 Simon Goldschmidt - * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets - to disable UDP checksum generation on transmit. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid - pointers or parameters, and let the possibility to redefined it in cc.h. Use - this macro to check "conn" parameter in api_msg.c functions. - - 2007-06-11 Simon Goldschmidt - * sockets.c, sockets.h: Added UDP lite support for sockets - - 2007-06-10 Simon Goldschmidt - * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled - by default) to switch off UDP-Lite support if not needed (reduces udp.c code - size) - - 2007-06-09 Dominik Spies (integrated by Frédéric Bernon) - * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: - AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and - LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt - (see TODO mark in the source code). - - 2007-06-09 Simon Goldschmidt - * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for - etharp_output() to match netif->output so etharp_output() can be used - directly as netif->output to save one function call. - - 2007-06-08 Simon Goldschmidt - * netif.h, ethernetif.c, slipif.c, loopif.c: Added define - NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, - added initialization of those to ethernetif, slipif and loopif. - - 2007-05-18 Simon Goldschmidt - * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF - (defaulting to off for now) that can be set to 0 to send fragmented - packets by passing PBUF_REFs down the stack. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP - connections, such present in patch #5959. - - 2007-05-23 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx - code in only one part... - - 2007-05-18 Simon Goldschmidt - * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp - elements to overflow. This is achieved by adding some bytes before and after - each pool element (increasing their size, of course), filling them with a - prominent value and checking them on freeing the element. - Set it to 2 to also check every element in every pool each time memp_malloc() - or memp_free() is called (slower but more helpful). - - 2007-05-10 Simon Goldschmidt - * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for - PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce - code size. - - 2007-05-11 Frédéric Bernon - * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: - Include a function pointer instead of a table index in the message to reduce - footprint. Disable some part of lwip_send and lwip_sendto if some options are - not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). - - 2007-05-10 Simon Goldschmidt - * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus - \ extern "C" {' in all header files. Now you can write your application using - the lwIP stack in C++ and simply #include the core files. Note I have left - out the netif/ppp/*h header files for now, since I don't know which files are - included by applications and which are for internal use only. - - 2007-05-09 Simon Goldschmidt - * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library - memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for - situations where some compilers might inline the copy and save a function - call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). - - 2007-05-08 Simon Goldschmidt - * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) - to be overriden in case the C-library malloc implementation is not protected - against concurrent access. - - 2007-05-04 Simon Goldschmidt (Atte Kojo) - * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending - multiple packets to the same host. - - 2007-05-04 Frédéric Bernon, Jonathan Larmour - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible - to corrupt remote addr/port connection state". Reduce problems "not enought memory" with - netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between - sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. - Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, - these fields are now renamed "addr" & "port". - - 2007-04-11 Jonathan Larmour - * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new - sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return - with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro - by the port in sys_arch.h if desired. - - 2007-04-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API - allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp - clients, using new functions from netifapi.h. Disable as default (no port change to do). - - 2007-04-05 Frédéric Bernon - * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. - - 2007-04-04 Simon Goldschmidt - * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) - use this for and architecture-independent form to tell the compiler you intentionally - are not using this variable. Can be overriden in cc.h. - - 2007-03-28 Frédéric Bernon - * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to - define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded - string, point on one of your's ethernetif field, or alloc a string you will free yourself). - It will be used by DHCP to register a client hostname, but can also be use when you call - snmp_set_sysname. - - 2007-03-28 Frédéric Bernon - * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to - initialize a network interface's flag with. It tell this interface is an ethernet - device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility - Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). - - 2007-03-26 Frédéric Bernon, Jonathan Larmour - * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build - time if you only use PPP or SLIP. The default is enable. Note we don't have to call - etharp_init in your port's initilization sequence if you use tcpip.c, because this call - is done in tcpip_init function. - - 2007-03-22 Frédéric Bernon - * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the - new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in - your lwipopts.h. More, unused counters are not defined in the stats structs, and not - display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined - but never used. Fix msg_in.c with the correct #if test for a stat display. - - 2007-03-21 Kieran Mansley - * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). - Provides callback on netif up/down state change. - - 2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, - ip.c, netif.h, tcpip.c, opt.h: - New configuration option LWIP_IGMP to enable IGMP processing. Based on only one - filter per all network interfaces. Declare a new function in netif to enable to - control the MAC filter (to reduce lwIP traffic processing). - - 2007-03-11 Frédéric Bernon - * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can - be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this - unless you know what you're doing (default are RFC1122 compliant). Note - that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. - - 2007-03-08 Frédéric Bernon - * tcp.h: Keepalive values can be configured at compile time, but don't change - this unless you know what you're doing (default are RFC1122 compliant). - - 2007-03-08 Frédéric Bernon - * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: - Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO - on UDP sockets/netconn. - - 2007-03-08 Simon Goldschmidt - * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. - - 2007-03-06 Frédéric Bernon - * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: - Implement SO_RCVTIMEO on UDP sockets/netconn. - - 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) - * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated - on the stack and remove the API msg type from memp - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * sockets.h, sockets.c: Move socket initialization to new - lwip_socket_init() function. - NOTE: this changes the API with ports. Ports will have to be - updated to call lwip_socket_init() now. - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * api_lib.c: Use memcpy in netbuf_copy_partial. - - - ++ Bug fixes: - - 2008-03-17 Frédéric Bernon, Ed Kerekes - * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have - some problems to fill the IP header on some targets, use now the - ip.h macros to do it). - - 2008-03-13 Frédéric Bernon - * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using - (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a - TCP connection caused a crash. Note that using (lwip_)recvfrom - like this is a bit slow and that using (lwip)getpeername is the - good lwip way to do it (so, using recv is faster on tcp sockets). - - 2008-03-12 Frédéric Bernon, Jonathan Larmour - * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's - recv_raw() does not consume data", and the ping sample (with - LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom - returned the IP payload, without the IP header). - - 2008-03-04 Jonathan Larmour - * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors - and/or warnings on some systems where mem_size_t and size_t differ. - * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. - - 2008-03-04 Kieran Mansley (contributions by others) - * Numerous small compiler error/warning fixes from contributions to - mailing list after 1.3.0 release candidate made. - - 2008-01-25 Cui hengbin (integrated by Frédéric Bernon) - * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. - - 2008-01-15 Kieran Mansley - * tcp_out.c: BUG20511. Modify persist timer to start when we are - prevented from sending by a small send window, not just a zero - send window. - - 2008-01-09 Jonathan Larmour - * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid - conflict with Linux system headers. - - 2008-01-06 Jonathan Larmour - * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP - address entirely on receiving a DHCPNAK, and restarting discovery. - - 2007-12-21 Simon Goldschmidt - * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail - is not protected" by using new macros for interlocked access to modify/test - netconn->recv_avail. - - 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) - * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) - - 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling - of silly window avoidance and prevent lwIP from shrinking the window) - - 2007-12-04 Simon Goldschmidt - * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last - data packet was lost): add assert that all segment lists are empty in - tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED - state from LAST_ACK in tcp_process - - 2007-12-02 Simon Goldschmidt - * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET - If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now - has to be set to 0 in lwipopts.h - - 2007-12-02 Simon Goldschmidt - * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always - allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen - netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. - This is a fix for thread-safety and allocates all items needed for a netconn - when the netconn is created. - - 2007-11-30 Simon Goldschmidt - * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple - netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed - to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same - port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) - - 2007-11-27 Simon Goldschmidt - * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by - letting ip_route only use netifs that are up. - - 2007-11-27 Simon Goldschmidt - * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF - and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and - sockets block most operations once they have seen a fatal error. - - 2007-11-27 Simon Goldschmidt - * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the - netif to send as an argument (to be able to send on netifs that are down). - - 2007-11-26 Simon Goldschmidt - * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs - arrive out-of-order - - 2007-11-21 Simon Goldschmidt - * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early - Fixed the nagle algorithm; nagle now also works for all raw API applications - and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' - - 2007-11-12 Frédéric Bernon - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most - of the netconn_peer and netconn_addr processing is done inside tcpip_thread - context in do_getaddr. - - 2007-11-10 Simon Goldschmidt - * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can - happen any time). Now the packet simply isn't enqueued when out of memory. - - 2007-11-01 Simon Goldschmidt - * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or - TCP_MSS if that is smaller) as long as no MSS option is received from the - remote host. - - 2007-11-01 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) - is now based on TCP_MSS instead of pcb->mss (on passive open now effectively - sending our configured TCP_MSS instead of the one received). - - 2007-11-01 Simon Goldschmidt - * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was - calculated based on the configured TCP_MSS, not on the MSS option received - with SYN+ACK. - - 2007-10-09 Simon Goldschmidt - * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too - short and also was generated wrong if checksum coverage != tot_len; - receive: checksum was calculated wrong if checksum coverage != tot_len - - 2007-10-08 Simon Goldschmidt - * mem.c: lfree was not updated in mem_realloc! - - 2007-10-07 Frédéric Bernon - * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential - crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: - this change cause an API breakage for netconn_addr, since a parameter - type change. Any compiler should cause an error without any changes in - yours netconn_peer calls (so, it can't be a "silent change"). It also - reduce a little bit the footprint for socket layer (lwip_getpeername & - lwip_getsockname use now a common lwip_getaddrname function since - netconn_peer & netconn_addr have the same parameters). - - 2007-09-20 Simon Goldschmidt - * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) - by checking tcp_tw_pcbs also - - 2007-09-19 Simon Goldschmidt - * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) - - 2007-09-15 Mike Kleshov - * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) - - 2007-09-06 Frédéric Bernon - * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove - it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which - already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" - if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. - - 2007-08-30 Frédéric Bernon - * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, - and fix some coding style. - - 2007-08-28 Frédéric Bernon - * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any - kind of packets. These packets are considered like Ethernet packets (payload - pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets - are considered like IP packets (payload pointing to iphdr). - - 2007-08-27 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error - problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state - and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). - - 2007-08-24 Kieran Mansley - * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy - compiler (Paradigm C++) - - 2007-08-09 Frédéric Bernon, Bill Florac - * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. - Introduce IGMP_STATS to centralize statistics management. - - 2007-08-09 Frédéric Bernon, Bill Florac - * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast - packet on a udp pcb binded on an netif's IP address, and not on "any". - - 2007-08-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. - This is mainly on using lookup/lookfor, and some coding styles... - - 2007-07-26 Frédéric Bernon (and "thedoctor") - * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. - - 2007-07-25 Simon Goldschmidt - * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if - tcp_output fails in tcp_close, the code in do_close_internal gets simpler - (tcp_output is called again later from tcp timers). - - 2007-07-25 Simon Goldschmidt - * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old - copy_from_pbuf, which illegally modified the given pbuf. - - 2007-07-25 Simon Goldschmidt - * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: - changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). - - 2007-07-24 Simon Goldschmidt - * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the - correct state (must be CLOSED). - - 2007-07-13 Thomas Taranowski (commited by Jared Grubb) - * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed - allocation. It now returns NULL. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in - all error cases. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, - because current code doesn't follow rawapi.txt documentation. - - 2007-07-13 Kieran Mansley - * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in - out of sequence processing of received packets - - 2007-07-03 Simon Goldschmidt - * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an - assumption is made that this pbuf is in one piece (i.e. not chained). These - assumptions clash with the possibility of converting to fully pool-based - pbuf implementations, where PBUF_RAM pbufs might be chained. - - 2007-07-03 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems - when closing tcp netconns: removed conn->sem, less context switches when - closing, both netconn_close and netconn_delete should safely close tcp - connections. - - 2007-07-02 Simon Goldschmidt - * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, - tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) - to cache ARP table indices with each pcb instead of single-entry cache for - the complete stack. - - 2007-07-02 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent - warnings when assigning to smaller types. - - 2007-06-28 Simon Goldschmidt - * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. - - 2007-06-28 Simon Goldschmidt - * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if - a segment contained chained pbufs) - - 2007-06-28 Frédéric Bernon - * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute - a "pseudo-random" value based on netif's MAC and some autoip fields. It's always - possible to define this macro in your own lwipopts.h to always use C library's - rand(). Note that autoip_create_rand_addr doesn't use this macro. - - 2007-06-28 Frédéric Bernon - * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option - LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications - in api_lib/api_msg (use pointers and not type with table, etc...) - - 2007-06-26 Simon Goldschmidt - * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload - for udp packets with no matching pcb. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match - could get udp input packets if the remote side matched. - - 2007-06-13 Simon Goldschmidt - * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get - changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. - - 2007-06-13 Simon Goldschmidt - * api_msg.c: pcb_new sets conn->err if protocol is not implemented - -> netconn_new_..() does not allocate a new connection for unsupported - protocols. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * api_lib.c: change return expression in netconn_addr and netconn_peer, because - conn->err was reset to ERR_OK without any reasons (and error was lost)... - - 2007-06-13 Frédéric Bernon, Matthias Weisser - * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename - MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid - some macro names collision with some OS macros. - - 2007-06-11 Simon Goldschmidt - * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, - create checksum over the complete packet. On RX, if it's < 8 (and not 0), - discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both - UDP & UDP Lite. - - 2007-06-11 Srinivas Gollakota & Oleg Tyshev - * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" - where TCP flags wasn't initialized in tcp_keepalive. - - 2007-06-03 Simon Goldschmidt - * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function - registered, p->payload was modified without modifying p->len if sending - icmp_dest_unreach() (had no negative effect but was definitively wrong). - - 2007-06-03 Simon Goldschmidt - * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp - re-used the input pbuf even if that didn't have enough space to include the - link headers. Now the space is tested and a new pbuf is allocated for the - echo response packet if the echo request pbuf isn't big enough. - - 2007-06-01 Simon Goldschmidt - * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. - - 2007-05-23 Frédéric Bernon - * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only - allocated by do_listen if success) and netconn_accept errors handling. In - most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" - by ASSERT, except for netconn_delete. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return - an error code if it's impossible to fetch a pbuf on a TCP connection (and not - directly close the recvmbox). - - 2007-05-22 Simon Goldschmidt - * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of - bound but unconnected (and non-listening) tcp_pcbs. - - 2007-05-22 Frédéric Bernon - * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only - used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of - sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features - like "sys_timeout" in their application threads. - - 2007-05-22 Frédéric Bernon - * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see - which parameters are used by which do_xxx function, and to avoid "misusing" - parameters (patch #5938). - - 2007-05-22 Simon Goldschmidt - * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: - changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto - is only 8 bits wide. This affects the api, as there, the protocol was - u16_t, too. - - 2007-05-18 Simon Goldschmidt - * memp.c: addition to patch #5913: smaller pointer was returned but - memp_memory was the same size -> did not save memory. - - 2007-05-16 Simon Goldschmidt - * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns - != ERR_OK. - - 2007-05-16 Simon Goldschmidt - * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same - as the one of the netif used for sending to prevent sending from old - addresses after a netif address gets changed (partly fixes bug #3168). - - 2007-05-16 Frédéric Bernon - * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work - with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in - tcpip_init) because we have to be sure that network interfaces are already - added (mac filter is updated only in igmp_init for the moment). - - 2007-05-16 Simon Goldschmidt - * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls - into sys_arch_sem_wait calls to prevent timers from running while waiting - for the heap. This fixes bug #19167. - - 2007-05-13 Simon Goldschmidt - * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines - for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from - tcp.h to sockets.h. - - 2007-05-07 Simon Goldschmidt - * mem.c: Another attempt to fix bug #17922. - - 2007-05-04 Simon Goldschmidt - * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() - implementation so that it can be reused (don't allocate the target - pbuf inside pbuf_copy()). - - 2007-05-04 Simon Goldschmidt - * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem - to save a little RAM (next pointer of memp is not used while not in pool). - - 2007-05-03 "maq" - * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. - (patch #3574). - - 2007-04-23 Simon Goldschmidt - * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results - in NULL reference for incoming TCP packets". Loopif has to be configured - (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() - (multithreading environments, e.g. netif->input() = tcpip_input()) or - putting packets on a list that is fed to the stack by calling loopif_poll() - (single-thread / NO_SYS / polling environment where e.g. - netif->input() = ip_input). - - 2007-04-17 Jonathan Larmour - * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold - the difference between two u16_t's. - * sockets.h: FD_SETSIZE needs to match number of sockets, which is - MEMP_NUM_NETCONN in sockets.c right now. - - 2007-04-12 Jonathan Larmour - * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). - - 2007-04-12 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission - timer is reset to fix bug#19434, with help from Oleg Tyshev. - - 2007-04-11 Simon Goldschmidt - * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than - previously thought need to be copied (everything but PBUF_ROM!). Cleaned up - pbuf.c: removed functions no needed any more (by etharp). - - 2007-04-11 Kieran Mansley - * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix - "Constant is long" warnings with 16bit compilers. Contributed by - avatar@mmlab.cse.yzu.edu.tw - - 2007-04-05 Frédéric Bernon, Jonathan Larmour - * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on - the mailbox is active". Now, the post is only done during a connect, and do_send, - do_write and do_join_leave_group don't do anything if a previous error was signaled. - - 2007-04-03 Frédéric Bernon - * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output - packets. See patch #5834. - - 2007-03-30 Frédéric Bernon - * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add - missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. - - 2007-03-30 Frédéric Bernon - * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with - others environment defines (these were too "generic"). - - 2007-03-28 Frédéric Bernon - * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call - result and can cause a crash. lwip_send now check netbuf_ref result. - - 2007-03-28 Simon Goldschmidt - * sockets.c Remove "#include <errno.h>" from sockets.c to avoid multiple - definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is - defined. This is the way it should have been already (looking at - doc/sys_arch.txt) - - 2007-03-28 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + - IP and TCP headers *and* physical link headers - - 2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov) - * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause - to send some garbage. It is not a definitive solution, but the patch does solve - the problem for most cases. - - 2007-03-22 Frédéric Bernon - * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). - - 2007-03-22 Frédéric Bernon - * api_lib.c: somes resources couldn't be freed if there was errors during - netconn_new_with_proto_and_callback. - - 2007-03-22 Frédéric Bernon - * ethernetif.c: update netif->input calls to check return value. In older ports, - it's a good idea to upgrade them, even if before, there could be another problem - (access to an uninitialized mailbox). - - 2007-03-21 Simon Goldschmidt - * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed - by casting to unsigned). - - 2007-03-21 Frédéric Bernon - * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from - api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a - dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. - Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a - faster and more reliable communication between api_lib and tcpip. - - 2007-03-21 Frédéric Bernon - * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. - - 2007-03-21 Frédéric Bernon - * api_msg.c, igmp.c, igmp.h: Fix C++ style comments - - 2007-03-21 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + - IP and TCP headers - - 2007-03-21 Kieran Mansley - * Fix all uses of pbuf_header to check the return value. In some - cases just assert if it fails as I'm not sure how to fix them, but - this is no worse than before when they would carry on regardless - of the failure. - - 2007-03-21 Kieran Mansley - * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and - comment out missing header include in icmp.c - - 2007-03-20 Frédéric Bernon - * memp.h, stats.c: Fix stats_display function where memp_names table wasn't - synchronized with memp.h. - - 2007-03-20 Frédéric Bernon - * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, - tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with - network interfaces. Also fix a compiler warning. - - 2007-03-20 Kieran Mansley - * udp.c: Only try and use pbuf_header() to make space for headers if - not a ROM or REF pbuf. - - 2007-03-19 Frédéric Bernon - * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() - and api_msg_post(). - - 2007-03-19 Frédéric Bernon - * Remove unimplemented "memp_realloc" function from memp.h. - - 2007-03-11 Simon Goldschmidt - * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused - memory corruption. - - 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) - * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 - (missing `const' qualifier in socket functions), to get more compatible to - standard POSIX sockets. - - 2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov) - * sockets.c: Add asserts inside bind, connect and sendto to check input - parameters. Remove excessive set_errno() calls after get_socket(), because - errno is set inside of get_socket(). Move last sock_set_errno() inside - lwip_close. - - 2007-03-09 Simon Goldschmidt - * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory - was allocated too small. - - 2007-03-06 Simon Goldschmidt - * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect - the stack from concurrent access. - - 2007-03-06 Frédéric Bernon, Dmitry Potapov - * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy - call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). - - 2007-03-06 Simon Goldschmidt - * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files - if IP_FRAG == 0 and IP_REASSEMBLY == 0 - - 2007-03-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration - option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. - Allow to do ARP processing for incoming packets inside tcpip_thread - (protecting ARP layer against concurrent access). You can also disable - old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. - Older ports have to use tcpip_ethinput. - - 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) - * err.h, err.c: fixed compiler warning "initialization dircards qualifiers - from pointer target type" - - 2007-03-05 Frédéric Bernon - * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, - ETHARP_TRUST_IP_MAC, review SO_REUSE) - - 2007-03-04 Frédéric Bernon - * api_msg.c: Remove some compiler warnings : parameter "pcb" was never - referenced. - - 2007-03-04 Frédéric Bernon - * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from - Dmitry Potapov). - The api_msg struct stay on the stack (not moved to netconn struct). - - 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) - * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if - SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) - Also fixed cast warning in pbuf_alloc() - - 2007-03-04 Simon Goldschmidt - * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt - existing pbuf chain when enqueuing multiple pbufs to a pending ARP request - - 2007-03-03 Frédéric Bernon - * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" - It is static, and never used in udp.c except udp_init(). - - 2007-03-02 Simon Goldschmidt - * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from - tcpip_thread() to tcpip_init(). This way, raw API connections can be - initialized before tcpip_thread is running (e.g. before OS is started) - - 2007-03-02 Frédéric Bernon - * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call - interval. - - 2007-02-28 Kieran Mansley - * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved - outside the region of the pbuf by pbuf_header() - - 2007-02-28 Kieran Mansley - * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero - when supplied timeout is also non-zero - -(STABLE-1.2.0) - - 2006-12-05 Leon Woestenberg - * CHANGELOG: Mention STABLE-1.2.0 release. - - ++ New features: - - 2006-12-01 Christiaan Simons - * mem.h, opt.h: Added MEM_LIBC_MALLOC option. - Note this is a workaround. Currently I have no other options left. - - 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) - * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define - to include/lwip/opt.h. - * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. - Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. - * opt.h: Add above new options. - - 2006-08-18 Christiaan Simons - * tcp_{in,out}.c: added SNMP counters. - * ipv4/ip.c: added SNMP counters. - * ipv4/ip_frag.c: added SNMP counters. - - 2006-08-08 Christiaan Simons - * etharp.{c,h}: added etharp_find_addr() to read - (stable) ethernet/IP address pair from ARP table - - 2006-07-14 Christiaan Simons - * mib_structs.c: added - * include/lwip/snmp_structs.h: added - * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct - - 2006-07-06 Christiaan Simons - * snmp/asn1_{enc,dec}.c added - * snmp/mib2.c added - * snmp/msg_{in,out}.c added - * include/lwip/snmp_asn1.h added - * include/lwip/snmp_msg.h added - * doc/snmp_agent.txt added - - 2006-03-29 Christiaan Simons - * inet.c, inet.h: Added platform byteswap support. - Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and - optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. - - ++ Bug fixes: - - 2006-11-30 Christiaan Simons - * dhcp.c: Fixed false triggers of request_timeout. - - 2006-11-28 Christiaan Simons - * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. - - 2006-10-11 Christiaan Simons - * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: - Partially accepted patch #5449 for ANSI C compatibility / build fixes. - * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol - identifier from 170 to 136 (bug #17574). - - 2006-10-10 Christiaan Simons - * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. - - 2006-08-17 Christiaan Simons - * udp.c: Fixed bug #17200, added check for broadcast - destinations for PCBs bound to a unicast address. - - 2006-08-07 Christiaan Simons - * api_msg.c: Flushing TCP output in do_close() (bug #15926). - - 2006-06-27 Christiaan Simons - * api_msg.c: Applied patch for cold case (bug #11135). - In accept_function() ensure newconn->callback is always initialized. - - 2006-06-15 Christiaan Simons - * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), - facilitate printing of mem_size_t and u16_t statistics. - - 2006-06-14 Christiaan Simons - * api_msg.c: Applied patch #5146 to handle allocation failures - in accept() by Kevin Lawson. - - 2006-05-26 Christiaan Simons - * api_lib.c: Removed conn->sem creation and destruction - from netconn_write() and added sys_sem_new to netconn_new_*. - -(STABLE-1_1_1) - - 2006-03-03 Christiaan Simons - * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap - access and added pbuf_alloc() return value checks. - - 2006-01-01 Leon Woestenberg leon.woestenberg@gmx.net - * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is - now handled by the checksum routine properly. - - 2006-02-27 Leon Woestenberg leon.woestenberg@gmx.net - * pbuf.c: Fix alignment; pbuf_init() would not work unless - pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) - - 2005-12-20 Leon Woestenberg leon.woestenberg@gmx.net - * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch - submitted by Mitrani Hiroshi. - - 2005-12-15 Christiaan Simons - * inet.c: Disabled the added summing routine to preserve code space. - - 2005-12-14 Leon Woestenberg leon.woestenberg@gmx.net - * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. - Added Curt McDowell's optimized checksumming routine for future - inclusion. Need to create test case for unaliged, aligned, odd, - even length combination of cases on various endianess machines. - - 2005-12-09 Christiaan Simons - * inet.c: Rewrote standard checksum routine in proper portable C. - - 2005-11-25 Christiaan Simons - * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. - * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, - u32_t, s32_t typedefs. This solves most debug word-length assumes. - - 2005-07-17 Leon Woestenberg leon.woestenberg@gmx.net - * inet.c: Fixed unaligned 16-bit access in the standard checksum - routine by Peter Jolasson. - * slipif.c: Fixed implementation assumption of single-pbuf datagrams. - - 2005-02-04 Leon Woestenberg leon.woestenberg@gmx.net - * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. - * tcp_{out|in}.c: Applied patch fixing unaligned access. - - 2005-01-04 Leon Woestenberg leon.woestenberg@gmx.net - * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. - - 2005-01-03 Leon Woestenberg leon.woestenberg@gmx.net - * udp.c: UDP pcb->recv() was called even when it was NULL. - -(STABLE-1_1_0) - - 2004-12-28 Leon Woestenberg leon.woestenberg@gmx.net - * etharp.*: Disabled multiple packets on the ARP queue. - This clashes with TCP queueing. - - 2004-11-28 Leon Woestenberg leon.woestenberg@gmx.net - * etharp.*: Fixed race condition from ARP request to ARP timeout. - Halved the ARP period, doubled the period counts. - ETHARP_MAX_PENDING now should be at least 2. This prevents - the counter from reaching 0 right away (which would allow - too little time for ARP responses to be received). - - 2004-11-25 Leon Woestenberg leon.woestenberg@gmx.net - * dhcp.c: Decline messages were not multicast but unicast. - * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. - Do not try hard to insert arbitrary packet's source address, - etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. - etharp_query() now always DOES call ETHARP_TRY_HARD so that users - querying an address will see it appear in the cache (DHCP could - suffer from this when a server invalidly gave an in-use address.) - * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are - comparing network addresses (identifiers), not the network masks - themselves. - * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given - IP address actually belongs to the network of the given interface. - - 2004-11-24 Kieran Mansley kjm25@cam.ac.uk - * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. - -(STABLE-1_1_0-RC1) - - 2004-10-16 Kieran Mansley kjm25@cam.ac.uk - * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, - even if one is already pending, if the rcv_wnd is above a threshold - (currently TCP_WND/2). This avoids waiting for a timer to expire to send a - delayed ACK in order to open the window if the stack is only receiving data. - - 2004-09-12 Kieran Mansley kjm25@cam.ac.uk - * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. - - 2004-08-20 Tony Mountifield tony@softins.co.uk - * etharp.c: Make sure the first pbuf queued on an ARP entry - is properly ref counted. - - 2004-07-27 Tony Mountifield tony@softins.co.uk - * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler - warnings about comparison. - * pbuf.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. Closed an unclosed comment. - * tcp.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. - * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). - * inet.c: Added a couple of casts to quiet the compiler. - No need to test isascii(c) before isdigit(c) or isxdigit(c). - - 2004-07-22 Tony Mountifield tony@softins.co.uk - * inet.c: Made data types consistent in inet_ntoa(). - Added casts for return values of checksum routines, to pacify compiler. - * ip_frag.c, tcp_out.c, sockets.c, pbuf.c - Small corrections to some debugging statements, to pacify compiler. - - 2004-07-21 Tony Mountifield tony@softins.co.uk - * etharp.c: Removed spurious semicolon and added missing end-of-comment. - * ethernetif.c Updated low_level_output() to match prototype for - netif->linkoutput and changed low_level_input() similarly for consistency. - * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype - of raw_recv() in raw.h and so avoid compiler error. - * sockets.c: Added trivial (int) cast to keep compiler happier. - * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. - -(STABLE-1_0_0) - - ++ Changes: - - 2004-07-05 Leon Woestenberg leon.woestenberg@gmx.net - * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure - your cc.h file defines this either 1 or 0. If non-defined, - defaults to 1. - * .c: Added <string.h> and <errno.h> includes where used. - * etharp.c: Made some array indices unsigned. - - 2004-06-27 Leon Woestenberg leon.woestenberg@gmx.net - * netif.*: Added netif_set_up()/down(). - * dhcp.c: Changes to restart program flow. - - 2004-05-07 Leon Woestenberg leon.woestenberg@gmx.net - * etharp.c: In find_entry(), instead of a list traversal per candidate, do a - single-pass lookup for different candidates. Should exploit locality. - - 2004-04-29 Leon Woestenberg leon.woestenberg@gmx.net - * tcp*.c: Cleaned up source comment documentation for Doxygen processing. - * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. - * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by - the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. - - ++ Bug fixes: - - 2004-04-27 Leon Woestenberg leon.woestenberg@gmx.net - * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution - suggested by Timmy Brolin. Fix for 32-bit processors that cannot access - non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix - is to prefix the 14-bit Ethernet headers with two padding bytes. - - 2004-04-23 Leon Woestenberg leon.woestenberg@gmx.net - * ip_addr.c: Fix in the ip_addr_isbroadcast() check. - * etharp.c: Fixed the case where the packet that initiates the ARP request - is not queued, and gets lost. Fixed the case where the packets destination - address is already known; we now always queue the packet and perform an ARP - request. - -(STABLE-0_7_0) - - ++ Bug fixes: - - * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. - * Fixed TCP bug in dequeueing of FIN from out of order segment queue. - * Fixed two possible NULL references in rare cases. - -(STABLE-0_6_6) - - ++ Bug fixes: - - * Fixed DHCP which did not include the IP address in DECLINE messages. - - ++ Changes: - - * etharp.c has been hauled over a bit. - -(STABLE-0_6_5) - - ++ Bug fixes: - - * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. - * Packets sent from ARP queue had invalid source hardware address. - - ++ Changes: - - * Pass-by ARP requests do now update the cache. - - ++ New features: - - * No longer dependent on ctype.h. - * New socket options. - * Raw IP pcb support. - -(STABLE-0_6_4) - - ++ Bug fixes: - - * Some debug formatters and casts fixed. - * Numereous fixes in PPP. - - ++ Changes: - - * DEBUGF now is LWIP_DEBUGF - * pbuf_dechain() has been re-enabled. - * Mentioned the changed use of CVS branches in README. - -(STABLE-0_6_3) - - ++ Bug fixes: - - * Fixed pool pbuf memory leak in pbuf_alloc(). - Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. - Reported by Savin Zlobec. - - * PBUF_POOL chains had their tot_len field not set for non-first - pbufs. Fixed in pbuf_alloc(). - - ++ New features: - - * Added PPP stack contributed by Marc Boucher - - ++ Changes: - - * Now drops short packets for ICMP/UDP/TCP protocols. More robust. - - * ARP queueuing now queues the latest packet instead of the first. - This is the RFC recommended behaviour, but can be overridden in - lwipopts.h. - -(0.6.2) - - ++ Bugfixes: - - * TCP has been fixed to deal with the new use of the pbuf->ref - counter. - - * DHCP dhcp_inform() crash bug fixed. - - ++ Changes: - - * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed - pbuf_refresh(). This has sped up pbuf pool operations considerably. - Implemented by David Haas. - -(0.6.1) - - ++ New features: - - * The packet buffer implementation has been enhanced to support - zero-copy and copy-on-demand for packet buffers which have their - payloads in application-managed memory. - Implemented by David Haas. - - Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy - if an outgoing packet can be directly sent on the link, or perform - a copy-on-demand when necessary. - - The application can safely assume the packet is sent, and the RAM - is available to the application directly after calling udp_send() - or similar function. - - ++ Bugfixes: - - * ARP_QUEUEING should now correctly work for all cases, including - PBUF_REF. - Implemented by Leon Woestenberg. - - ++ Changes: - - * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer - to a '0.0.0.0' IP address. - - * The packet buffer implementation is changed. The pbuf->ref counter - meaning has changed, and several pbuf functions have been - adapted accordingly. - - * netif drivers have to be changed to set the hardware address length field - that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). - See the contrib/ports/c16x cs8900 driver as a driver example. - - * netif's have a dhcp field that must be initialized to NULL by the driver. - See the contrib/ports/c16x cs8900 driver as a driver example. - -(0.5.x) This file has been unmaintained up to 0.6.1. All changes are - logged in CVS but have not been explained here. - -(0.5.3) Changes since version 0.5.2 - - ++ Bugfixes: - - * memp_malloc(MEMP_API_MSG) could fail with multiple application - threads because it wasn't protected by semaphores. - - ++ Other changes: - - * struct ip_addr now packed. - - * The name of the time variable in arp.c has been changed to ctime - to avoid conflicts with the time() function. - -(0.5.2) Changes since version 0.5.1 - - ++ New features: - - * A new TCP function, tcp_tmr(), now handles both TCP timers. - - ++ Bugfixes: - - * A bug in tcp_parseopt() could cause the stack to hang because of a - malformed TCP option. - - * The address of new connections in the accept() function in the BSD - socket library was not handled correctly. - - * pbuf_dechain() did not update the ->tot_len field of the tail. - - * Aborted TCP connections were not handled correctly in all - situations. - - ++ Other changes: - - * All protocol header structs are now packed. - - * The ->len field in the tcp_seg structure now counts the actual - amount of data, and does not add one for SYN and FIN segments. - -(0.5.1) Changes since version 0.5.0 - - ++ New features: - - * Possible to run as a user process under Linux. - - * Preliminary support for cross platform packed structs. - - * ARP timer now implemented. - - ++ Bugfixes: - - * TCP output queue length was badly initialized when opening - connections. - - * TCP delayed ACKs were not sent correctly. - - * Explicit initialization of BSS segment variables. - - * read() in BSD socket library could drop data. - - * Problems with memory alignment. - - * Situations when all TCP buffers were used could lead to - starvation. - - * TCP MSS option wasn't parsed correctly. - - * Problems with UDP checksum calculation. - - * IP multicast address tests had endianess problems. - - * ARP requests had wrong destination hardware address. - - ++ Other changes: - - * struct eth_addr changed from u16_t[3] array to u8_t[6]. - - * A ->linkoutput() member was added to struct netif. - - * TCP and UDP ->dest_* struct members where changed to ->remote_*. - - * ntoh* macros are now null definitions for big endian CPUs. - -(0.5.0) Changes since version 0.4.2 - - ++ New features: - - * Redesigned operating system emulation layer to make porting easier. - - * Better control over TCP output buffers. - - * Documenation added. - - ++ Bugfixes: - - * Locking issues in buffer management. - - * Bugfixes in the sequential API. - - * IP forwarding could cause memory leakage. This has been fixed. - - ++ Other changes: - - * Directory structure somewhat changed; the core/ tree has been - collapsed. - -(0.4.2) Changes since version 0.4.1 - - ++ New features: - - * Experimental ARP implementation added. - - * Skeleton Ethernet driver added. - - * Experimental BSD socket API library added. - - ++ Bugfixes: - - * In very intense situations, memory leakage could occur. This has - been fixed. - - ++ Other changes: - - * Variables named "data" and "code" have been renamed in order to - avoid name conflicts in certain compilers. - - * Variable++ have in appliciable cases been translated to ++variable - since some compilers generate better code in the latter case. - -(0.4.1) Changes since version 0.4 - - ++ New features: - - * TCP: Connection attempts time out earlier than data - transmissions. Nagle algorithm implemented. Push flag set on the - last segment in a burst. - - * UDP: experimental support for UDP-Lite extensions. - - ++ Bugfixes: - - * TCP: out of order segments were in some cases handled incorrectly, - and this has now been fixed. Delayed acknowledgements was broken - in 0.4, has now been fixed. Binding to an address that is in use - now results in an error. Reset connections sometimes hung an - application; this has been fixed. - - * Checksum calculation sometimes failed for chained pbufs with odd - lengths. This has been fixed. - - * API: a lot of bug fixes in the API. The UDP API has been improved - and tested. Error reporting and handling has been - improved. Logical flaws and race conditions for incoming TCP - connections has been found and removed. - - * Memory manager: alignment issues. Reallocating memory sometimes - failed, this has been fixed. - - * Generic library: bcopy was flawed and has been fixed. - - ++ Other changes: - - * API: all datatypes has been changed from generic ones such as - ints, to specified ones such as u16_t. Functions that return - errors now have the correct type (err_t). - - * General: A lot of code cleaned up and debugging code removed. Many - portability issues have been fixed. - - * The license was changed; the advertising clause was removed. - - * C64 port added. - - * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri - Kosunen, Mikael Caleres, and Frits Wilmink for reporting and - fixing bugs! - -(0.4) Changes since version 0.3.1 - - * Memory management has been radically changed; instead of - allocating memory from a shared heap, memory for objects that are - rapidly allocated and deallocated is now kept in pools. Allocation - and deallocation from those memory pools is very fast. The shared - heap is still present but is used less frequently. - - * The memory, memory pool, and packet buffer subsystems now support - 4-, 2-, or 1-byte alignment. - - * "Out of memory" situations are handled in a more robust way. - - * Stack usage has been reduced. - - * Easier configuration of lwIP parameters such as memory usage, - TTLs, statistics gathering, etc. All configuration parameters are - now kept in a single header file "lwipopts.h". - - * The directory structure has been changed slightly so that all - architecture specific files are kept under the src/arch - hierarchy. - - * Error propagation has been improved, both in the protocol modules - and in the API. - - * The code for the RTXC architecture has been implemented, tested - and put to use. - - * Bugs have been found and corrected in the TCP, UDP, IP, API, and - the Internet checksum modules. - - * Bugs related to porting between a 32-bit and a 16-bit architecture - have been found and corrected. - - * The license has been changed slightly to conform more with the - original BSD license, including the advertisement clause. - -(0.3.1) Changes since version 0.3 - - * Fix of a fatal bug in the buffer management. Pbufs with allocated - RAM never returned the RAM when the pbuf was deallocated. - - * TCP congestion control, window updates and retransmissions did not - work correctly. This has now been fixed. - - * Bugfixes in the API. - -(0.3) Changes since version 0.2 - - * New and improved directory structure. All include files are now - kept in a dedicated include/ directory. - - * The API now has proper error handling. A new function, - netconn_err(), now returns an error code for the connection in - case of errors. - - * Improvements in the memory management subsystem. The system now - keeps a pointer to the lowest free memory block. A new function, - mem_malloc2() tries to allocate memory once, and if it fails tries - to free some memory and retry the allocation. - - * Much testing has been done with limited memory - configurations. lwIP now does a better job when overloaded. - - * Some bugfixes and improvements to the buffer (pbuf) subsystem. - - * Many bugfixes in the TCP code: - - - Fixed a bug in tcp_close(). - - - The TCP receive window was incorrectly closed when out of - sequence segments was received. This has been fixed. - - - Connections are now timed-out of the FIN-WAIT-2 state. - - - The initial congestion window could in some cases be too - large. This has been fixed. - - - The retransmission queue could in some cases be screwed up. This - has been fixed. - - - TCP RST flag now handled correctly. - - - Out of sequence data was in some cases never delivered to the - application. This has been fixed. - - - Retransmitted segments now contain the correct acknowledgment - number and advertised window. - - - TCP retransmission timeout backoffs are not correctly computed - (ala BSD). After a number of retransmissions, TCP now gives up - the connection. - - * TCP connections now are kept on three lists, one for active - connections, one for listening connections, and one for - connections that are in TIME-WAIT. This greatly speeds up the fast - timeout processing for sending delayed ACKs. - - * TCP now provides proper feedback to the application when a - connection has been successfully set up. - - * More comments have been added to the code. The code has also been - somewhat cleaned up. - -(0.2) Initial public release. diff --git a/external/badvpn_dns/lwip/CMakeLists.txt b/external/badvpn_dns/lwip/CMakeLists.txt deleted file mode 100644 index 121892d..0000000 --- a/external/badvpn_dns/lwip/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -set(LWIP_SOURCES - src/core/timers.c - src/core/udp.c - src/core/memp.c - src/core/init.c - src/core/pbuf.c - src/core/tcp.c - src/core/tcp_out.c - src/core/sys.c - src/core/netif.c - src/core/def.c - src/core/mem.c - src/core/tcp_in.c - src/core/stats.c - src/core/inet_chksum.c - src/core/ipv4/icmp.c - src/core/ipv4/ip4.c - src/core/ipv4/ip4_addr.c - src/core/ipv4/ip_frag.c - src/core/ipv6/ip6.c - src/core/ipv6/nd6.c - src/core/ipv6/icmp6.c - src/core/ipv6/ip6_addr.c - src/core/ipv6/ip6_frag.c - custom/sys.c -) -badvpn_add_library(lwip "system" "" "${LWIP_SOURCES}") diff --git a/external/badvpn_dns/lwip/COPYING b/external/badvpn_dns/lwip/COPYING deleted file mode 100644 index e23898b..0000000 --- a/external/badvpn_dns/lwip/COPYING +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - - diff --git a/external/badvpn_dns/lwip/FILES b/external/badvpn_dns/lwip/FILES deleted file mode 100644 index 6625319..0000000 --- a/external/badvpn_dns/lwip/FILES +++ /dev/null @@ -1,4 +0,0 @@ -src/ - The source code for the lwIP TCP/IP stack. -doc/ - The documentation for lwIP. - -See also the FILES file in each subdirectory. diff --git a/external/badvpn_dns/lwip/README b/external/badvpn_dns/lwip/README deleted file mode 100644 index a62cc4f..0000000 --- a/external/badvpn_dns/lwip/README +++ /dev/null @@ -1,89 +0,0 @@ -INTRODUCTION - -lwIP is a small independent implementation of the TCP/IP protocol -suite that has been developed by Adam Dunkels at the Computer and -Networks Architectures (CNA) lab at the Swedish Institute of Computer -Science (SICS). - -The focus of the lwIP TCP/IP implementation is to reduce the RAM usage -while still having a full scale TCP. This making lwIP suitable for use -in embedded systems with tens of kilobytes of free RAM and room for -around 40 kilobytes of code ROM. - -FEATURES - - * IP (Internet Protocol) including packet forwarding over multiple network - interfaces - * ICMP (Internet Control Message Protocol) for network maintenance and debugging - * IGMP (Internet Group Management Protocol) for multicast traffic management - * UDP (User Datagram Protocol) including experimental UDP-lite extensions - * TCP (Transmission Control Protocol) with congestion control, RTT estimation - and fast recovery/fast retransmit - * Specialized raw/native API for enhanced performance - * Optional Berkeley-like socket API - * DNS (Domain names resolver) - * SNMP (Simple Network Management Protocol) - * DHCP (Dynamic Host Configuration Protocol) - * AUTOIP (for IPv4, conform with RFC 3927) - * PPP (Point-to-Point Protocol) - * ARP (Address Resolution Protocol) for Ethernet - -LICENSE - -lwIP is freely available under a BSD license. - -DEVELOPMENT - -lwIP has grown into an excellent TCP/IP stack for embedded devices, -and developers using the stack often submit bug fixes, improvements, -and additions to the stack to further increase its usefulness. - -Development of lwIP is hosted on Savannah, a central point for -software development, maintenance and distribution. Everyone can -help improve lwIP by use of Savannah's interface, CVS and the -mailing list. A core team of developers will commit changes to the -CVS source tree. - -The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and -contributions (such as platform ports) are in the 'contrib' module. - -See doc/savannah.txt for details on CVS server access for users and -developers. - -Last night's CVS tar ball can be downloaded from: - http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING] - -The current CVS trees are web-browsable: - http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/ - http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/ - -Submit patches and bugs via the lwIP project page: - http://savannah.nongnu.org/projects/lwip/ - - -DOCUMENTATION - -The original out-dated homepage of lwIP and Adam Dunkels' papers on -lwIP are at the official lwIP home page: - http://www.sics.se/~adam/lwip/ - -Self documentation of the source code is regularly extracted from the -current CVS sources and is available from this web page: - http://www.nongnu.org/lwip/ - -There is now a constantly growin wiki about lwIP at - http://lwip.wikia.com/wiki/LwIP_Wiki - -Also, there are mailing lists you can subscribe at - http://savannah.nongnu.org/mail/?group=lwip -plus searchable archives: - http://lists.nongnu.org/archive/html/lwip-users/ - http://lists.nongnu.org/archive/html/lwip-devel/ - -Reading Adam's papers, the files in docs/, browsing the source code -documentation and browsing the mailing list archives is a good way to -become familiar with the design of lwIP. - -Adam Dunkels adam@sics.se -Leon Woestenberg leon.woestenberg@gmx.net - diff --git a/external/badvpn_dns/lwip/UPGRADING b/external/badvpn_dns/lwip/UPGRADING deleted file mode 100644 index 6501107..0000000 --- a/external/badvpn_dns/lwip/UPGRADING +++ /dev/null @@ -1,144 +0,0 @@ -This file lists major changes between release versions that require -ports or applications to be changed. Use it to update a port or an -application written for an older version of lwIP to correctly work -with newer versions. - - -(CVS HEAD) - - * [Enter new changes just after this line - do not remove this line] - - ++ Application changes: - - * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for - compatibility to old applications, but will be removed in the future). - - * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() - - +++ Raw API: - * Changed the semantics of tcp_close() (since it was rather a - shutdown before): Now the application does *NOT* get any calls to the recv - callback (aside from NULL/closed) after calling tcp_close() - - * When calling tcp_abort() from a raw API TCP callback function, - make sure you return ERR_ABRT to prevent accessing unallocated memory. - (ERR_ABRT now means the applicaiton has called tcp_abort!) - - +++ Netconn API: - * Changed netconn_receive() and netconn_accept() to return - err_t, not a pointer to new data/netconn. - - +++ Socket API: - * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they - now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. - - * Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - +++ all APIs: - * correctly implemented SO(F)_REUSEADDR - - ++ Port changes - - +++ new files: - - * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: - - * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains - the actual application programmer's API - - * Separated timer implementation from sys.h/.c, moved to timers.h/.c; - Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you - still want to use your own timer implementation for NO_SYS==0 (as before). - - +++ sys layer: - - * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ - sys_sem_t; - - * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - - * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use - binary semaphores instead of mutexes - as before) - - +++ new options: - - * Don't waste memory when chaining segments, added option TCP_OVERSIZE to - prevent creating many small pbufs when calling tcp_write with many small - blocks of data. Instead, pbufs are allocated larger than needed and the - space is used for later calls to tcp_write. - - * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs - in tcp_write/udp_send. - - * Added an additional option LWIP_ETHERNET to support ethernet without ARP - (necessary for pure PPPoE) - - * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may - be used to place these pools into user-defined memory by using external - declaration. - - * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT - - +++ new pools: - - * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, - so MEMP_NUM_NETDB has to be set accordingly. - - * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so - MEMP_NUM_LOCALHOSTLIST has to be set accordingly. - - * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have - to be set accordingly. - - * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES - has to be set accordingly - - * Integrated loopif into netif.c - loopif does not have to be created by the - port any more, just define LWIP_HAVE_LOOPIF to 1. - - * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined - in cc.h, e.g. used by igmp) - - * Added printf-formatter X8_F to printf u8_t as hex - - * The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - - * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work - with user-allocated structs instead of calling mem_malloc - - * Added const char* name to mem- and memp-stats for easier debugging. - - * Calculate the TCP/UDP checksum while copying to only fetch data once: - Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum - - * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to - more than one pcb. - - * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned - off any more, if this is set to 0, only one packet (the most recent one) is - queued (like demanded by RFC 1122). - - - ++ Major bugfixes/improvements - - * Implemented tcp_shutdown() to only shut down one end of a connection - * Implemented shutdown() at socket- and netconn-level - * Added errorset support to select() + improved select speed overhead - * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) - * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 - * Use macros defined in ip_addr.h to work with IP addresses - * Implemented many nonblocking socket/netconn functions - * Fixed ARP input processing: only add a new entry if a request was directed as us - * mem_realloc() to mem_trim() to prevent confusion with realloc() - * Some improvements for AutoIP (don't route/forward link-local addresses, don't break - existing connections when assigning a routable address) - * Correctly handle remote side overrunning our rcv_wnd in ooseq case - * Removed packing from ip_addr_t, the packed version is now only used in protocol headers - * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 - * Added support for static ARP table entries - -(STABLE-1.3.2) - - * initial version of this file diff --git a/external/badvpn_dns/lwip/custom/arch/cc.h b/external/badvpn_dns/lwip/custom/arch/cc.h deleted file mode 100644 index 653a2e2..0000000 --- a/external/badvpn_dns/lwip/custom/arch/cc.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file cc.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_CUSTOM_CC_H -#define LWIP_CUSTOM_CC_H - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/packed.h> -#include <misc/print_macros.h> -#include <misc/byteorder.h> -#include <base/BLog.h> - -#define u8_t uint8_t -#define s8_t int8_t -#define u16_t uint16_t -#define s16_t int16_t -#define u32_t uint32_t -#define s32_t int32_t -#define mem_ptr_t uintptr_t - -#define PACK_STRUCT_BEGIN B_START_PACKED -#define PACK_STRUCT_END B_END_PACKED -#define PACK_STRUCT_STRUCT B_PACKED - -#define LWIP_PLATFORM_DIAG(x) { if (BLog_WouldLog(BLOG_CHANNEL_lwip, BLOG_INFO)) { BLog_Begin(); BLog_Append x; BLog_Finish(BLOG_CHANNEL_lwip, BLOG_INFO); } } -#define LWIP_PLATFORM_ASSERT(x) { fprintf(stderr, "%s: lwip assertion failure: %s\n", __FUNCTION__, (x)); abort(); } - -#define U16_F PRIu16 -#define S16_F PRId16 -#define X16_F PRIx16 -#define U32_F PRIu32 -#define S32_F PRId32 -#define X32_F PRIx32 -#define SZT_F "zu" - -#define LWIP_PLATFORM_BYTESWAP 1 -#define LWIP_PLATFORM_HTONS(x) hton16(x) -#define LWIP_PLATFORM_HTONL(x) hton32(x) - -#define LWIP_RAND() ( \ - (((uint32_t)(rand() & 0xFF)) << 24) | \ - (((uint32_t)(rand() & 0xFF)) << 16) | \ - (((uint32_t)(rand() & 0xFF)) << 8) | \ - (((uint32_t)(rand() & 0xFF)) << 0) \ -) - -// for BYTE_ORDER -#if defined(BADVPN_USE_WINAPI) && !defined(_MSC_VER) - #include <sys/param.h> -#elif defined(BADVPN_LINUX) - #include <endian.h> -#elif defined(BADVPN_FREEBSD) - #include <machine/endian.h> -#else - #define LITTLE_ENDIAN 1234 - #define BIG_ENDIAN 4321 - #if defined(BADVPN_LITTLE_ENDIAN) - #define BYTE_ORDER LITTLE_ENDIAN - #else - #define BYTE_ORDER BIG_ENDIAN - #endif -#endif - -#endif diff --git a/external/badvpn_dns/lwip/custom/arch/perf.h b/external/badvpn_dns/lwip/custom/arch/perf.h deleted file mode 100644 index 09c9d47..0000000 --- a/external/badvpn_dns/lwip/custom/arch/perf.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file perf.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_CUSTOM_PERF_H -#define LWIP_CUSTOM_PERF_H - -#define PERF_START -#define PERF_STOP(x) - -#endif diff --git a/external/badvpn_dns/lwip/custom/lwipopts.h b/external/badvpn_dns/lwip/custom/lwipopts.h deleted file mode 100644 index 64e03ec..0000000 --- a/external/badvpn_dns/lwip/custom/lwipopts.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file lwipopts.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_CUSTOM_LWIPOPTS_H -#define LWIP_CUSTOM_LWIPOPTS_H - -#define NO_SYS 1 -#define MEM_ALIGNMENT 4 - -#define LWIP_ARP 0 -#define ARP_QUEUEING 0 -#define IP_FORWARD 0 -#define LWIP_ICMP 1 -#define LWIP_RAW 0 -#define LWIP_DHCP 0 -#define LWIP_AUTOIP 0 -#define LWIP_SNMP 0 -#define LWIP_IGMP 0 -#define LWIP_DNS 0 -#define LWIP_UDP 0 -#define LWIP_UDPLITE 0 -#define LWIP_TCP 1 -#define LWIP_CALLBACK_API 1 -#define LWIP_NETIF_API 0 -#define LWIP_NETIF_LOOPBACK 0 -#define LWIP_HAVE_LOOPIF 0 -#define LWIP_HAVE_SLIPIF 0 -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 -#define PPP_SUPPORT 0 -#define LWIP_IPV6 1 -#define LWIP_IPV6_MLD 0 -#define LWIP_IPV6_AUTOCONFIG 0 - -#define MEMP_NUM_TCP_PCB_LISTEN 16 -#define MEMP_NUM_TCP_PCB 1024 -#define TCP_MSS 1460 -#define TCP_SND_BUF 16384 -#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS)) - -#define MEM_LIBC_MALLOC 1 -#define MEMP_MEM_MALLOC 1 - -#endif diff --git a/external/badvpn_dns/lwip/custom/sys.c b/external/badvpn_dns/lwip/custom/sys.c deleted file mode 100644 index efd1455..0000000 --- a/external/badvpn_dns/lwip/custom/sys.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file sys.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <system/BTime.h> - -#include <lwip/sys.h> - -u32_t sys_now (void) -{ - return btime_gettime(); -} diff --git a/external/badvpn_dns/lwip/doc/FILES b/external/badvpn_dns/lwip/doc/FILES deleted file mode 100644 index 05d356f..0000000 --- a/external/badvpn_dns/lwip/doc/FILES +++ /dev/null @@ -1,6 +0,0 @@ -savannah.txt - How to obtain the current development source code. -contrib.txt - How to contribute to lwIP as a developer. -rawapi.txt - The documentation for the core API of lwIP. - Also provides an overview about the other APIs and multithreading. -snmp_agent.txt - The documentation for the lwIP SNMP agent. -sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/external/badvpn_dns/lwip/doc/contrib.txt b/external/badvpn_dns/lwip/doc/contrib.txt deleted file mode 100644 index 39596fc..0000000 --- a/external/badvpn_dns/lwip/doc/contrib.txt +++ /dev/null @@ -1,63 +0,0 @@ -1 Introduction - -This document describes some guidelines for people participating -in lwIP development. - -2 How to contribute to lwIP - -Here is a short list of suggestions to anybody working with lwIP and -trying to contribute bug reports, fixes, enhancements, platform ports etc. -First of all as you may already know lwIP is a volunteer project so feedback -to fixes or questions might often come late. Hopefully the bug and patch tracking -features of Savannah help us not lose users' input. - -2.1 Source code style: - -1. do not use tabs. -2. indentation is two spaces per level (i.e. per tab). -3. end debug messages with a trailing newline (\n). -4. one space between keyword and opening bracket. -5. no space between function and opening bracket. -6. one space and no newline before opening curly braces of a block. -7. closing curly brace on a single line. -8. spaces surrounding assignment and comparisons. -9. don't initialize static and/or global variables to zero, the compiler takes care of that. -10. use current source code style as further reference. - -2.2 Source code documentation style: - -1. JavaDoc compliant and Doxygen compatible. -2. Function documentation above functions in .c files, not .h files. - (This forces you to synchronize documentation and implementation.) -3. Use current documentation style as further reference. - -2.3 Bug reports and patches: - -1. Make sure you are reporting bugs or send patches against the latest - sources. (From the latest release and/or the current CVS sources.) -2. If you think you found a bug make sure it's not already filed in the - bugtracker at Savannah. -3. If you have a fix put the patch on Savannah. If it is a patch that affects - both core and arch specific stuff please separate them so that the core can - be applied separately while leaving the other patch 'open'. The prefered way - is to NOT touch archs you can't test and let maintainers take care of them. - This is a good way to see if they are used at all - the same goes for unix - netifs except tapif. -4. Do not file a bug and post a fix to it to the patch area. Either a bug report - or a patch will be enough. - If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. -5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two) - can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded - as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead - for reporting a compiler warning fix. -6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other - trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you - change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than - if it's not to the point and long :) so the chances for it to be applied are greater. - -2.4 Platform porters: - -1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and - you think it could benefit others[1] you might want discuss this on the mailing list. You - can also ask for CVS access to submit and maintain your port in the contrib CVS module. - \ No newline at end of file diff --git a/external/badvpn_dns/lwip/doc/rawapi.txt b/external/badvpn_dns/lwip/doc/rawapi.txt deleted file mode 100644 index 8c19030..0000000 --- a/external/badvpn_dns/lwip/doc/rawapi.txt +++ /dev/null @@ -1,511 +0,0 @@ -Raw TCP/IP interface for lwIP - -Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons - -lwIP provides three Application Program's Interfaces (APIs) for programs -to use for communication with the TCP/IP code: -* low-level "core" / "callback" or "raw" API. -* higher-level "sequential" API. -* BSD-style socket API. - -The sequential API provides a way for ordinary, sequential, programs -to use the lwIP stack. It is quite similar to the BSD socket API. The -model of execution is based on the blocking open-read-write-close -paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP -code and the application program must reside in different execution -contexts (threads). - -The socket API is a compatibility API for existing applications, -currently it is built on top of the sequential API. It is meant to -provide all functions needed to run socket API applications running -on other platforms (e.g. unix / windows etc.). However, due to limitations -in the specification of this API, there might be incompatibilities -that require small modifications of existing programs. - -** Threading - -lwIP started targeting single-threaded environments. When adding multi- -threading support, instead of making the core thread-safe, another -approach was chosen: there is one main thread running the lwIP core -(also known as the "tcpip_thread"). The raw API may only be used from -this thread! Application threads using the sequential- or socket API -communicate with this main thread through message passing. - - As such, the list of functions that may be called from - other threads or an ISR is very limited! Only functions - from these API header files are thread-safe: - - api.h - - netbuf.h - - netdb.h - - netifapi.h - - sockets.h - - sys.h - - Additionaly, memory (de-)allocation functions may be - called from multiple threads (not ISR!) with NO_SYS=0 - since they are protected by SYS_LIGHTWEIGHT_PROT and/or - semaphores. - - Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 - and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, - pbuf_free() may also be called from another thread or - an ISR (since only then, mem_free - for PBUF_RAM - may - be called from an ISR: otherwise, the HEAP is only - protected by semaphores). - - -** The remainder of this document discusses the "raw" API. ** - -The raw TCP/IP interface allows the application program to integrate -better with the TCP/IP code. Program execution is event based by -having callback functions being called from within the TCP/IP -code. The TCP/IP code and the application program both run in the same -thread. The sequential API has a much higher overhead and is not very -well suited for small systems since it forces a multithreaded paradigm -on the application. - -The raw TCP/IP interface is not only faster in terms of code execution -time but is also less memory intensive. The drawback is that program -development is somewhat harder and application programs written for -the raw TCP/IP interface are more difficult to understand. Still, this -is the preferred way of writing applications that should be small in -code size and memory usage. - -Both APIs can be used simultaneously by different application -programs. In fact, the sequential API is implemented as an application -program using the raw TCP/IP interface. - ---- Callbacks - -Program execution is driven by callbacks. Each callback is an ordinary -C function that is called from within the TCP/IP code. Every callback -function is passed the current TCP or UDP connection state as an -argument. Also, in order to be able to keep program specific state, -the callback functions are called with a program specified argument -that is independent of the TCP/IP state. - -The function for setting the application connection state is: - -- void tcp_arg(struct tcp_pcb *pcb, void *arg) - - Specifies the program specific state that should be passed to all - other callback functions. The "pcb" argument is the current TCP - connection control block, and the "arg" argument is the argument - that will be passed to the callbacks. - - ---- TCP connection setup - -The functions used for setting up connections is similar to that of -the sequential API and of the BSD socket API. A new TCP connection -identifier (i.e., a protocol control block - PCB) is created with the -tcp_new() function. This PCB can then be either set to listen for new -incoming connections or be explicitly connected to another host. - -- struct tcp_pcb *tcp_new(void) - - Creates a new connection identifier (PCB). If memory is not - available for creating the new pcb, NULL is returned. - -- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Binds the pcb to a local IP address and port number. The IP address - can be specified as IP_ADDR_ANY in order to bind the connection to - all local IP addresses. - - If another connection is bound to the same port, the function will - return ERR_USE, otherwise ERR_OK is returned. - -- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) - - Commands a pcb to start listening for incoming connections. When an - incoming connection is accepted, the function specified with the - tcp_accept() function will be called. The pcb will have to be bound - to a local port with the tcp_bind() function. - - The tcp_listen() function returns a new connection identifier, and - the one passed as an argument to the function will be - deallocated. The reason for this behavior is that less memory is - needed for a connection that is listening, so tcp_listen() will - reclaim the memory needed for the original connection and allocate a - new smaller memory block for the listening connection. - - tcp_listen() may return NULL if no memory was available for the - listening connection. If so, the memory associated with the pcb - passed as an argument to tcp_listen() will not be deallocated. - -- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) - - Same as tcp_listen, but limits the number of outstanding connections - in the listen queue to the value specified by the backlog argument. - To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. - -- void tcp_accepted(struct tcp_pcb *pcb) - - Inform lwIP that an incoming connection has been accepted. This would - usually be called from the accept callback. This allows lwIP to perform - housekeeping tasks, such as allowing further incoming connections to be - queued in the listen backlog. - ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed - into the accept callback! - -- void tcp_accept(struct tcp_pcb *pcb, - err_t (* accept)(void *arg, struct tcp_pcb *newpcb, - err_t err)) - - Specified the callback function that should be called when a new - connection arrives on a listening connection. - -- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port, err_t (* connected)(void *arg, - struct tcp_pcb *tpcb, - err_t err)); - - Sets up the pcb to connect to the remote host and sends the - initial SYN segment which opens the connection. - - The tcp_connect() function returns immediately; it does not wait for - the connection to be properly setup. Instead, it will call the - function specified as the fourth argument (the "connected" argument) - when the connection is established. If the connection could not be - properly established, either because the other host refused the - connection or because the other host didn't answer, the "err" - callback function of this pcb (registered with tcp_err, see below) - will be called. - - The tcp_connect() function can return ERR_MEM if no memory is - available for enqueueing the SYN segment. If the SYN indeed was - enqueued successfully, the tcp_connect() function returns ERR_OK. - - ---- Sending TCP data - -TCP data is sent by enqueueing the data with a call to -tcp_write(). When the data is successfully transmitted to the remote -host, the application will be notified with a call to a specified -callback function. - -- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags) - - Enqueues the data pointed to by the argument dataptr. The length of - the data is passed as the len parameter. The apiflags can be one or more of: - - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated - for the data to be copied into. If this flag is not given, no new memory - should be allocated and the data should only be referenced by pointer. This - also means that the memory behind dataptr must not change until the data is - ACKed by the remote host - - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given, - the PSH flag is set in the last segment created by this call to tcp_write. - If this flag is given, the PSH flag is not set. - - The tcp_write() function will fail and return ERR_MEM if the length - of the data exceeds the current send buffer size or if the length of - the queue of outgoing segment is larger than the upper limit defined - in lwipopts.h. The number of bytes available in the output queue can - be retrieved with the tcp_sndbuf() function. - - The proper way to use this function is to call the function with at - most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, - the application should wait until some of the currently enqueued - data has been successfully received by the other host and try again. - -- void tcp_sent(struct tcp_pcb *pcb, - err_t (* sent)(void *arg, struct tcp_pcb *tpcb, - u16_t len)) - - Specifies the callback function that should be called when data has - successfully been received (i.e., acknowledged) by the remote - host. The len argument passed to the callback function gives the - amount bytes that was acknowledged by the last acknowledgment. - - ---- Receiving TCP data - -TCP data reception is callback based - an application specified -callback function is called when new data arrives. When the -application has taken the data, it has to call the tcp_recved() -function to indicate that TCP can advertise increase the receive -window. - -- void tcp_recv(struct tcp_pcb *pcb, - err_t (* recv)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err)) - - Sets the callback function that will be called when new data - arrives. The callback function will be passed a NULL pbuf to - indicate that the remote host has closed the connection. If - there are no errors and the callback function is to return - ERR_OK, then it must free the pbuf. Otherwise, it must not - free the pbuf so that lwIP core code can store it. - -- void tcp_recved(struct tcp_pcb *pcb, u16_t len) - - Must be called when the application has received the data. The len - argument indicates the length of the received data. - - ---- Application polling - -When a connection is idle (i.e., no data is either transmitted or -received), lwIP will repeatedly poll the application by calling a -specified callback function. This can be used either as a watchdog -timer for killing connections that have stayed idle for too long, or -as a method of waiting for memory to become available. For instance, -if a call to tcp_write() has failed because memory wasn't available, -the application may use the polling functionality to call tcp_write() -again when the connection has been idle for a while. - -- void tcp_poll(struct tcp_pcb *pcb, - err_t (* poll)(void *arg, struct tcp_pcb *tpcb), - u8_t interval) - - Specifies the polling interval and the callback function that should - be called to poll the application. The interval is specified in - number of TCP coarse grained timer shots, which typically occurs - twice a second. An interval of 10 means that the application would - be polled every 5 seconds. - - ---- Closing and aborting connections - -- err_t tcp_close(struct tcp_pcb *pcb) - - Closes the connection. The function may return ERR_MEM if no memory - was available for closing the connection. If so, the application - should wait and try again either by using the acknowledgment - callback or the polling functionality. If the close succeeds, the - function returns ERR_OK. - - The pcb is deallocated by the TCP code after a call to tcp_close(). - -- void tcp_abort(struct tcp_pcb *pcb) - - Aborts the connection by sending a RST (reset) segment to the remote - host. The pcb is deallocated. This function never fails. - - ATTENTION: When calling this from one of the TCP callbacks, make - sure you always return ERR_ABRT (and never return ERR_ABRT otherwise - or you will risk accessing deallocated memory or memory leaks! - - -If a connection is aborted because of an error, the application is -alerted of this event by the err callback. Errors that might abort a -connection are when there is a shortage of memory. The callback -function to be called is set using the tcp_err() function. - -- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, - err_t err)) - - The error callback function does not get the pcb passed to it as a - parameter since the pcb may already have been deallocated. - - ---- Lower layer TCP interface - -TCP provides a simple interface to the lower layers of the -system. During system initialization, the function tcp_init() has -to be called before any other TCP function is called. When the system -is running, the two timer functions tcp_fasttmr() and tcp_slowtmr() -must be called with regular intervals. The tcp_fasttmr() should be -called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and -tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. - - ---- UDP interface - -The UDP interface is similar to that of TCP, but due to the lower -level of complexity of UDP, the interface is significantly simpler. - -- struct udp_pcb *udp_new(void) - - Creates a new UDP pcb which can be used for UDP communication. The - pcb is not active until it has either been bound to a local address - or connected to a remote address. - -- void udp_remove(struct udp_pcb *pcb) - - Removes and deallocates the pcb. - -- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Binds the pcb to a local address. The IP-address argument "ipaddr" - can be IP_ADDR_ANY to indicate that it should listen to any local IP - address. The function currently always return ERR_OK. - -- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Sets the remote end of the pcb. This function does not generate any - network traffic, but only set the remote address of the pcb. - -- err_t udp_disconnect(struct udp_pcb *pcb) - - Remove the remote end of the pcb. This function does not generate - any network traffic, but only removes the remote address of the pcb. - -- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) - - Sends the pbuf p. The pbuf is not deallocated. - -- void udp_recv(struct udp_pcb *pcb, - void (* recv)(void *arg, struct udp_pcb *upcb, - struct pbuf *p, - ip_addr_t *addr, - u16_t port), - void *recv_arg) - - Specifies a callback function that should be called when a UDP - datagram is received. - - ---- System initalization - -A truly complete and generic sequence for initializing the lwip stack -cannot be given because it depends on the build configuration (lwipopts.h) -and additional initializations for your runtime environment (e.g. timers). - -We can give you some idea on how to proceed when using the raw API. -We assume a configuration using a single Ethernet netif and the -UDP and TCP transport layers, IPv4 and the DHCP client. - -Call these functions in the order of appearance: - -- stats_init() - - Clears the structure where runtime statistics are gathered. - -- sys_init() - - Not of much use since we set the NO_SYS 1 option in lwipopts.h, - to be called for easy configuration changes. - -- mem_init() - - Initializes the dynamic memory heap defined by MEM_SIZE. - -- memp_init() - - Initializes the memory pools defined by MEMP_NUM_x. - -- pbuf_init() - - Initializes the pbuf memory pool defined by PBUF_POOL_SIZE. - -- etharp_init() - - Initializes the ARP table and queue. - Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval - after this initialization. - -- ip_init() - - Doesn't do much, it should be called to handle future changes. - -- udp_init() - - Clears the UDP PCB list. - -- tcp_init() - - Clears the TCP PCB list and clears some internal TCP timers. - Note: you must call tcp_fasttmr() and tcp_slowtmr() at the - predefined regular intervals after this initialization. - -- netif_add(struct netif *netif, ip_addr_t *ipaddr, - ip_addr_t *netmask, ip_addr_t *gw, - void *state, err_t (* init)(struct netif *netif), - err_t (* input)(struct pbuf *p, struct netif *netif)) - - Adds your network interface to the netif_list. Allocate a struct - netif and pass a pointer to this structure as the first argument. - Give pointers to cleared ip_addr structures when using DHCP, - or fill them with sane numbers otherwise. The state pointer may be NULL. - - The init function pointer must point to a initialization function for - your ethernet netif interface. The following code illustrates it's use. - - err_t netif_if_init(struct netif *netif) - { - u8_t i; - - for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i]; - init_my_eth_device(); - return ERR_OK; - } - - For ethernet drivers, the input function pointer must point to the lwip - function ethernet_input() declared in "netif/etharp.h". Other drivers - must use ip_input() declared in "lwip/ip.h". - -- netif_set_default(struct netif *netif) - - Registers the default network interface. - -- netif_set_up(struct netif *netif) - - When the netif is fully configured this function must be called. - -- dhcp_start(struct netif *netif) - - Creates a new DHCP client for this interface on the first call. - Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at - the predefined regular intervals after starting the client. - - You can peek in the netif->dhcp struct for the actual DHCP status. - - ---- Optimalization hints - -The first thing you want to optimize is the lwip_standard_checksum() -routine from src/core/inet.c. You can override this standard -function with the #define LWIP_CHKSUM <your_checksum_routine>. - -There are C examples given in inet.c or you might want to -craft an assembly function for this. RFC1071 is a good -introduction to this subject. - -Other significant improvements can be made by supplying -assembly or inline replacements for htons() and htonl() -if you're using a little-endian architecture. -#define LWIP_PLATFORM_BYTESWAP 1 -#define LWIP_PLATFORM_HTONS(x) <your_htons> -#define LWIP_PLATFORM_HTONL(x) <your_htonl> - -Check your network interface driver if it reads at -a higher speed than the maximum wire-speed. If the -hardware isn't serviced frequently and fast enough -buffer overflows are likely to occur. - -E.g. when using the cs8900 driver, call cs8900if_service(ethif) -as frequently as possible. When using an RTOS let the cs8900 interrupt -wake a high priority task that services your driver using a binary -semaphore or event flag. Some drivers might allow additional tuning -to match your application and network. - -For a production release it is recommended to set LWIP_STATS to 0. -Note that speed performance isn't influenced much by simply setting -high values to the memory options. - -For more optimization hints take a look at the lwIP wiki. - ---- Zero-copy MACs - -To achieve zero-copy on transmit, the data passed to the raw API must -remain unchanged until sent. Because the send- (or write-)functions return -when the packets have been enqueued for sending, data must be kept stable -after that, too. - -This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions -must *not* be reused by the application unless their ref-count is 1. - -For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too, -but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while -PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change). - -Also, data passed to tcp_write without the copy-flag must not be changed! - -Therefore, be careful which type of PBUF you use and if you copy TCP data -or not! diff --git a/external/badvpn_dns/lwip/doc/savannah.txt b/external/badvpn_dns/lwip/doc/savannah.txt deleted file mode 100644 index 409905b..0000000 --- a/external/badvpn_dns/lwip/doc/savannah.txt +++ /dev/null @@ -1,135 +0,0 @@ -Daily Use Guide for using Savannah for lwIP - -Table of Contents: - -1 - Obtaining lwIP from the CVS repository -2 - Committers/developers CVS access using SSH (to be written) -3 - Merging from DEVEL branch to main trunk (stable branch) -4 - How to release lwIP - - - -1 Obtaining lwIP from the CVS repository ----------------------------------------- - -To perform an anonymous CVS checkout of the main trunk (this is where -bug fixes and incremental enhancements occur), do this: - -cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip - -Or, obtain a stable branch (updated with bug fixes only) as follows: -cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ - -r STABLE-0_7 -d lwip-0.7 lwip - -Or, obtain a specific (fixed) release as follows: -cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ - -r STABLE-0_7_0 -d lwip-0.7.0 lwip - -3 Committers/developers CVS access using SSH --------------------------------------------- - -The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. -As such, CVS commits to the server occur through a SSH tunnel for project members. -To create a SSH2 key pair in UNIX-like environments, do this: - -ssh-keygen -t dsa - -Under Windows, a recommended SSH client is "PuTTY", freely available with good -documentation and a graphic user interface. Use its key generator. - -Now paste the id_dsa.pub contents into your Savannah account public key list. Wait -a while so that Savannah can update its configuration (This can take minutes). - -Try to login using SSH: - -ssh -v your_login@cvs.sv.gnu.org - -If it tells you: - -Authenticating with public key "your_key_name"... -Server refused to allocate pty - -then you could login; Savannah refuses to give you a shell - which is OK, as we -are allowed to use SSH for CVS only. Now, you should be able to do this: - -export CVS_RSH=ssh -cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip - -after which you can edit your local files with bug fixes or new features and -commit them. Make sure you know what you are doing when using CVS to make -changes on the repository. If in doubt, ask on the lwip-members mailing list. - -(If SSH asks about authenticity of the host, you can check the key - fingerprint against http://savannah.nongnu.org/cvs/?group=lwip) - - -3 Merging from DEVEL branch to main trunk (stable) --------------------------------------------------- - -Merging is a delicate process in CVS and requires the -following disciplined steps in order to prevent conflicts -in the future. Conflicts can be hard to solve! - -Merging from branch A to branch B requires that the A branch -has a tag indicating the previous merger. This tag is called -'merged_from_A_to_B'. After merging, the tag is moved in the -A branch to remember this merger for future merge actions. - -IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE -REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE -MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME). - -Merge all changes in DEVEL since our last merge to main: - -In the working copy of the main trunk: -cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL - -(This will apply the changes between 'merged_from_DEVEL_to_main' -and 'DEVEL' to your work set of files) - -We can now commit the merge result. -cvs commit -R -m "Merged from DEVEL to main." - -If this worked out OK, we now move the tag in the DEVEL branch -to this merge point, so we can use this point for future merges: - -cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip - -4 How to release lwIP ---------------------- - -First, checkout a clean copy of the branch to be released. Tag this set with -tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example). - -Login CVS using pserver authentication, then export a clean copy of the -tagged tree. Export is similar to a checkout, except that the CVS metadata -is not created locally. - -export CVS_RSH=ssh -cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ - -r STABLE-0_6_3 -d lwip-0.6.3 lwip - -Archive this directory using tar, gzip'd, bzip2'd and zip'd. - -tar czvf lwip-0.6.3.tar.gz lwip-0.6.3 -tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3 -zip -r lwip-0.6.3.zip lwip-0.6.3 - -Now, sign the archives with a detached GPG binary signature as follows: - -gpg -b lwip-0.6.3.tar.gz -gpg -b lwip-0.6.3.tar.bz2 -gpg -b lwip-0.6.3.zip - -Upload these files using anonymous FTP: -ncftp ftp://savannah.gnu.org/incoming/savannah/lwip - -ncftp>mput *0.6.3.* - -Additionally, you may post a news item on Savannah, like this: - -A new 0.6.3 release is now available here: -http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 - -You will have to submit this via the user News interface, then approve -this via the Administrator News interface. \ No newline at end of file diff --git a/external/badvpn_dns/lwip/doc/snmp_agent.txt b/external/badvpn_dns/lwip/doc/snmp_agent.txt deleted file mode 100644 index 2653230..0000000 --- a/external/badvpn_dns/lwip/doc/snmp_agent.txt +++ /dev/null @@ -1,181 +0,0 @@ -SNMPv1 agent for lwIP - -Author: Christiaan Simons - -This is a brief introduction how to use and configure the SNMP agent. -Note the agent uses the raw-API UDP interface so you may also want to -read rawapi.txt to gain a better understanding of the SNMP message handling. - -0 Agent Capabilities -==================== - -SNMPv1 per RFC1157 - This is an old(er) standard but is still widely supported. - For SNMPv2c and v3 have a greater complexity and need many - more lines of code. IMHO this breaks the idea of "lightweight IP". - - Note the S in SNMP stands for "Simple". Note that "Simple" is - relative. SNMP is simple compared to the complex ISO network - management protocols CMIP (Common Management Information Protocol) - and CMOT (CMip Over Tcp). - -MIB II per RFC1213 - The standard lwIP stack management information base. - This is a required MIB, so this is always enabled. - When builing lwIP without TCP, the mib-2.tcp group is omitted. - The groups EGP, CMOT and transmission are disabled by default. - - Most mib-2 objects are not writable except: - sysName, sysLocation, sysContact, snmpEnableAuthenTraps. - Writing to or changing the ARP and IP address and route - tables is not possible. - - Note lwIP has a very limited notion of IP routing. It currently - doen't have a route table and doesn't have a notion of the U,G,H flags. - Instead lwIP uses the interface list with only one default interface - acting as a single gateway interface (G) for the default route. - - The agent returns a "virtual table" with the default route 0.0.0.0 - for the default interface and network routes (no H) for each - network interface in the netif_list. - All routes are considered to be up (U). - -Loading additional MIBs - MIBs can only be added in compile-time, not in run-time. - There is no MIB compiler thus additional MIBs must be hand coded. - -Large SNMP message support - The packet decoding and encoding routines are designed - to use pbuf-chains. Larger payloads than the minimum - SNMP requirement of 484 octets are supported if the - PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your - local requirement. - -1 Building the Agent -==================== - -First of all you'll need to add the following define -to your local lwipopts.h: - -#define LWIP_SNMP 1 - -and add the source files in lwip/src/core/snmp -and some snmp headers in lwip/src/include/lwip to your makefile. - -Note you'll might need to adapt you network driver to update -the mib2 variables for your interface. - -2 Running the Agent -=================== - -The following function calls must be made in your program to -actually get the SNMP agent running. - -Before starting the agent you should supply pointers -to non-volatile memory for sysContact, sysLocation, -and snmpEnableAuthenTraps. You can do this by calling - -snmp_set_syscontact() -snmp_set_syslocation() -snmp_set_snmpenableauthentraps() - -Additionally you may want to set - -snmp_set_sysdescr() -snmp_set_sysobjid() (if you have a private MIB) -snmp_set_sysname() - -Also before starting the agent you need to setup -one or more trap destinations using these calls: - -snmp_trap_dst_enable(); -snmp_trap_dst_ip_set(); - -In the lwIP initialisation sequence call snmp_init() just after -the call to udp_init(). - -Exactly every 10 msec the SNMP uptime timestamp must be updated with -snmp_inc_sysuptime(). You should call this from a timer interrupt -or a timer signal handler depending on your runtime environment. - -An alternative way to update the SNMP uptime timestamp is to do a call like -snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to -a lower frequency). Another one is to not call snmp_inc_sysuptime() or -snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. -This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside -snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only -when it's queried (any function which need "sysuptime" have to call -snmp_get_sysuptime). - - -3 Private MIBs -============== - -If want to extend the agent with your own private MIB you'll need to -add the following define to your local lwipopts.h: - -#define SNMP_PRIVATE_MIB 1 - -You must provide the private_mib.h and associated files yourself. -Note we don't have a "MIB compiler" that generates C source from a MIB, -so you're required to do some serious coding if you enable this! - -Note the lwIP enterprise ID (26381) is assigned to the lwIP project, -ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP -MAINTAINERS! - -If you need to create your own private MIB you'll need -to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html - -You can set it by passing a struct snmp_obj_id to the agent -using snmp_set_sysobjid(&my_object_id), just before snmp_init(). - -Note the object identifiers for thes MIB-2 and your private MIB -tree must be kept in sorted ascending (lexicographical) order. -This to ensure correct getnext operation. - -An example for a private MIB is part of the "minimal Unix" project: -contrib/ports/unix/proj/minimal/lwip_prvmib.c - -The next chapter gives a more detailed description of the -MIB-2 tree and the optional private MIB. - -4 The Gory Details -================== - -4.0 Object identifiers and the MIB tree. - -We have three distinct parts for all object identifiers: - -The prefix - .iso.org.dod.internet - -the middle part - .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress - -and the index part - .1.192.168.0.1 - -Objects located above the .internet hierarchy aren't supported. -Currently only the .mgmt sub-tree is available and -when the SNMP_PRIVATE_MIB is enabled the .private tree -becomes available too. - -Object identifiers from incoming requests are checked -for a matching prefix, middle part and index part -or are expanded(*) for GetNext requests with short -or inexisting names in the request. -(* we call this "expansion" but this also -resembles the "auto-completion" operation) - -The middle part is usually located in ROM (const) -to preserve precious RAM on small microcontrollers. -However RAM location is possible for a dynamically -changing private tree. - -The index part is handled by functions which in -turn use dynamically allocated index trees from RAM. -These trees are updated by e.g. the etharp code -when new entries are made or removed form the ARP cache. - -/** @todo more gory details */ diff --git a/external/badvpn_dns/lwip/doc/sys_arch.txt b/external/badvpn_dns/lwip/doc/sys_arch.txt deleted file mode 100644 index 847cd77..0000000 --- a/external/badvpn_dns/lwip/doc/sys_arch.txt +++ /dev/null @@ -1,267 +0,0 @@ -sys_arch interface for lwIP 0.6++ - -Author: Adam Dunkels - -The operating system emulation layer provides a common interface -between the lwIP code and the underlying operating system kernel. The -general idea is that porting lwIP to new architectures requires only -small changes to a few header files and a new sys_arch -implementation. It is also possible to do a sys_arch implementation -that does not rely on any underlying operating system. - -The sys_arch provides semaphores and mailboxes to lwIP. For the full -lwIP functionality, multiple threads support can be implemented in the -sys_arch, but this is not required for the basic lwIP -functionality. Previous versions of lwIP required the sys_arch to -implement timer scheduling as well but as of lwIP 0.5 this is -implemented in a higher layer. - -In addition to the source file providing the functionality of sys_arch, -the OS emulation layer must provide several header files defining -macros used throughout lwip. The files required and the macros they -must define are listed below the sys_arch description. - -Semaphores can be either counting or binary - lwIP works with both -kinds. Mailboxes are used for message passing and can be implemented -either as a queue which allows multiple messages to be posted to a -mailbox, or as a rendez-vous point where only one message can be -posted at a time. lwIP works with both kinds, but the former type will -be more efficient. A message in a mailbox is just a pointer, nothing -more. - -Semaphores are represented by the type "sys_sem_t" which is typedef'd -in the sys_arch.h file. Mailboxes are equivalently represented by the -type "sys_mbox_t". lwIP does not place any restrictions on how -sys_sem_t or sys_mbox_t are represented internally. - -Since lwIP 1.4.0, semaphore and mailbox functions are prototyped in a way that -allows both using pointers or actual OS structures to be used. This way, memory -required for such types can be either allocated in place (globally or on the -stack) or on the heap (allocated internally in the "*_new()" functions). - -The following functions must be implemented by the sys_arch: - -- void sys_init(void) - - Is called to initialize the sys_arch layer. - -- err_t sys_sem_new(sys_sem_t *sem, u8_t count) - - Creates a new semaphore. The semaphore is allocated to the memory that 'sem' - points to (which can be both a pointer or the actual OS structure). - The "count" argument specifies the initial state of the semaphore (which is - either 0 or 1). - If the semaphore has been created, ERR_OK should be returned. Returning any - other error will provide a hint what went wrong, but except for assertions, - no real error handling is implemented. - -- void sys_sem_free(sys_sem_t *sem) - - Deallocates a semaphore. - -- void sys_sem_signal(sys_sem_t *sem) - - Signals a semaphore. - -- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) - - Blocks the thread while waiting for the semaphore to be - signaled. If the "timeout" argument is non-zero, the thread should - only be blocked for the specified time (measured in - milliseconds). If the "timeout" argument is zero, the thread should be - blocked until the semaphore is signalled. - - If the timeout argument is non-zero, the return value is the number of - milliseconds spent waiting for the semaphore to be signaled. If the - semaphore wasn't signaled within the specified time, the return value is - SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore - (i.e., it was already signaled), the function may return zero. - - Notice that lwIP implements a function with a similar name, - sys_sem_wait(), that uses the sys_arch_sem_wait() function. - -- int sys_sem_valid(sys_sem_t *sem) - - Returns 1 if the semaphore is valid, 0 if it is not valid. - When using pointers, a simple way is to check the pointer for != NULL. - When directly using OS structures, implementing this may be more complex. - This may also be a define, in which case the function is not prototyped. - -- void sys_sem_set_invalid(sys_sem_t *sem) - - Invalidate a semaphore so that sys_sem_valid() returns 0. - ATTENTION: This does NOT mean that the semaphore shall be deallocated: - sys_sem_free() is always called before calling this function! - This may also be a define, in which case the function is not prototyped. - -- err_t sys_mbox_new(sys_mbox_t *mbox, int size) - - Creates an empty mailbox for maximum "size" elements. Elements stored - in mailboxes are pointers. You have to define macros "_MBOX_SIZE" - in your lwipopts.h, or ignore this parameter in your implementation - and use a default size. - If the mailbox has been created, ERR_OK should be returned. Returning any - other error will provide a hint what went wrong, but except for assertions, - no real error handling is implemented. - -- void sys_mbox_free(sys_mbox_t *mbox) - - Deallocates a mailbox. If there are messages still present in the - mailbox when the mailbox is deallocated, it is an indication of a - programming error in lwIP and the developer should be notified. - -- void sys_mbox_post(sys_mbox_t *mbox, void *msg) - - Posts the "msg" to the mailbox. This function have to block until - the "msg" is really posted. - -- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) - - Try to post the "msg" to the mailbox. Returns ERR_MEM if this one - is full, else, ERR_OK if the "msg" is posted. - -- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) - - Blocks the thread until a message arrives in the mailbox, but does - not block the thread longer than "timeout" milliseconds (similar to - the sys_arch_sem_wait() function). If "timeout" is 0, the thread should - be blocked until a message arrives. The "msg" argument is a result - parameter that is set by the function (i.e., by doing "*msg = - ptr"). The "msg" parameter maybe NULL to indicate that the message - should be dropped. - - The return values are the same as for the sys_arch_sem_wait() function: - Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a - timeout. - - Note that a function with a similar name, sys_mbox_fetch(), is - implemented by lwIP. - -- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) - - This is similar to sys_arch_mbox_fetch, however if a message is not - present in the mailbox, it immediately returns with the code - SYS_MBOX_EMPTY. On success 0 is returned. - - To allow for efficient implementations, this can be defined as a - function-like macro in sys_arch.h instead of a normal function. For - example, a naive implementation could be: - #define sys_arch_mbox_tryfetch(mbox,msg) \ - sys_arch_mbox_fetch(mbox,msg,1) - although this would introduce unnecessary delays. - -- int sys_mbox_valid(sys_mbox_t *mbox) - - Returns 1 if the mailbox is valid, 0 if it is not valid. - When using pointers, a simple way is to check the pointer for != NULL. - When directly using OS structures, implementing this may be more complex. - This may also be a define, in which case the function is not prototyped. - -- void sys_mbox_set_invalid(sys_mbox_t *mbox) - - Invalidate a mailbox so that sys_mbox_valid() returns 0. - ATTENTION: This does NOT mean that the mailbox shall be deallocated: - sys_mbox_free() is always called before calling this function! - This may also be a define, in which case the function is not prototyped. - -If threads are supported by the underlying operating system and if -such functionality is needed in lwIP, the following function will have -to be implemented as well: - -- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) - - Starts a new thread named "name" with priority "prio" that will begin its - execution in the function "thread()". The "arg" argument will be passed as an - argument to the thread() function. The stack size to used for this thread is - the "stacksize" parameter. The id of the new thread is returned. Both the id - and the priority are system dependent. - -- sys_prot_t sys_arch_protect(void) - - This optional function does a "fast" critical region protection and returns - the previous protection level. This function is only called during very short - critical regions. An embedded system which supports ISR-based drivers might - want to implement this function by disabling interrupts. Task-based systems - might want to implement this by using a mutex or disabling tasking. This - function should support recursive calls from the same task or interrupt. In - other words, sys_arch_protect() could be called while already protected. In - that case the return value indicates that it is already protected. - - sys_arch_protect() is only required if your port is supporting an operating - system. - -- void sys_arch_unprotect(sys_prot_t pval) - - This optional function does a "fast" set of critical region protection to the - value specified by pval. See the documentation for sys_arch_protect() for - more information. This function is only required if your port is supporting - an operating system. - -For some configurations, you also need: - -- u32_t sys_now(void) - - This optional function returns the current time in milliseconds (don't care - for wraparound, this is only used for time diffs). - Not implementing this function means you cannot use some modules (e.g. TCP - timestamps, internal timeouts for NO_SYS==1). - - -Note: - -Be carefull with using mem_malloc() in sys_arch. When malloc() refers to -mem_malloc() you can run into a circular function call problem. In mem.c -mem_init() tries to allcate a semaphore using mem_malloc, which of course -can't be performed when sys_arch uses mem_malloc. - -------------------------------------------------------------------------------- -Additional files required for the "OS support" emulation layer: -------------------------------------------------------------------------------- - -cc.h - Architecture environment, some compiler specific, some - environment specific (probably should move env stuff - to sys_arch.h.) - - Typedefs for the types used by lwip - - u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t - - Compiler hints for packing lwip's structures - - PACK_STRUCT_FIELD(x) - PACK_STRUCT_STRUCT - PACK_STRUCT_BEGIN - PACK_STRUCT_END - - Platform specific diagnostic output - - LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. - LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. - Portability defines for printf formatters: - U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F - - "lightweight" synchronization mechanisms - - SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. - SYS_ARCH_PROTECT(x) - enter protection mode. - SYS_ARCH_UNPROTECT(x) - leave protection mode. - - If the compiler does not provide memset() this file must include a - definition of it, or include a file which defines it. - - This file must either include a system-local <errno.h> which defines - the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO - to make lwip/arch.h define the codes which are used throughout. - - -perf.h - Architecture specific performance measurement. - Measurement calls made throughout lwip, these can be defined to nothing. - PERF_START - start measuring something. - PERF_STOP(x) - stop measuring something, and record the result. - -sys_arch.h - Tied to sys_arch.c - - Arch dependent types for the following objects: - sys_sem_t, sys_mbox_t, sys_thread_t, - And, optionally: - sys_prot_t - - Defines to set vars of sys_mbox_t and sys_sem_t to NULL. - SYS_MBOX_NULL NULL - SYS_SEM_NULL NULL diff --git a/external/badvpn_dns/lwip/lwip-base-version b/external/badvpn_dns/lwip/lwip-base-version deleted file mode 100644 index b48d5b6..0000000 --- a/external/badvpn_dns/lwip/lwip-base-version +++ /dev/null @@ -1 +0,0 @@ -666e84eef281d0059377d0f5029c1c550488f829 diff --git a/external/badvpn_dns/lwip/src/FILES b/external/badvpn_dns/lwip/src/FILES deleted file mode 100644 index 952aeab..0000000 --- a/external/badvpn_dns/lwip/src/FILES +++ /dev/null @@ -1,13 +0,0 @@ -api/ - The code for the high-level wrapper API. Not needed if - you use the lowel-level call-back/raw API. - -core/ - The core of the TPC/IP stack; protocol implementations, - memory and buffer management, and the low-level raw API. - -include/ - lwIP include files. - -netif/ - Generic network interface device drivers are kept here, - as well as the ARP module. - -For more information on the various subdirectories, check the FILES -file in each directory. diff --git a/external/badvpn_dns/lwip/src/api/api_lib.c b/external/badvpn_dns/lwip/src/api/api_lib.c deleted file mode 100644 index adaaad4..0000000 --- a/external/badvpn_dns/lwip/src/api/api_lib.c +++ /dev/null @@ -1,788 +0,0 @@ -/** - * @file - * Sequential API External module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -/* This is the part of the API that is linked with - the application */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api.h" -#include "lwip/tcpip.h" -#include "lwip/memp.h" - -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" - -#include <string.h> - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is also created. - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param proto the IP protocol for RAW IP pcbs - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn* -netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) -{ - struct netconn *conn; - struct api_msg msg; - - conn = netconn_alloc(t, callback); - if (conn != NULL) { - err_t err; - msg.msg.msg.n.proto = proto; - msg.msg.conn = conn; - TCPIP_APIMSG((&msg), lwip_netconn_do_newconn, err); - if (err != ERR_OK) { - LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); - LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); - LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ - sys_sem_free(&conn->op_completed); - sys_mbox_free(&conn->recvmbox); - memp_free(MEMP_NETCONN, conn); - return NULL; - } - } - return conn; -} - -/** - * Close a netconn 'connection' and free its resources. - * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate - * after this returns. - * - * @param conn the netconn to delete - * @return ERR_OK if the connection was deleted - */ -err_t -netconn_delete(struct netconn *conn) -{ - struct api_msg msg; - - /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ - if (conn == NULL) { - return ERR_OK; - } - - msg.function = lwip_netconn_do_delconn; - msg.msg.conn = conn; - tcpip_apimsg(&msg); - - netconn_free(conn); - - /* don't care for return value of lwip_netconn_do_delconn since it only calls void functions */ - - return ERR_OK; -} - -/** - * Get the local or remote IP address and port of a netconn. - * For RAW netconns, this returns the protocol instead of a port! - * - * @param conn the netconn to query - * @param addr a pointer to which to save the IP address - * @param port a pointer to which to save the port (or protocol for RAW) - * @param local 1 to get the local IP address, 0 to get the remote one - * @return ERR_CONN for invalid connections - * ERR_OK if the information was retrieved - */ -err_t -netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); - - msg.msg.conn = conn; - msg.msg.msg.ad.ipaddr = ip_2_ipX(addr); - msg.msg.msg.ad.port = port; - msg.msg.msg.ad.local = local; - TCPIP_APIMSG(&msg, lwip_netconn_do_getaddr, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Bind a netconn to a specific local IP address and port. - * Binding one netconn twice might not always be checked correctly! - * - * @param conn the netconn to bind - * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY - * to bind to all addresses) - * @param port the local port to bind the netconn to (not used for RAW) - * @return ERR_OK if bound, any other err_t on failure - */ -err_t -netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.msg.conn = conn; - msg.msg.msg.bc.ipaddr = addr; - msg.msg.msg.bc.port = port; - TCPIP_APIMSG(&msg, lwip_netconn_do_bind, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Connect a netconn to a specific remote IP address and port. - * - * @param conn the netconn to connect - * @param addr the remote IP address to connect to - * @param port the remote port to connect to (no used for RAW) - * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise - */ -err_t -netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.msg.conn = conn; - msg.msg.msg.bc.ipaddr = addr; - msg.msg.msg.bc.port = port; -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - /* The TCP version waits for the connect to succeed, - so always needs to use message passing. */ - msg.function = lwip_netconn_do_connect; - err = tcpip_apimsg(&msg); - } -#endif /* LWIP_TCP */ -#if (LWIP_UDP || LWIP_RAW) && LWIP_TCP - else -#endif /* (LWIP_UDP || LWIP_RAW) && LWIP_TCP */ -#if (LWIP_UDP || LWIP_RAW) - { - /* UDP and RAW only set flags, so we can use core-locking. */ - TCPIP_APIMSG(&msg, lwip_netconn_do_connect, err); - } -#endif /* (LWIP_UDP || LWIP_RAW) */ - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Disconnect a netconn from its current peer (only valid for UDP netconns). - * - * @param conn the netconn to disconnect - * @return TODO: return value is not set here... - */ -err_t -netconn_disconnect(struct netconn *conn) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.msg.conn = conn; - TCPIP_APIMSG(&msg, lwip_netconn_do_disconnect, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Set a TCP netconn into listen mode - * - * @param conn the tcp netconn to set to listen mode - * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 - * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns - * don't return any error (yet?)) - */ -err_t -netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) -{ -#if LWIP_TCP - struct api_msg msg; - err_t err; - - /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ - LWIP_UNUSED_ARG(backlog); - - LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.msg.conn = conn; -#if TCP_LISTEN_BACKLOG - msg.msg.msg.lb.backlog = backlog; -#endif /* TCP_LISTEN_BACKLOG */ - TCPIP_APIMSG(&msg, lwip_netconn_do_listen, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(backlog); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * Accept a new connection on a TCP listening netconn. - * - * @param conn the TCP listen netconn - * @param new_conn pointer where the new connection is stored - * @return ERR_OK if a new connection has been received or an error - * code otherwise - */ -err_t -netconn_accept(struct netconn *conn, struct netconn **new_conn) -{ -#if LWIP_TCP - struct netconn *newconn; - err_t err; -#if TCP_LISTEN_BACKLOG - struct api_msg msg; -#endif /* TCP_LISTEN_BACKLOG */ - - LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); - *new_conn = NULL; - LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;); - - err = conn->last_err; - if (ERR_IS_FATAL(err)) { - /* don't recv on fatal errors: this might block the application task - waiting on acceptmbox forever! */ - return err; - } - -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { - NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - - if (newconn == NULL) { - /* connection has been aborted */ - NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); - return ERR_ABRT; - } -#if TCP_LISTEN_BACKLOG - /* Let the stack know that we have accepted the connection. */ - msg.msg.conn = conn; - /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); -#endif /* TCP_LISTEN_BACKLOG */ - - *new_conn = newconn; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(new_conn); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * Receive data: actual implementation that doesn't care whether pbuf or netbuf - * is received - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf/netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - */ -static err_t -netconn_recv_data(struct netconn *conn, void **new_buf) -{ - void *buf = NULL; - u16_t len; - err_t err; -#if LWIP_TCP - struct api_msg msg; -#endif /* LWIP_TCP */ - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); - - err = conn->last_err; - if (ERR_IS_FATAL(err)) { - /* don't recv on fatal errors: this might block the application task - waiting on recvmbox forever! */ - /* @todo: this does not allow us to fetch data that has been put into recvmbox - before the fatal error occurred - is that a problem? */ - return err; - } - -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { - NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - if (!netconn_get_noautorecved(conn) || (buf == NULL)) { - /* Let the stack know that we have taken the data. */ - /* TODO: Speedup: Don't block and wait for the answer here - (to prevent multiple thread-switches). */ - msg.msg.conn = conn; - if (buf != NULL) { - msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len; - } else { - msg.msg.msg.r.len = 1; - } - /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); - } - - /* If we are closed, we indicate that we no longer wish to use the socket */ - if (buf == NULL) { - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - /* Avoid to lose any previous error code */ - NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); - return ERR_CLSD; - } - len = ((struct pbuf *)buf)->tot_len; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ -#if (LWIP_UDP || LWIP_RAW) - { - LWIP_ASSERT("buf != NULL", buf != NULL); - len = netbuf_len((struct netbuf *)buf); - } -#endif /* (LWIP_UDP || LWIP_RAW) */ - -#if LWIP_SO_RCVBUF - SYS_ARCH_DEC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); - - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -} - -/** - * Receive data (in form of a pbuf) from a TCP netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - * ERR_ARG if conn is not a TCP netconn - */ -err_t -netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) -{ - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data(conn, (void **)new_buf); -} - -/** - * Receive data (in form of a netbuf containing a packet buffer) from a netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - */ -err_t -netconn_recv(struct netconn *conn, struct netbuf **new_buf) -{ -#if LWIP_TCP - struct netbuf *buf = NULL; - err_t err; -#endif /* LWIP_TCP */ - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - struct pbuf *p = NULL; - /* This is not a listening netconn, since recvmbox is set */ - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - NETCONN_SET_SAFE_ERR(conn, ERR_MEM); - return ERR_MEM; - } - - err = netconn_recv_data(conn, (void **)&p); - if (err != ERR_OK) { - memp_free(MEMP_NETBUF, buf); - return err; - } - LWIP_ASSERT("p != NULL", p != NULL); - - buf->p = p; - buf->ptr = p; - buf->port = 0; - ipX_addr_set_any(LWIP_IPV6, &buf->addr); - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ - { -#if (LWIP_UDP || LWIP_RAW) - return netconn_recv_data(conn, (void **)new_buf); -#endif /* (LWIP_UDP || LWIP_RAW) */ - } -} - -/** - * TCP: update the receive window: by calling this, the application - * tells the stack that it has processed data and is able to accept - * new data. - * ATTENTION: use with care, this is mainly used for sockets! - * Can only be used when calling netconn_set_noautorecved(conn, 1) before. - * - * @param conn the netconn for which to update the receive window - * @param length amount of data processed (ATTENTION: this must be accurate!) - */ -void -netconn_recved(struct netconn *conn, u32_t length) -{ -#if LWIP_TCP - if ((conn != NULL) && (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && - (netconn_get_noautorecved(conn))) { - struct api_msg msg; - /* Let the stack know that we have taken the data. */ - /* TODO: Speedup: Don't block and wait for the answer here - (to prevent multiple thread-switches). */ - msg.msg.conn = conn; - msg.msg.msg.r.len = length; - /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); - } -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(length); -#endif /* LWIP_TCP */ -} - -/** - * Send data (in form of a netbuf) to a specific remote IP address and port. - * Only to be used for UDP and RAW netconns (not TCP). - * - * @param conn the netconn over which to send data - * @param buf a netbuf containing the data to send - * @param addr the remote IP address to which to send the data - * @param port the remote port to which to send the data - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) -{ - if (buf != NULL) { - ipX_addr_set_ipaddr(PCB_ISIPV6(conn->pcb.ip), &buf->addr, addr); - buf->port = port; - return netconn_send(conn, buf); - } - return ERR_VAL; -} - -/** - * Send data over a UDP or RAW netconn (that is already connected). - * - * @param conn the UDP or RAW netconn over which to send data - * @param buf a netbuf containing the data to send - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_send(struct netconn *conn, struct netbuf *buf) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); - msg.msg.conn = conn; - msg.msg.msg.b = buf; - TCPIP_APIMSG(&msg, lwip_netconn_do_send, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Send data over a TCP netconn. - * - * @param conn the TCP netconn over which to send data - * @param dataptr pointer to the application buffer that contains the data to send - * @param size size of the application data to send - * @param apiflags combination of following flags : - * - NETCONN_COPY: data will be copied into memory belonging to the stack - * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent - * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once - * @param bytes_written pointer to a location that receives the number of written bytes - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written) -{ - struct api_msg msg; - err_t err; - u8_t dontblock; - - LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type)== NETCONN_TCP), return ERR_VAL;); - if (size == 0) { - return ERR_OK; - } - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); - if (dontblock && !bytes_written) { - /* This implies netconn_write() cannot be used for non-blocking send, since - it has no way to return the number of bytes written. */ - return ERR_VAL; - } - - /* non-blocking write sends as much */ - msg.msg.conn = conn; - msg.msg.msg.w.dataptr = dataptr; - msg.msg.msg.w.apiflags = apiflags; - msg.msg.msg.w.len = size; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout != 0) { - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - msg.msg.msg.w.time_started = sys_now(); - } else { - msg.msg.msg.w.time_started = 0; - } -#endif /* LWIP_SO_SNDTIMEO */ - - /* For locking the core: this _can_ be delayed on low memory/low send buffer, - but if it is, this is done inside api_msg.c:do_write(), so we can use the - non-blocking version here. */ - TCPIP_APIMSG(&msg, lwip_netconn_do_write, err); - if ((err == ERR_OK) && (bytes_written != NULL)) { - if (dontblock -#if LWIP_SO_SNDTIMEO - || (conn->send_timeout != 0) -#endif /* LWIP_SO_SNDTIMEO */ - ) { - /* nonblocking write: maybe the data has been sent partly */ - *bytes_written = msg.msg.msg.w.len; - } else { - /* blocking call succeeded: all data has been sent if it */ - *bytes_written = size; - } - } - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Close ot shutdown a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close or shutdown - * @param how fully close or only shutdown one side? - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -static err_t -netconn_close_shutdown(struct netconn *conn, u8_t how) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.function = lwip_netconn_do_close; - msg.msg.conn = conn; - /* shutting down both ends is the same as closing */ - msg.msg.msg.sd.shut = how; - /* because of the LWIP_TCPIP_CORE_LOCKING implementation of lwip_netconn_do_close, - don't use TCPIP_APIMSG here */ - err = tcpip_apimsg(&msg); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} - -/** - * Close a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_close(struct netconn *conn) -{ - /* shutting down both ends is the same as closing */ - return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); -} - -/** - * Shut down one or both sides of a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to shut down - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) -{ - return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * Join multicast groups for UDP netconns. - * - * @param conn the UDP netconn for which to change multicast addresses - * @param multiaddr IP address of the multicast group to join or leave - * @param netif_addr the IP address of the network interface on which to send - * the igmp message - * @param join_or_leave flag whether to send a join- or leave-message - * @return ERR_OK if the action was taken, any err_t on error - */ -err_t -netconn_join_leave_group(struct netconn *conn, - ip_addr_t *multiaddr, - ip_addr_t *netif_addr, - enum netconn_igmp join_or_leave) -{ - struct api_msg msg; - err_t err; - - LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); - - msg.msg.conn = conn; - msg.msg.msg.jl.multiaddr = ip_2_ipX(multiaddr); - msg.msg.msg.jl.netif_addr = ip_2_ipX(netif_addr); - msg.msg.msg.jl.join_or_leave = join_or_leave; - TCPIP_APIMSG(&msg, lwip_netconn_do_join_leave_group, err); - - NETCONN_SET_SAFE_ERR(conn, err); - return err; -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * Execute a DNS query, only one IP address is returned - * - * @param name a string representation of the DNS host name to query - * @param addr a preallocated ip_addr_t where to store the resolved IP address - * @return ERR_OK: resolving succeeded - * ERR_MEM: memory error, try again later - * ERR_ARG: dns client not initialized or invalid hostname - * ERR_VAL: dns server response was invalid - */ -err_t -netconn_gethostbyname(const char *name, ip_addr_t *addr) -{ - struct dns_api_msg msg; - err_t err; - sys_sem_t sem; - - LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); - - err = sys_sem_new(&sem, 0); - if (err != ERR_OK) { - return err; - } - - msg.name = name; - msg.addr = addr; - msg.err = &err; - msg.sem = &sem; - - tcpip_callback(lwip_netconn_do_gethostbyname, &msg); - sys_sem_wait(&sem); - sys_sem_free(&sem); - - return err; -} -#endif /* LWIP_DNS*/ - -#endif /* LWIP_NETCONN */ diff --git a/external/badvpn_dns/lwip/src/api/api_msg.c b/external/badvpn_dns/lwip/src/api/api_msg.c deleted file mode 100644 index b1a9b77..0000000 --- a/external/badvpn_dns/lwip/src/api/api_msg.c +++ /dev/null @@ -1,1610 +0,0 @@ -/** - * @file - * Sequential API Internal module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api_msg.h" - -#include "lwip/ip.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" - -#include "lwip/memp.h" -#include "lwip/tcpip.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/mld6.h" - -#include <string.h> - -#define SET_NONBLOCKING_CONNECT(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) -#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) - -/* forward declarations */ -#if LWIP_TCP -static err_t lwip_netconn_do_writemore(struct netconn *conn); -static void lwip_netconn_do_close_internal(struct netconn *conn); -#endif - -#if LWIP_RAW -/** - * Receive callback function for RAW netconns. - * Doesn't 'eat' the packet, only references it and sends it to - * conn->recvmbox - * - * @see raw.h (struct raw_pcb.recv) for parameters and return value - */ -static u8_t -recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, - ip_addr_t *addr) -{ - struct pbuf *q; - struct netbuf *buf; - struct netconn *conn; - - LWIP_UNUSED_ARG(addr); - conn = (struct netconn *)arg; - - if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) { -#if LWIP_SO_RCVBUF - int recv_avail; - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { - return 0; - } -#endif /* LWIP_SO_RCVBUF */ - /* copy the whole packet into new pbufs */ - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(q != NULL) { - if (pbuf_copy(q, p) != ERR_OK) { - pbuf_free(q); - q = NULL; - } - } - - if (q != NULL) { - u16_t len; - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(q); - return 0; - } - - buf->p = q; - buf->ptr = q; - ipX_addr_copy(PCB_ISIPV6(pcb), buf->addr, *ipX_current_src_addr()); - buf->port = pcb->protocol; - - len = q->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return 0; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - } - } - - return 0; /* do not eat the packet */ -} -#endif /* LWIP_RAW*/ - -#if LWIP_UDP -/** - * Receive callback function for UDP netconns. - * Posts the packet to conn->recvmbox or deletes it on memory error. - * - * @see udp.h (struct udp_pcb.recv) for parameters - */ -static void -recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *addr, u16_t port) -{ - struct netbuf *buf; - struct netconn *conn; - u16_t len; -#if LWIP_SO_RCVBUF - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ - LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_udp must have an argument", arg != NULL); - conn = (struct netconn *)arg; - LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); - -#if LWIP_SO_RCVBUF - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) || - ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { -#else /* LWIP_SO_RCVBUF */ - if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) { -#endif /* LWIP_SO_RCVBUF */ - pbuf_free(p); - return; - } - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(p); - return; - } else { - buf->p = p; - buf->ptr = p; - ipX_addr_set_ipaddr(ip_current_is_v6(), &buf->addr, addr); - buf->port = port; -#if LWIP_NETBUF_RECVINFO - { - /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr* udphdr = ipX_next_header_ptr(); -#if LWIP_CHECKSUM_ON_COPY - buf->flags = NETBUF_FLAG_DESTADDR; -#endif /* LWIP_CHECKSUM_ON_COPY */ - ipX_addr_set(ip_current_is_v6(), &buf->toaddr, ipX_current_dest_addr()); - buf->toport_chksum = udphdr->dest; - } -#endif /* LWIP_NETBUF_RECVINFO */ - } - - len = p->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } -} -#endif /* LWIP_UDP */ - -#if LWIP_TCP -/** - * Receive callback function for TCP netconns. - * Posts the packet to conn->recvmbox, but doesn't delete it on errors. - * - * @see tcp.h (struct tcp_pcb.recv) for parameters and return value - */ -static err_t -recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct netconn *conn; - u16_t len; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); - conn = (struct netconn *)arg; - LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); - - if (conn == NULL) { - return ERR_VAL; - } - if (!sys_mbox_valid(&conn->recvmbox)) { - /* recvmbox already deleted */ - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } - return ERR_OK; - } - /* Unlike for UDP or RAW pcbs, don't check for available space - using recv_avail since that could break the connection - (data is already ACKed) */ - - /* don't overwrite fatal errors! */ - NETCONN_SET_SAFE_ERR(conn, err); - - if (p != NULL) { - len = p->tot_len; - } else { - len = 0; - } - - if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { - /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ - return ERR_MEM; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - - return ERR_OK; -} - -/** - * Poll callback function for TCP netconns. - * Wakes up an application thread that waits for a connection to close - * or data to be sent. The application thread then takes the - * appropriate action to go on. - * - * Signals the conn->sem. - * netconn_close waits for conn->sem if closing failed. - * - * @see tcp.h (struct tcp_pcb.poll) for parameters and return value - */ -static err_t -poll_tcp(void *arg, struct tcp_pcb *pcb) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn); - } else if (conn->state == NETCONN_CLOSE) { - lwip_netconn_do_close_internal(conn); - } - /* @todo: implement connect timeout here? */ - - /* Did a nonblocking write fail before? Then check available write-space. */ - if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } - - return ERR_OK; -} - -/** - * Sent callback function for TCP netconns. - * Signals the conn->sem and calls API_EVENT. - * netconn_write waits for conn->sem if send buffer is low. - * - * @see tcp.h (struct tcp_pcb.sent) for parameters and return value - */ -static err_t -sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn); - } else if (conn->state == NETCONN_CLOSE) { - lwip_netconn_do_close_internal(conn); - } - - if (conn) { - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); - } - } - - return ERR_OK; -} - -/** - * Error callback function for TCP netconns. - * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. - * The application thread has then to decide what to do. - * - * @see tcp.h (struct tcp_pcb.err) for parameters - */ -static void -err_tcp(void *arg, err_t err) -{ - struct netconn *conn; - enum netconn_state old_state; - SYS_ARCH_DECL_PROTECT(lev); - - conn = (struct netconn *)arg; - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - conn->pcb.tcp = NULL; - - /* no check since this is always fatal! */ - SYS_ARCH_PROTECT(lev); - conn->last_err = err; - SYS_ARCH_UNPROTECT(lev); - - /* reset conn->state now before waking up other threads */ - old_state = conn->state; - conn->state = NETCONN_NONE; - - /* Notify the user layer about a connection error. Used to signal - select. */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - /* Try to release selects pending on 'read' or 'write', too. - They will get an error if they actually try to read or write. */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - /* pass NULL-message to recvmbox to wake up pending recv */ - if (sys_mbox_valid(&conn->recvmbox)) { - /* use trypost to prevent deadlock */ - sys_mbox_trypost(&conn->recvmbox, NULL); - } - /* pass NULL-message to acceptmbox to wake up pending accept */ - if (sys_mbox_valid(&conn->acceptmbox)) { - /* use trypost to preven deadlock */ - sys_mbox_trypost(&conn->acceptmbox, NULL); - } - - if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || - (old_state == NETCONN_CONNECT)) { - /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary - since the pcb has already been deleted! */ - int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - - if (!was_nonblocking_connect) { - /* set error return code */ - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - conn->current_msg->err = err; - conn->current_msg = NULL; - /* wake up the waiting task */ - sys_sem_signal(&conn->op_completed); - } - } else { - LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); - } -} - -/** - * Setup a tcp_pcb with the correct callback function pointers - * and their arguments. - * - * @param conn the TCP netconn to setup - */ -static void -setup_tcp(struct netconn *conn) -{ - struct tcp_pcb *pcb; - - pcb = conn->pcb.tcp; - tcp_arg(pcb, conn); - tcp_recv(pcb, recv_tcp); - tcp_sent(pcb, sent_tcp); - tcp_poll(pcb, poll_tcp, 4); - tcp_err(pcb, err_tcp); -} - -/** - * Accept callback function for TCP netconns. - * Allocates a new netconn and posts that to conn->acceptmbox. - * - * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value - */ -static err_t -accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - struct netconn *newconn; - struct netconn *conn = (struct netconn *)arg; - - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); - - if (!sys_mbox_valid(&conn->acceptmbox)) { - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); - return ERR_VAL; - } - - /* We have to set the callback here even though - * the new socket is unknown. conn->socket is marked as -1. */ - newconn = netconn_alloc(conn->type, conn->callback); - if (newconn == NULL) { - return ERR_MEM; - } - newconn->pcb.tcp = newpcb; - setup_tcp(newconn); - /* no protection: when creating the pcb, the netconn is not yet known - to the application thread */ - newconn->last_err = err; - - if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { - /* When returning != ERR_OK, the pcb is aborted in tcp_process(), - so do nothing here! */ - /* remove all references to this netconn from the pcb */ - struct tcp_pcb* pcb = newconn->pcb.tcp; - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_sent(pcb, NULL); - tcp_poll(pcb, NULL, 4); - tcp_err(pcb, NULL); - /* remove reference from to the pcb from this netconn */ - newconn->pcb.tcp = NULL; - /* no need to drain since we know the recvmbox is empty. */ - sys_mbox_free(&newconn->recvmbox); - sys_mbox_set_invalid(&newconn->recvmbox); - netconn_free(newconn); - return ERR_MEM; - } else { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Create a new pcb of a specific type. - * Called from lwip_netconn_do_newconn(). - * - * @param msg the api_msg_msg describing the connection type - * @return msg->conn->err, but the return value is currently ignored - */ -static void -pcb_new(struct api_msg_msg *msg) -{ - LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); - - /* Allocate a PCB for this connection */ - switch(NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->conn->pcb.raw = raw_new(msg->msg.n.proto); - if(msg->conn->pcb.raw != NULL) { - raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp = udp_new(); - if(msg->conn->pcb.udp != NULL) { -#if LWIP_UDPLITE - if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); - } -#endif /* LWIP_UDPLITE */ - if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - msg->conn->pcb.tcp = tcp_new(); - if(msg->conn->pcb.tcp != NULL) { - setup_tcp(msg->conn); - } - break; -#endif /* LWIP_TCP */ - default: - /* Unsupported netconn type, e.g. protocol disabled */ - msg->err = ERR_VAL; - return; - } - if (msg->conn->pcb.ip == NULL) { - msg->err = ERR_MEM; - } -#if LWIP_IPV6 - else { - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - ip_set_v6(msg->conn->pcb.ip, 1); - } - } -#endif /* LWIP_IPV6 */ -} - -/** - * Create a new pcb of a specific type inside a netconn. - * Called from netconn_new_with_proto_and_callback. - * - * @param msg the api_msg_msg describing the connection type - */ -void -lwip_netconn_do_newconn(struct api_msg_msg *msg) -{ - msg->err = ERR_OK; - if(msg->conn->pcb.tcp == NULL) { - pcb_new(msg); - } - /* Else? This "new" connection already has a PCB allocated. */ - /* Is this an error condition? Should it be deleted? */ - /* We currently just are happy and return. */ - - TCPIP_APIMSG_ACK(msg); -} - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is NOT created! - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param proto the IP protocol for RAW IP pcbs - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn* -netconn_alloc(enum netconn_type t, netconn_callback callback) -{ - struct netconn *conn; - int size; - - conn = (struct netconn *)memp_malloc(MEMP_NETCONN); - if (conn == NULL) { - return NULL; - } - - conn->last_err = ERR_OK; - conn->type = t; - conn->pcb.tcp = NULL; - - /* If all sizes are the same, every compiler should optimize this switch to nothing, */ - switch(NETCONNTYPE_GROUP(t)) { -#if LWIP_RAW - case NETCONN_RAW: - size = DEFAULT_RAW_RECVMBOX_SIZE; - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - size = DEFAULT_UDP_RECVMBOX_SIZE; - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - size = DEFAULT_TCP_RECVMBOX_SIZE; - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); - goto free_and_return; - } - - if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { - goto free_and_return; - } - if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { - sys_sem_free(&conn->op_completed); - goto free_and_return; - } - -#if LWIP_TCP - sys_mbox_set_invalid(&conn->acceptmbox); -#endif - conn->state = NETCONN_NONE; -#if LWIP_SOCKET - /* initialize socket to -1 since 0 is a valid socket */ - conn->socket = -1; -#endif /* LWIP_SOCKET */ - conn->callback = callback; -#if LWIP_TCP - conn->current_msg = NULL; - conn->write_offset = 0; -#endif /* LWIP_TCP */ -#if LWIP_SO_SNDTIMEO - conn->send_timeout = 0; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - conn->recv_timeout = 0; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; - conn->recv_avail = 0; -#endif /* LWIP_SO_RCVBUF */ - conn->flags = 0; - return conn; -free_and_return: - memp_free(MEMP_NETCONN, conn); - return NULL; -} - -/** - * Delete a netconn and all its resources. - * The pcb is NOT freed (since we might not be in the right thread context do this). - * - * @param conn the netconn to free - */ -void -netconn_free(struct netconn *conn) -{ - LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); - LWIP_ASSERT("recvmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("acceptmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ - - sys_sem_free(&conn->op_completed); - sys_sem_set_invalid(&conn->op_completed); - - memp_free(MEMP_NETCONN, conn); -} - -/** - * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in - * these mboxes - * - * @param conn the netconn to free - * @bytes_drained bytes drained from recvmbox - * @accepts_drained pending connections drained from acceptmbox - */ -static void -netconn_drain(struct netconn *conn) -{ - void *mem; -#if LWIP_TCP - struct pbuf *p; -#endif /* LWIP_TCP */ - - /* This runs in tcpip_thread, so we don't need to lock against rx packets */ - - /* Delete and drain the recvmbox. */ - if (sys_mbox_valid(&conn->recvmbox)) { - while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { -#if LWIP_TCP - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { - if(mem != NULL) { - p = (struct pbuf*)mem; - /* pcb might be set to NULL already by err_tcp() */ - if (conn->pcb.tcp != NULL) { - tcp_recved(conn->pcb.tcp, p->tot_len); - } - pbuf_free(p); - } - } else -#endif /* LWIP_TCP */ - { - netbuf_delete((struct netbuf *)mem); - } - } - sys_mbox_free(&conn->recvmbox); - sys_mbox_set_invalid(&conn->recvmbox); - } - - /* Delete and drain the acceptmbox. */ -#if LWIP_TCP - if (sys_mbox_valid(&conn->acceptmbox)) { - while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { - struct netconn *newconn = (struct netconn *)mem; - /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ - /* pcb might be set to NULL already by err_tcp() */ - if (conn->pcb.tcp != NULL) { - tcp_accepted(conn->pcb.tcp); - } - /* drain recvmbox */ - netconn_drain(newconn); - if (newconn->pcb.tcp != NULL) { - tcp_abort(newconn->pcb.tcp); - newconn->pcb.tcp = NULL; - } - netconn_free(newconn); - } - sys_mbox_free(&conn->acceptmbox); - sys_mbox_set_invalid(&conn->acceptmbox); - } -#endif /* LWIP_TCP */ -} - -#if LWIP_TCP -/** - * Internal helper function to close a TCP netconn: since this sometimes - * doesn't work at the first attempt, this function is called from multiple - * places. - * - * @param conn the TCP netconn to close - */ -static void -lwip_netconn_do_close_internal(struct netconn *conn) -{ - err_t err; - u8_t shut, shut_rx, shut_tx, close; - - LWIP_ASSERT("invalid conn", (conn != NULL)); - LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); - LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); - LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - - shut = conn->current_msg->msg.sd.shut; - shut_rx = shut & NETCONN_SHUT_RD; - shut_tx = shut & NETCONN_SHUT_WR; - /* shutting down both ends is the same as closing */ - close = shut == NETCONN_SHUT_RDWR; - - /* Set back some callback pointers */ - if (close) { - tcp_arg(conn->pcb.tcp, NULL); - } - if (conn->pcb.tcp->state == LISTEN) { - tcp_accept(conn->pcb.tcp, NULL); - } else { - /* some callbacks have to be reset if tcp_close is not successful */ - if (shut_rx) { - tcp_recv(conn->pcb.tcp, NULL); - tcp_accept(conn->pcb.tcp, NULL); - } - if (shut_tx) { - tcp_sent(conn->pcb.tcp, NULL); - } - if (close) { - tcp_poll(conn->pcb.tcp, NULL, 4); - tcp_err(conn->pcb.tcp, NULL); - } - } - /* Try to close the connection */ - if (close) { - err = tcp_close(conn->pcb.tcp); - } else { - err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx); - } - if (err == ERR_OK) { - /* Closing succeeded */ - conn->current_msg->err = ERR_OK; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - if (close) { - /* Set back some callback pointers as conn is going away */ - conn->pcb.tcp = NULL; - /* Trigger select() in socket layer. Make sure everybody notices activity - on the connection, error first! */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - } - if (shut_rx) { - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - if (shut_tx) { - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - /* wake up the application task */ - sys_sem_signal(&conn->op_completed); - } else { - /* Closing failed, restore some of the callbacks */ - /* Closing of listen pcb will never fail! */ - LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); - tcp_sent(conn->pcb.tcp, sent_tcp); - tcp_poll(conn->pcb.tcp, poll_tcp, 4); - tcp_err(conn->pcb.tcp, err_tcp); - tcp_arg(conn->pcb.tcp, conn); - /* don't restore recv callback: we don't want to receive any more data */ - } - /* If closing didn't succeed, we get called again either - from poll_tcp or from sent_tcp */ -} -#endif /* LWIP_TCP */ - -/** - * Delete the pcb inside a netconn. - * Called from netconn_delete. - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_delconn(struct api_msg_msg *msg) -{ - /* @todo TCP: abort running write/connect? */ - if ((msg->conn->state != NETCONN_NONE) && - (msg->conn->state != NETCONN_LISTEN) && - (msg->conn->state != NETCONN_CONNECT)) { - /* this only happens for TCP netconns */ - LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", - NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); - msg->err = ERR_INPROGRESS; - } else { - LWIP_ASSERT("blocking connect in progress", - (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); - /* Drain and delete mboxes */ - netconn_drain(msg->conn); - - if (msg->conn->pcb.tcp != NULL) { - - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - raw_remove(msg->conn->pcb.raw); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp->recv_arg = NULL; - udp_remove(msg->conn->pcb.udp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - msg->conn->state = NETCONN_CLOSE; - msg->msg.sd.shut = NETCONN_SHUT_RDWR; - msg->conn->current_msg = msg; - lwip_netconn_do_close_internal(msg->conn); - /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing - the application thread, so we can return at this point! */ - return; -#endif /* LWIP_TCP */ - default: - break; - } - msg->conn->pcb.tcp = NULL; - } - /* tcp netconns don't come here! */ - - /* @todo: this lets select make the socket readable and writable, - which is wrong! errfd instead? */ - API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); - } - if (sys_sem_valid(&msg->conn->op_completed)) { - sys_sem_signal(&msg->conn->op_completed); - } -} - -/** - * Bind a pcb contained in a netconn - * Called from netconn_bind. - * - * @param msg the api_msg_msg pointing to the connection and containing - * the IP address and port to bind to - */ -void -lwip_netconn_do_bind(struct api_msg_msg *msg) -{ - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_VAL; - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); - break; -#endif /* LWIP_TCP */ - default: - break; - } - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * TCP callback function if a connection (opened by tcp_connect/lwip_netconn_do_connect) has - * been established (or reset by the remote host). - * - * @see tcp.h (struct tcp_pcb.connected) for parameters and return values - */ -static err_t -lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) -{ - struct netconn *conn; - int was_blocking; - - LWIP_UNUSED_ARG(pcb); - - conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - - LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); - LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", - (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); - - if (conn->current_msg != NULL) { - conn->current_msg->err = err; - } - if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) { - setup_tcp(conn); - } - was_blocking = !IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - if (!was_blocking) { - NETCONN_SET_SAFE_ERR(conn, ERR_OK); - } - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - if (was_blocking) { - sys_sem_signal(&conn->op_completed); - } - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Connect a pcb contained inside a netconn - * Called from netconn_connect. - * - * @param msg the api_msg_msg pointing to the connection and containing - * the IP address and port to connect to - */ -void -lwip_netconn_do_connect(struct api_msg_msg *msg) -{ - if (msg->conn->pcb.tcp == NULL) { - /* This may happen when calling netconn_connect() a second time */ - msg->err = ERR_CLSD; - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ - sys_sem_signal(&msg->conn->op_completed); - return; - } - } else { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - /* Prevent connect while doing any other action. */ - if (msg->conn->state != NETCONN_NONE) { - msg->err = ERR_ISCONN; - } else { - setup_tcp(msg->conn); - msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, - msg->msg.bc.port, lwip_netconn_do_connected); - if (msg->err == ERR_OK) { - u8_t non_blocking = netconn_is_nonblocking(msg->conn); - msg->conn->state = NETCONN_CONNECT; - SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); - if (non_blocking) { - msg->err = ERR_INPROGRESS; - } else { - msg->conn->current_msg = msg; - /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), - * when the connection is established! */ - return; - } - } - } - /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ - sys_sem_signal(&msg->conn->op_completed); - return; -#endif /* LWIP_TCP */ - default: - LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); - break; - } - } - /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), - so use TCPIP_APIMSG_ACK() here. */ - TCPIP_APIMSG_ACK(msg); -} - -/** - * Connect a pcb contained inside a netconn - * Only used for UDP netconns. - * Called from netconn_disconnect. - * - * @param msg the api_msg_msg pointing to the connection to disconnect - */ -void -lwip_netconn_do_disconnect(struct api_msg_msg *msg) -{ -#if LWIP_UDP - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { - udp_disconnect(msg->conn->pcb.udp); - msg->err = ERR_OK; - } else -#endif /* LWIP_UDP */ - { - msg->err = ERR_VAL; - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Set a TCP pcb contained in a netconn into listen mode - * Called from netconn_listen. - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_listen(struct api_msg_msg *msg) -{ - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - if (msg->conn->state == NETCONN_NONE) { - struct tcp_pcb* lpcb; -#if LWIP_IPV6 - if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { -#if TCP_LISTEN_BACKLOG - lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); -#else /* TCP_LISTEN_BACKLOG */ - lpcb = tcp_listen_dual(msg->conn->pcb.tcp); -#endif /* TCP_LISTEN_BACKLOG */ - } else -#endif /* LWIP_IPV6 */ - { -#if TCP_LISTEN_BACKLOG - lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); -#else /* TCP_LISTEN_BACKLOG */ - lpcb = tcp_listen(msg->conn->pcb.tcp); -#endif /* TCP_LISTEN_BACKLOG */ - } - if (lpcb == NULL) { - /* in this case, the old pcb is still allocated */ - msg->err = ERR_MEM; - } else { - /* delete the recvmbox and allocate the acceptmbox */ - if (sys_mbox_valid(&msg->conn->recvmbox)) { - /** @todo: should we drain the recvmbox here? */ - sys_mbox_free(&msg->conn->recvmbox); - sys_mbox_set_invalid(&msg->conn->recvmbox); - } - msg->err = ERR_OK; - if (!sys_mbox_valid(&msg->conn->acceptmbox)) { - msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); - } - if (msg->err == ERR_OK) { - msg->conn->state = NETCONN_LISTEN; - msg->conn->pcb.tcp = lpcb; - tcp_arg(msg->conn->pcb.tcp, msg->conn); - tcp_accept(msg->conn->pcb.tcp, accept_function); - } else { - /* since the old pcb is already deallocated, free lpcb now */ - tcp_close(lpcb); - msg->conn->pcb.tcp = NULL; - } - } - } - } else { - msg->err = ERR_ARG; - } - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a RAW or UDP pcb contained in a netconn - * Called from netconn_send - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_send(struct api_msg_msg *msg) -{ - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { - msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); - } else { - msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr)); - } - break; -#endif -#if LWIP_UDP - case NETCONN_UDP: -#if LWIP_CHECKSUM_ON_COPY - if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { - msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } else { - msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, - ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } -#else /* LWIP_CHECKSUM_ON_COPY */ - if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { - msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); - } else { - msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - break; -#endif /* LWIP_UDP */ - default: - break; - } - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Indicate data has been received from a TCP pcb contained in a netconn - * Called from netconn_recv - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_recv(struct api_msg_msg *msg) -{ - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { -#if TCP_LISTEN_BACKLOG - if (msg->conn->pcb.tcp->state == LISTEN) { - tcp_accepted(msg->conn->pcb.tcp); - } else -#endif /* TCP_LISTEN_BACKLOG */ - { - u32_t remaining = msg->msg.r.len; - do { - u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; - tcp_recved(msg->conn->pcb.tcp, recved); - remaining -= recved; - }while(remaining != 0); - } - } - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * See if more data needs to be written from a previous call to netconn_write. - * Called initially from lwip_netconn_do_write. If the first call can't send all data - * (because of low memory or empty send-buffer), this function is called again - * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the - * blocking application thread (waiting in netconn_write) is released. - * - * @param conn netconn (that is currently in state NETCONN_WRITE) to process - * @return ERR_OK - * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished - */ -static err_t -lwip_netconn_do_writemore(struct netconn *conn) -{ - err_t err; - void *dataptr; - u16_t len, available; - u8_t write_finished = 0; - size_t diff; - u8_t dontblock = netconn_is_nonblocking(conn) || - (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK); - u8_t apiflags = conn->current_msg->msg.w.apiflags; - - LWIP_ASSERT("conn != NULL", conn != NULL); - LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); - LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", - conn->write_offset < conn->current_msg->msg.w.len); - -#if LWIP_SO_SNDTIMEO - if ((conn->send_timeout != 0) && - ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { - write_finished = 1; - if (conn->write_offset == 0) { - /* nothing has been written */ - err = ERR_WOULDBLOCK; - conn->current_msg->msg.w.len = 0; - } else { - /* partial write */ - err = ERR_OK; - conn->current_msg->msg.w.len = conn->write_offset; - } - } else -#endif /* LWIP_SO_SNDTIMEO */ - { - dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; - diff = conn->current_msg->msg.w.len - conn->write_offset; - if (diff > 0xffffUL) { /* max_u16_t */ - len = 0xffff; -#if LWIP_TCPIP_CORE_LOCKING - conn->flags |= NETCONN_FLAG_WRITE_DELAYED; -#endif - apiflags |= TCP_WRITE_FLAG_MORE; - } else { - len = (u16_t)diff; - } - available = tcp_sndbuf(conn->pcb.tcp); - if (available < len) { - /* don't try to write more than sendbuf */ - len = available; - if (dontblock){ - if (!len) { - err = ERR_WOULDBLOCK; - goto err_mem; - } - } else { -#if LWIP_TCPIP_CORE_LOCKING - conn->flags |= NETCONN_FLAG_WRITE_DELAYED; -#endif - apiflags |= TCP_WRITE_FLAG_MORE; - } - } - LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); - err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); - /* if OK or memory error, check available space */ - if ((err == ERR_OK) || (err == ERR_MEM)) { -err_mem: - if (dontblock && (len < conn->current_msg->msg.w.len)) { - /* non-blocking write did not write everything: mark the pcb non-writable - and let poll_tcp check writable space to mark the pcb writable again */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); - conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { - /* The queued byte- or pbuf-count exceeds the configured low-water limit, - let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); - } - } - - if (err == ERR_OK) { - conn->write_offset += len; - if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { - /* return sent length */ - conn->current_msg->msg.w.len = conn->write_offset; - /* everything was written */ - write_finished = 1; - conn->write_offset = 0; - } - tcp_output(conn->pcb.tcp); - } else if ((err == ERR_MEM) && !dontblock) { - /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called - we do NOT return to the application thread, since ERR_MEM is - only a temporary error! */ - - /* tcp_write returned ERR_MEM, try tcp_output anyway */ - tcp_output(conn->pcb.tcp); - -#if LWIP_TCPIP_CORE_LOCKING - conn->flags |= NETCONN_FLAG_WRITE_DELAYED; -#endif - } else { - /* On errors != ERR_MEM, we don't try writing any more but return - the error to the application thread. */ - write_finished = 1; - conn->current_msg->msg.w.len = 0; - } - } - if (write_finished) { - /* everything was written: set back connection state - and back to application task */ - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; -#if LWIP_TCPIP_CORE_LOCKING - if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0) -#endif - { - sys_sem_signal(&conn->op_completed); - } - } -#if LWIP_TCPIP_CORE_LOCKING - else - return ERR_MEM; -#endif - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a TCP pcb contained in a netconn - * Called from netconn_write - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_write(struct api_msg_msg *msg) -{ - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { -#if LWIP_TCP - if (msg->conn->state != NETCONN_NONE) { - /* netconn is connecting, closing or in blocking write */ - msg->err = ERR_INPROGRESS; - } else if (msg->conn->pcb.tcp != NULL) { - msg->conn->state = NETCONN_WRITE; - /* set all the variables used by lwip_netconn_do_writemore */ - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); - msg->conn->current_msg = msg; - msg->conn->write_offset = 0; -#if LWIP_TCPIP_CORE_LOCKING - msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; - if (lwip_netconn_do_writemore(msg->conn) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(&msg->conn->op_completed, 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_writemore(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG - since lwip_netconn_do_writemore ACKs it! */ - return; - } else { - msg->err = ERR_CONN; - } -#else /* LWIP_TCP */ - msg->err = ERR_VAL; -#endif /* LWIP_TCP */ -#if (LWIP_UDP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * Return a connection's local or remote address - * Called from netconn_getaddr - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_getaddr(struct api_msg_msg *msg) -{ - if (msg->conn->pcb.ip != NULL) { - if (msg->msg.ad.local) { - ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), *(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->local_ip); - } else { - ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), *(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->remote_ip); - } - msg->err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (msg->msg.ad.local) { - *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; - } else { - /* return an error as connecting is only a helper for upper layers */ - msg->err = ERR_CONN; - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - if (msg->msg.ad.local) { - *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; - } else { - if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { - msg->err = ERR_CONN; - } else { - *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; - } - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("invalid netconn_type", 0); - break; - } - } else { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * Close a TCP pcb contained in a netconn - * Called from netconn_close - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_close(struct api_msg_msg *msg) -{ -#if LWIP_TCP - /* @todo: abort running write/connect? */ - if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) { - /* this only happens for TCP netconns */ - LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", - NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); - msg->err = ERR_INPROGRESS; - } else if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)) { - if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) { - /* LISTEN doesn't support half shutdown */ - msg->err = ERR_CONN; - } else { - if (msg->msg.sd.shut & NETCONN_SHUT_RD) { - /* Drain and delete mboxes */ - netconn_drain(msg->conn); - } - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - msg->conn->state = NETCONN_CLOSE; - msg->conn->current_msg = msg; - lwip_netconn_do_close_internal(msg->conn); - /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ - return; - } - } else -#endif /* LWIP_TCP */ - { - msg->err = ERR_VAL; - } - sys_sem_signal(&msg->conn->op_completed); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * Join multicast groups for UDP netconns. - * Called from netconn_join_leave_group - * - * @param msg the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) -{ - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { -#if LWIP_UDP -#if LWIP_IPV6 && LWIP_IPV6_MLD - if (PCB_ISIPV6(msg->conn->pcb.udp)) { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup(ipX_2_ip6(msg->msg.jl.netif_addr), - ipX_2_ip6(msg->msg.jl.multiaddr)); - } else { - msg->err = mld6_leavegroup(ipX_2_ip6(msg->msg.jl.netif_addr), - ipX_2_ip6(msg->msg.jl.multiaddr)); - } - } - else -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { -#if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup(ipX_2_ip(msg->msg.jl.netif_addr), - ipX_2_ip(msg->msg.jl.multiaddr)); - } else { - msg->err = igmp_leavegroup(ipX_2_ip(msg->msg.jl.netif_addr), - ipX_2_ip(msg->msg.jl.multiaddr)); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_UDP */ -#if (LWIP_TCP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_TCP || LWIP_RAW) */ - } - } else { - msg->err = ERR_CONN; - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * Callback function that is called when DNS name is resolved - * (or on timeout). A waiting application thread is waked up by - * signaling the semaphore. - */ -static void -lwip_netconn_do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg*)arg; - - LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); - LWIP_UNUSED_ARG(name); - - if (ipaddr == NULL) { - /* timeout or memory error */ - *msg->err = ERR_VAL; - } else { - /* address was resolved */ - *msg->err = ERR_OK; - *msg->addr = *ipaddr; - } - /* wake up the application task waiting in netconn_gethostbyname */ - sys_sem_signal(msg->sem); -} - -/** - * Execute a DNS query - * Called from netconn_gethostbyname - * - * @param arg the dns_api_msg pointing to the query - */ -void -lwip_netconn_do_gethostbyname(void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg*)arg; - - *msg->err = dns_gethostbyname(msg->name, msg->addr, lwip_netconn_do_dns_found, msg); - if (*msg->err != ERR_INPROGRESS) { - /* on error or immediate success, wake up the application - * task waiting in netconn_gethostbyname */ - sys_sem_signal(msg->sem); - } -} -#endif /* LWIP_DNS */ - -#endif /* LWIP_NETCONN */ diff --git a/external/badvpn_dns/lwip/src/api/err.c b/external/badvpn_dns/lwip/src/api/err.c deleted file mode 100644 index 92fa8b7..0000000 --- a/external/badvpn_dns/lwip/src/api/err.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file - * Error Management module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/err.h" - -#ifdef LWIP_DEBUG - -static const char *err_strerr[] = { - "Ok.", /* ERR_OK 0 */ - "Out of memory error.", /* ERR_MEM -1 */ - "Buffer error.", /* ERR_BUF -2 */ - "Timeout.", /* ERR_TIMEOUT -3 */ - "Routing problem.", /* ERR_RTE -4 */ - "Operation in progress.", /* ERR_INPROGRESS -5 */ - "Illegal value.", /* ERR_VAL -6 */ - "Operation would block.", /* ERR_WOULDBLOCK -7 */ - "Address in use.", /* ERR_USE -8 */ - "Already connected.", /* ERR_ISCONN -9 */ - "Connection aborted.", /* ERR_ABRT -10 */ - "Connection reset.", /* ERR_RST -11 */ - "Connection closed.", /* ERR_CLSD -12 */ - "Not connected.", /* ERR_CONN -13 */ - "Illegal argument.", /* ERR_ARG -14 */ - "Low-level netif error.", /* ERR_IF -15 */ -}; - -/** - * Convert an lwip internal error to a string representation. - * - * @param err an lwip internal err_t - * @return a string representation for err - */ -const char * -lwip_strerr(err_t err) -{ - return err_strerr[-err]; - -} - -#endif /* LWIP_DEBUG */ diff --git a/external/badvpn_dns/lwip/src/api/netbuf.c b/external/badvpn_dns/lwip/src/api/netbuf.c deleted file mode 100644 index 0ccd2bc..0000000 --- a/external/badvpn_dns/lwip/src/api/netbuf.c +++ /dev/null @@ -1,245 +0,0 @@ -/** - * @file - * Network buffer management - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netbuf.h" -#include "lwip/memp.h" - -#include <string.h> - -/** - * Create (allocate) and initialize a new netbuf. - * The netbuf doesn't yet contain a packet buffer! - * - * @return a pointer to a new netbuf - * NULL on lack of memory - */ -struct -netbuf *netbuf_new(void) -{ - struct netbuf *buf; - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf != NULL) { - buf->p = NULL; - buf->ptr = NULL; - ipX_addr_set_any(LWIP_IPV6, &buf->addr); - buf->port = 0; -#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY -#if LWIP_CHECKSUM_ON_COPY - buf->flags = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ - buf->toport_chksum = 0; -#if LWIP_NETBUF_RECVINFO - ipX_addr_set_any(LWIP_IPV6, &buf->toaddr); -#endif /* LWIP_NETBUF_RECVINFO */ -#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ - return buf; - } else { - return NULL; - } -} - -/** - * Deallocate a netbuf allocated by netbuf_new(). - * - * @param buf pointer to a netbuf allocated by netbuf_new() - */ -void -netbuf_delete(struct netbuf *buf) -{ - if (buf != NULL) { - if (buf->p != NULL) { - pbuf_free(buf->p); - buf->p = buf->ptr = NULL; - } - memp_free(MEMP_NETBUF, buf); - } -} - -/** - * Allocate memory for a packet buffer for a given netbuf. - * - * @param buf the netbuf for which to allocate a packet buffer - * @param size the size of the packet buffer to allocate - * @return pointer to the allocated memory - * NULL if no memory could be allocated - */ -void * -netbuf_alloc(struct netbuf *buf, u16_t size) -{ - LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); - - /* Deallocate any previously allocated memory. */ - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); - if (buf->p == NULL) { - return NULL; - } - LWIP_ASSERT("check that first pbuf can hold size", - (buf->p->len >= size)); - buf->ptr = buf->p; - return buf->p->payload; -} - -/** - * Free the packet buffer included in a netbuf - * - * @param buf pointer to the netbuf which contains the packet buffer to free - */ -void -netbuf_free(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = buf->ptr = NULL; -} - -/** - * Let a netbuf reference existing (non-volatile) data. - * - * @param buf netbuf which should reference the data - * @param dataptr pointer to the data to reference - * @param size size of the data - * @return ERR_OK if data is referenced - * ERR_MEM if data couldn't be referenced due to lack of memory - */ -err_t -netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) -{ - LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (buf->p == NULL) { - buf->ptr = NULL; - return ERR_MEM; - } - buf->p->payload = (void*)dataptr; - buf->p->len = buf->p->tot_len = size; - buf->ptr = buf->p; - return ERR_OK; -} - -/** - * Chain one netbuf to another (@see pbuf_chain) - * - * @param head the first netbuf - * @param tail netbuf to chain after head, freed by this function, may not be reference after returning - */ -void -netbuf_chain(struct netbuf *head, struct netbuf *tail) -{ - LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); - LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); - pbuf_cat(head->p, tail->p); - head->ptr = head->p; - memp_free(MEMP_NETBUF, tail); -} - -/** - * Get the data pointer and length of the data inside a netbuf. - * - * @param buf netbuf to get the data from - * @param dataptr pointer to a void pointer where to store the data pointer - * @param len pointer to an u16_t where the length of the data is stored - * @return ERR_OK if the information was retreived, - * ERR_BUF on error. - */ -err_t -netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) -{ - LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); - - if (buf->ptr == NULL) { - return ERR_BUF; - } - *dataptr = buf->ptr->payload; - *len = buf->ptr->len; - return ERR_OK; -} - -/** - * Move the current data pointer of a packet buffer contained in a netbuf - * to the next part. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - * @return -1 if there is no next part - * 1 if moved to the next part but now there is no next part - * 0 if moved to the next part and there are still more parts - */ -s8_t -netbuf_next(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;); - if (buf->ptr->next == NULL) { - return -1; - } - buf->ptr = buf->ptr->next; - if (buf->ptr->next == NULL) { - return 1; - } - return 0; -} - -/** - * Move the current data pointer of a packet buffer contained in a netbuf - * to the beginning of the packet. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - */ -void -netbuf_first(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); - buf->ptr = buf->p; -} - -#endif /* LWIP_NETCONN */ diff --git a/external/badvpn_dns/lwip/src/api/netdb.c b/external/badvpn_dns/lwip/src/api/netdb.c deleted file mode 100644 index 6a4bac5..0000000 --- a/external/badvpn_dns/lwip/src/api/netdb.c +++ /dev/null @@ -1,353 +0,0 @@ -/** - * @file - * API functions for name resolving - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/netdb.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include "lwip/err.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/api.h" -#include "lwip/dns.h" - -#include <string.h> -#include <stdlib.h> - -/** helper struct for gethostbyname_r to access the char* buffer */ -struct gethostbyname_r_helper { - ip_addr_t *addr_list[2]; - ip_addr_t addr; - char *aliases; -}; - -/** h_errno is exported in netdb.h for access by applications. */ -#if LWIP_DNS_API_DECLARE_H_ERRNO -int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ - -/** define "hostent" variables storage: 0 if we use a static (but unprotected) - * set of variables for lwip_gethostbyname, 1 if we use a local storage */ -#ifndef LWIP_DNS_API_HOSTENT_STORAGE -#define LWIP_DNS_API_HOSTENT_STORAGE 0 -#endif - -/** define "hostent" variables storage */ -#if LWIP_DNS_API_HOSTENT_STORAGE -#define HOSTENT_STORAGE -#else -#define HOSTENT_STORAGE static -#endif /* LWIP_DNS_API_STATIC_HOSTENT */ - -/** - * Returns an entry containing addresses of address family AF_INET - * for the host with name name. - * Due to dns_gethostbyname limitations, only one address is returned. - * - * @param name the hostname to resolve - * @return an entry containing addresses of address family AF_INET - * for the host with name name - */ -struct hostent* -lwip_gethostbyname(const char *name) -{ - err_t err; - ip_addr_t addr; - - /* buffer variables for lwip_gethostbyname() */ - HOSTENT_STORAGE struct hostent s_hostent; - HOSTENT_STORAGE char *s_aliases; - HOSTENT_STORAGE ip_addr_t s_hostent_addr; - HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; - - /* query host IP address */ - err = netconn_gethostbyname(name, &addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - h_errno = HOST_NOT_FOUND; - return NULL; - } - - /* fill hostent */ - s_hostent_addr = addr; - s_phostent_addr[0] = &s_hostent_addr; - s_phostent_addr[1] = NULL; - s_hostent.h_name = (char*)name; - s_hostent.h_aliases = &s_aliases; - s_hostent.h_addrtype = AF_INET; - s_hostent.h_length = sizeof(ip_addr_t); - s_hostent.h_addr_list = (char**)&s_phostent_addr; - -#if DNS_DEBUG - /* dump hostent */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); - if (s_hostent.h_aliases != NULL) { - u8_t idx; - for ( idx=0; s_hostent.h_aliases[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx])); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx])); - } - } - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); - if (s_hostent.h_addr_list != NULL) { - u8_t idx; - for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx]))); - } - } -#endif /* DNS_DEBUG */ - -#if LWIP_DNS_API_HOSTENT_STORAGE - /* this function should return the "per-thread" hostent after copy from s_hostent */ - return sys_thread_hostent(&s_hostent); -#else - return &s_hostent; -#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ -} - -/** - * Thread-safe variant of lwip_gethostbyname: instead of using a static - * buffer, this function takes buffer and errno pointers as arguments - * and uses these for the result. - * - * @param name the hostname to resolve - * @param ret pre-allocated struct where to store the result - * @param buf pre-allocated buffer where to store additional data - * @param buflen the size of buf - * @param result pointer to a hostent pointer that is set to ret on success - * and set to zero on error - * @param h_errnop pointer to an int where to store errors (instead of modifying - * the global h_errno) - * @return 0 on success, non-zero on error, additional error information - * is stored in *h_errnop instead of h_errno to be thread-safe - */ -int -lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop) -{ - err_t err; - struct gethostbyname_r_helper *h; - char *hostname; - size_t namelen; - int lh_errno; - - if (h_errnop == NULL) { - /* ensure h_errnop is never NULL */ - h_errnop = &lh_errno; - } - - if (result == NULL) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - /* first thing to do: set *result to nothing */ - *result = NULL; - if ((name == NULL) || (ret == NULL) || (buf == NULL)) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - - namelen = strlen(name); - if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { - /* buf can't hold the data needed + a copy of name */ - *h_errnop = ERANGE; - return -1; - } - - h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); - hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); - - /* query host IP address */ - err = netconn_gethostbyname(name, &h->addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - *h_errnop = HOST_NOT_FOUND; - return -1; - } - - /* copy the hostname into buf */ - MEMCPY(hostname, name, namelen); - hostname[namelen] = 0; - - /* fill hostent */ - h->addr_list[0] = &h->addr; - h->addr_list[1] = NULL; - h->aliases = NULL; - ret->h_name = hostname; - ret->h_aliases = &h->aliases; - ret->h_addrtype = AF_INET; - ret->h_length = sizeof(ip_addr_t); - ret->h_addr_list = (char**)&h->addr_list; - - /* set result != NULL */ - *result = ret; - - /* return success */ - return 0; -} - -/** - * Frees one or more addrinfo structures returned by getaddrinfo(), along with - * any additional storage associated with those structures. If the ai_next field - * of the structure is not null, the entire list of structures is freed. - * - * @param ai struct addrinfo to free - */ -void -lwip_freeaddrinfo(struct addrinfo *ai) -{ - struct addrinfo *next; - - while (ai != NULL) { - next = ai->ai_next; - memp_free(MEMP_NETDB, ai); - ai = next; - } -} - -/** - * Translates the name of a service location (for example, a host name) and/or - * a service name and returns a set of socket addresses and associated - * information to be used in creating a socket with which to address the - * specified service. - * Memory for the result is allocated internally and must be freed by calling - * lwip_freeaddrinfo()! - * - * Due to a limitation in dns_gethostbyname, only the first address of a - * host is returned. - * Also, service names are not supported (only port numbers)! - * - * @param nodename descriptive name or address string of the host - * (may be NULL -> local address) - * @param servname port number as string of NULL - * @param hints structure containing input values that set socktype and protocol - * @param res pointer to a pointer where to store the result (set to NULL on failure) - * @return 0 on success, non-zero on failure - */ -int -lwip_getaddrinfo(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - err_t err; - ip_addr_t addr; - struct addrinfo *ai; - struct sockaddr_in *sa = NULL; - int port_nr = 0; - size_t total_size; - size_t namelen = 0; - - if (res == NULL) { - return EAI_FAIL; - } - *res = NULL; - if ((nodename == NULL) && (servname == NULL)) { - return EAI_NONAME; - } - - if (servname != NULL) { - /* service name specified: convert to port number - * @todo?: currently, only ASCII integers (port numbers) are supported! */ - port_nr = atoi(servname); - if ((port_nr <= 0) || (port_nr > 0xffff)) { - return EAI_SERVICE; - } - } - - if (nodename != NULL) { - /* service location specified, try to resolve */ - err = netconn_gethostbyname(nodename, &addr); - if (err != ERR_OK) { - return EAI_FAIL; - } - } else { - /* service location specified, use loopback address */ - ip_addr_set_loopback(&addr); - } - - total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in); - if (nodename != NULL) { - namelen = strlen(nodename); - LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); - total_size += namelen + 1; - } - /* If this fails, please report to lwip-devel! :-) */ - LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", - total_size <= NETDB_ELEM_SIZE); - ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); - if (ai == NULL) { - goto memerr; - } - memset(ai, 0, total_size); - sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo)); - /* set up sockaddr */ - inet_addr_from_ipaddr(&sa->sin_addr, &addr); - sa->sin_family = AF_INET; - sa->sin_len = sizeof(struct sockaddr_in); - sa->sin_port = htons((u16_t)port_nr); - - /* set up addrinfo */ - ai->ai_family = AF_INET; - if (hints != NULL) { - /* copy socktype & protocol from hints if specified */ - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - } - if (nodename != NULL) { - /* copy nodename to canonname if specified */ - ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - MEMCPY(ai->ai_canonname, nodename, namelen); - ai->ai_canonname[namelen] = 0; - } - ai->ai_addrlen = sizeof(struct sockaddr_in); - ai->ai_addr = (struct sockaddr*)sa; - - *res = ai; - - return 0; -memerr: - if (ai != NULL) { - memp_free(MEMP_NETDB, ai); - } - return EAI_MEMORY; -} - -#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/external/badvpn_dns/lwip/src/api/netifapi.c b/external/badvpn_dns/lwip/src/api/netifapi.c deleted file mode 100644 index 81403f8..0000000 --- a/external/badvpn_dns/lwip/src/api/netifapi.c +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file - * Network Interface Sequential API module - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netifapi.h" -#include "lwip/tcpip.h" - -/** - * Call netif_add() inside the tcpip_thread context. - */ -static void -netifapi_do_netif_add(struct netifapi_msg_msg *msg) -{ - if (!netif_add( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw, - msg->msg.add.state, - msg->msg.add.init, - msg->msg.add.input)) { - msg->err = ERR_IF; - } else { - msg->err = ERR_OK; - } - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call netif_set_addr() inside the tcpip_thread context. - */ -static void -netifapi_do_netif_set_addr(struct netifapi_msg_msg *msg) -{ - netif_set_addr( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw); - msg->err = ERR_OK; - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the - * tcpip_thread context. - */ -static void -netifapi_do_netif_common(struct netifapi_msg_msg *msg) -{ - if (msg->msg.common.errtfunc != NULL) { - msg->err = msg->msg.common.errtfunc(msg->netif); - } else { - msg->err = ERR_OK; - msg->msg.common.voidfunc(msg->netif); - } - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call netif_add() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_add() - */ -err_t -netifapi_netif_add(struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw, - void *state, - netif_init_fn init, - netif_input_fn input) -{ - struct netifapi_msg msg; - msg.function = netifapi_do_netif_add; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - msg.msg.msg.add.state = state; - msg.msg.msg.add.init = init; - msg.msg.msg.add.input = input; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -/** - * Call netif_set_addr() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_set_addr() - */ -err_t -netifapi_netif_set_addr(struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw) -{ - struct netifapi_msg msg; - msg.function = netifapi_do_netif_set_addr; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -/** - * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe - * way by running that function inside the tcpip_thread context. - * - * @note use only for functions where there is only "netif" parameter. - */ -err_t -netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc) -{ - struct netifapi_msg msg; - msg.function = netifapi_do_netif_common; - msg.msg.netif = netif; - msg.msg.msg.common.voidfunc = voidfunc; - msg.msg.msg.common.errtfunc = errtfunc; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -#endif /* LWIP_NETIF_API */ diff --git a/external/badvpn_dns/lwip/src/api/sockets.c b/external/badvpn_dns/lwip/src/api/sockets.c deleted file mode 100644 index 6603671..0000000 --- a/external/badvpn_dns/lwip/src/api/sockets.c +++ /dev/null @@ -1,2555 +0,0 @@ -/** - * @file - * Sockets BSD-Like API module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - * Improved by Marc Boucher marc@mbsi.ca and David Haas dhaas@alum.rpi.edu - * - */ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sockets.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/inet.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/pbuf.h" -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include <string.h> - -#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipXaddr, port) do { \ - (sin)->sin_len = sizeof(struct sockaddr_in); \ - (sin)->sin_family = AF_INET; \ - (sin)->sin_port = htons((port)); \ - inet_addr_from_ipaddr(&(sin)->sin_addr, ipX_2_ip(ipXaddr)); \ - memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) -#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipXaddr, port) do { \ - inet_addr_to_ipaddr(ipX_2_ip(ipXaddr), &((sin)->sin_addr)); \ - (port) = ntohs((sin)->sin_port); }while(0) - -#if LWIP_IPV6 -#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ - ((namelen) == sizeof(struct sockaddr_in6))) -#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ - ((name)->sa_family == AF_INET6)) -#define SOCK_ADDR_TYPE_MATCH(name, sock) \ - ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ - (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) -#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipXaddr, port) do { \ - (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ - (sin6)->sin6_family = AF_INET6; \ - (sin6)->sin6_port = htons((port)); \ - (sin6)->sin6_flowinfo = 0; \ - inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipX_2_ip6(ipXaddr)); }while(0) -#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) do { \ - if (isipv6) { \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ipXaddr, port); \ - } else { \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port); \ - } } while(0) -#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipXaddr, port) do { \ - inet6_addr_to_ip6addr(ipX_2_ip6(ipXaddr), &((sin6)->sin6_addr)); \ - (port) = ntohs((sin6)->sin6_port); }while(0) -#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) do { \ - if (isipv6) { \ - SOCKADDR6_TO_IP6ADDR_PORT((struct sockaddr_in6*)(void*)(sockaddr), ipXaddr, port); \ - } else { \ - SOCKADDR4_TO_IP4ADDR_PORT((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port); \ - } } while(0) -#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ - (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) -#else /* LWIP_IPV6 */ -#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) -#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) -#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port) -#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) \ - SOCKADDR4_TO_IP4ADDR_PORT((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) -#endif /* LWIP_IPV6 */ - -#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ - IS_SOCK_ADDR_TYPE_VALID(name)) -#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ - SOCK_ADDR_TYPE_MATCH(name, sock)) -#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) - - - -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock { - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - void *lastdata; - /** offset in the data that was left from the previous read */ - u16_t lastoffset; - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** last error that occurred on this socket */ - int err; - /** counter of how many threads are waiting for this socket using select */ - int select_waiting; -}; - -/** Description for a task waiting in select */ -struct lwip_select_cb { - /** Pointer to the next waiting task */ - struct lwip_select_cb *next; - /** Pointer to the previous waiting task */ - struct lwip_select_cb *prev; - /** readset passed to select */ - fd_set *readset; - /** writeset passed to select */ - fd_set *writeset; - /** unimplemented: exceptset passed to select */ - fd_set *exceptset; - /** don't signal the same semaphore twice: set to 1 when signalled */ - int sem_signalled; - /** semaphore to wake up a task waiting for select */ - sys_sem_t sem; -}; - -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data { - /** socket struct for which to change options */ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - /** socket index for which to change options */ - int s; -#endif /* LWIP_DEBUG */ - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ - void *optval; - /** size of *optval */ - socklen_t *optlen; - /** if an error occures, it is temporarily stored here */ - err_t err; -}; - -/** A struct sockaddr replacement that has the same alignment as sockaddr_in/ - * sockaddr_in6 if instantiated. - */ -union sockaddr_aligned { - struct sockaddr sa; -#if LWIP_IPV6 - struct sockaddr_in6 sin6; -#endif /* LWIP_IPV6 */ - struct sockaddr_in sin; -}; - - -/** The global array of available sockets */ -static struct lwip_sock sockets[NUM_SOCKETS]; -/** The global list of tasks waiting for select */ -static struct lwip_select_cb *select_cb_list; -/** This counter is increased from lwip_select when the list is chagned - and checked in event_callback to see if it has changed. */ -static volatile int select_cb_ctr; - -/** Table to quickly map an lwIP error (err_t) to a socket error - * by using -err as an index */ -static const int err_to_errno_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - EADDRINUSE, /* ERR_USE -8 Address in use. */ - EALREADY, /* ERR_ISCONN -9 Already connected. */ - ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ - ECONNRESET, /* ERR_RST -11 Connection reset. */ - ENOTCONN, /* ERR_CLSD -12 Connection closed. */ - ENOTCONN, /* ERR_CONN -13 Not connected. */ - EIO, /* ERR_ARG -14 Illegal argument. */ - -1, /* ERR_IF -15 Low-level netif error */ -}; - -#define ERR_TO_ERRNO_TABLE_SIZE \ - (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) - -#define err_to_errno(err) \ - ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ - err_to_errno_table[-(err)] : EIO) - -#ifdef ERRNO -#ifndef set_errno -#define set_errno(err) errno = (err) -#endif -#else /* ERRNO */ -#define set_errno(err) -#endif /* ERRNO */ - -#define sock_set_errno(sk, e) do { \ - sk->err = (e); \ - set_errno(sk->err); \ -} while (0) - -/* Forward delcaration of some functions */ -static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); -static void lwip_getsockopt_internal(void *arg); -static void lwip_setsockopt_internal(void *arg); - -/** - * Initialize this module. This function has to be called before any other - * functions in this module! - */ -void -lwip_socket_init(void) -{ -} - -/** - * Map a externally used socket index to the internal socket representation. - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -get_socket(int s) -{ - struct lwip_sock *sock; - - if ((s < 0) || (s >= NUM_SOCKETS)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); - set_errno(EBADF); - return NULL; - } - - sock = &sockets[s]; - - if (!sock->conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); - set_errno(EBADF); - return NULL; - } - - return sock; -} - -/** - * Same as get_socket but doesn't set errno - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -tryget_socket(int s) -{ - if ((s < 0) || (s >= NUM_SOCKETS)) { - return NULL; - } - if (!sockets[s].conn) { - return NULL; - } - return &sockets[s]; -} - -/** - * Allocate a new socket for a given netconn. - * - * @param newconn the netconn for which to allocate a socket - * @param accepted 1 if socket has been created by accept(), - * 0 if socket has been created by socket() - * @return the index of the new socket; -1 on error - */ -static int -alloc_socket(struct netconn *newconn, int accepted) -{ - int i; - SYS_ARCH_DECL_PROTECT(lev); - - /* allocate a new socket identifier */ - for (i = 0; i < NUM_SOCKETS; ++i) { - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - if (!sockets[i].conn) { - sockets[i].conn = newconn; - /* The socket is not yet known to anyone, so no need to protect - after having marked it as used. */ - SYS_ARCH_UNPROTECT(lev); - sockets[i].lastdata = NULL; - sockets[i].lastoffset = 0; - sockets[i].rcvevent = 0; - /* TCP sendbuf is empty, but the socket is not yet writable until connected - * (unless it has been created by accept()). */ - sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); - sockets[i].errevent = 0; - sockets[i].err = 0; - sockets[i].select_waiting = 0; - return i; - } - SYS_ARCH_UNPROTECT(lev); - } - return -1; -} - -/** Free a socket. The socket's netconn must have been - * delete before! - * - * @param sock the socket to free - * @param is_tcp != 0 for TCP sockets, used to free lastdata - */ -static void -free_socket(struct lwip_sock *sock, int is_tcp) -{ - void *lastdata; - SYS_ARCH_DECL_PROTECT(lev); - - lastdata = sock->lastdata; - sock->lastdata = NULL; - sock->lastoffset = 0; - sock->err = 0; - - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - sock->conn = NULL; - SYS_ARCH_UNPROTECT(lev); - /* don't use 'sock' after this line, as another task might have allocated it */ - - if (lastdata != NULL) { - if (is_tcp) { - pbuf_free((struct pbuf *)lastdata); - } else { - netbuf_delete((struct netbuf *)lastdata); - } - } -} - -/* Below this, the well-known socket functions are implemented. - * Use google.com or opengroup.org to get a good description :-) - * - * Exceptions are documented! - */ - -int -lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct lwip_sock *sock, *nsock; - struct netconn *newconn; - ipX_addr_t naddr; - u16_t port = 0; - int newsock; - err_t err; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); - sock_set_errno(sock, EWOULDBLOCK); - return -1; - } - - /* wait for a new connection */ - err = netconn_accept(sock->conn, &newconn); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return EOPNOTSUPP; - } - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - LWIP_ASSERT("newconn != NULL", newconn != NULL); - /* Prevent automatic window updates, we do this on our own! */ - netconn_set_noautorecved(newconn, 1); - - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must - * not be NULL if addr is valid. - */ - if (addr != NULL) { - union sockaddr_aligned tempaddr; - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, ipX_2_ip(&naddr), &port); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - netconn_delete(newconn); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); - - IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(newconn->type), &tempaddr, &naddr, port); - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; - } - MEMCPY(addr, &tempaddr, *addrlen); - } - - newsock = alloc_socket(newconn, 1); - if (newsock == -1) { - netconn_delete(newconn); - sock_set_errno(sock, ENFILE); - return -1; - } - LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); - LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); - nsock = &sockets[newsock]; - - /* See event_callback: If data comes in right away after an accept, even - * though the server task might not have created a new socket yet. - * In that case, newconn->socket is counted down (newconn->socket--), - * so nsock->rcvevent is >= 1 here! - */ - SYS_ARCH_PROTECT(lev); - nsock->rcvevent += (s16_t)(-1 - newconn->socket); - newconn->socket = newsock; - SYS_ARCH_UNPROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); - if (addr != NULL) { - LWIP_DEBUGF(SOCKETS_DEBUG, (" addr=")); - ipX_addr_debug_print(NETCONNTYPE_ISIPV6(newconn->type), SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); - } - - sock_set_errno(sock, 0); - return newsock; -} - -int -lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - ipX_addr_t local_addr; - u16_t local_port; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - return -1; - } - - /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - LWIP_UNUSED_ARG(namelen); - - SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &local_addr, local_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); - ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); - - err = netconn_bind(sock->conn, ipX_2_ip(&local_addr), local_port); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_close(int s) -{ - struct lwip_sock *sock; - int is_tcp = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if(sock->conn != NULL) { - is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; - } else { - LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); - } - - netconn_delete(sock->conn); - - free_socket(sock, is_tcp); - set_errno(0); - return 0; -} - -int -lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - return -1; - } - - /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - LWIP_UNUSED_ARG(namelen); - if (name->sa_family == AF_UNSPEC) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); - err = netconn_disconnect(sock->conn); - } else { - ipX_addr_t remote_addr; - u16_t remote_port; - SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &remote_addr, remote_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); - - err = netconn_connect(sock->conn, ipX_2_ip(&remote_addr), remote_port); - } - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -/** - * Set a socket into listen mode. - * The socket may not have been used for another connection previously. - * - * @param s the socket to set to listening mode - * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) - * @return 0 on success, non-zero on failure - */ -int -lwip_listen(int s, int backlog) -{ - struct lwip_sock *sock; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* limit the "backlog" parameter to fit in an u8_t */ - backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); - - err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return EOPNOTSUPP; - } - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - struct lwip_sock *sock; - void *buf = NULL; - struct pbuf *p; - u16_t buflen, copylen; - int off = 0; - u8_t done = 0; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - do { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); - /* Check if there is data left from the last recv operation. */ - if (sock->lastdata) { - buf = sock->lastdata; - } else { - /* If this is non-blocking call, then check first */ - if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && - (sock->rcvevent <= 0)) { - if (off > 0) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); - sock_set_errno(sock, EWOULDBLOCK); - return -1; - } - - /* No data was left from the previous operation, so we try to get - some from the network. */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); - } else { - err = netconn_recv(sock->conn, (struct netbuf **)&buf); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", - err, buf)); - - if (err != ERR_OK) { - if (off > 0) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - /* We should really do some error checking here. */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is "%s"!\n", - s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - if (err == ERR_CLSD) { - return 0; - } else { - return -1; - } - } - LWIP_ASSERT("buf != NULL", buf != NULL); - sock->lastdata = buf; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - p = (struct pbuf *)buf; - } else { - p = ((struct netbuf *)buf)->p; - } - buflen = p->tot_len; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", - buflen, len, off, sock->lastoffset)); - - buflen -= sock->lastoffset; - - if (len > buflen) { - copylen = buflen; - } else { - copylen = (u16_t)len; - } - - /* copy the contents of the received buffer into - the supplied memory pointer mem */ - pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); - - off += copylen; - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); - len -= copylen; - if ( (len <= 0) || - (p->flags & PBUF_FLAG_PUSH) || - (sock->rcvevent <= 0) || - ((flags & MSG_PEEK)!=0)) { - done = 1; - } - } else { - done = 1; - } - - /* Check to see from where the data was.*/ - if (done) { -#if !SOCKETS_DEBUG - if (from && fromlen) -#endif /* !SOCKETS_DEBUG */ - { - u16_t port; - ipX_addr_t tmpaddr; - ipX_addr_t *fromaddr; - union sockaddr_aligned saddr; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - fromaddr = &tmpaddr; - /* @todo: this does not work for IPv6, yet */ - netconn_getaddr(sock->conn, ipX_2_ip(fromaddr), &port, 0); - } else { - port = netbuf_fromport((struct netbuf *)buf); - fromaddr = netbuf_fromaddr_ipX((struct netbuf *)buf); - } - IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), - &saddr, fromaddr, port); - ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), - SOCKETS_DEBUG, fromaddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); -#if SOCKETS_DEBUG - if (from && fromlen) -#endif /* SOCKETS_DEBUG */ - { - if (*fromlen > saddr.sa.sa_len) { - *fromlen = saddr.sa.sa_len; - } - MEMCPY(from, &saddr, *fromlen); - } - } - } - - /* If we don't peek the incoming message... */ - if ((flags & MSG_PEEK) == 0) { - /* If this is a TCP socket, check if there is data left in the - buffer. If so, it should be saved in the sock structure for next - time around. */ - if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) && (buflen - copylen > 0)) { - sock->lastdata = buf; - sock->lastoffset += copylen; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); - } else { - sock->lastdata = NULL; - sock->lastoffset = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - pbuf_free((struct pbuf *)buf); - } else { - netbuf_delete((struct netbuf *)buf); - } - } - } - } while (!done); - - if ((off > 0) && (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - } - sock_set_errno(sock, 0); - return off; -} - -int -lwip_read(int s, void *mem, size_t len) -{ - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); -} - -int -lwip_recv(int s, void *mem, size_t len, int flags) -{ - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); -} - -int -lwip_send(int s, const void *data, size_t size, int flags) -{ - struct lwip_sock *sock; - err_t err; - u8_t write_flags; - size_t written; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", - s, data, size, flags)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { -#if (LWIP_UDP || LWIP_RAW) - return lwip_sendto(s, data, size, flags, NULL, 0); -#else /* (LWIP_UDP || LWIP_RAW) */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - - write_flags = NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); - written = 0; - err = netconn_write_partly(sock->conn, data, size, write_flags, &written); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? (int)written : -1); -} - -int -lwip_sendto(int s, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - struct lwip_sock *sock; - err_t err; - u16_t short_size; - u16_t remote_port; -#if !LWIP_TCPIP_CORE_LOCKING - struct netbuf buf; -#endif - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - return lwip_send(s, data, size, flags); -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(flags); - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* LWIP_TCP */ - } - - if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - return -1; - } - - /* @todo: split into multiple sendto's? */ - LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); - short_size = (u16_t)size; - LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || - (IS_SOCK_ADDR_LEN_VALID(tolen) && - IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - LWIP_UNUSED_ARG(tolen); - -#if LWIP_TCPIP_CORE_LOCKING - /* Special speedup for fast UDP/RAW sending: call the raw API directly - instead of using the netconn functions. */ - { - struct pbuf* p; - ipX_addr_t *remote_addr; - ipX_addr_t remote_addr_tmp; - -#if LWIP_NETIF_TX_SINGLE_PBUF - p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); - if (p != NULL) { -#if LWIP_CHECKSUM_ON_COPY - u16_t chksum = 0; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { - chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - MEMCPY(p->payload, data, size); -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); - if (p != NULL) { - p->payload = (void*)data; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - if (to != NULL) { - SOCKADDR_TO_IPXADDR_PORT(to->sa_family == AF_INET6, - to, &remote_addr_tmp, remote_port); - remote_addr = &remote_addr_tmp; - } else { - remote_addr = &sock->conn->pcb.ip->remote_ip; -#if LWIP_UDP - if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) { - remote_port = sock->conn->pcb.udp->remote_port; - } else -#endif /* LWIP_UDP */ - { - remote_port = 0; - } - } - - LOCK_TCPIP_CORE(); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { -#if LWIP_RAW - err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, ipX_2_ip(remote_addr)); -#else /* LWIP_RAW */ - err = ERR_ARG; -#endif /* LWIP_RAW */ - } -#if LWIP_UDP && LWIP_RAW - else -#endif /* LWIP_UDP && LWIP_RAW */ - { -#if LWIP_UDP -#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF - err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, - ipX_2_ip(remote_addr), remote_port, 1, chksum); -#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ - err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, - ipX_2_ip(remote_addr), remote_port); -#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ -#else /* LWIP_UDP */ - err = ERR_ARG; -#endif /* LWIP_UDP */ - } - UNLOCK_TCPIP_CORE(); - - pbuf_free(p); - } else { - err = ERR_MEM; - } - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - /* initialize a buffer */ - buf.p = buf.ptr = NULL; -#if LWIP_CHECKSUM_ON_COPY - buf.flags = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ - if (to) { - SOCKADDR_TO_IPXADDR_PORT((to->sa_family) == AF_INET6, to, &buf.addr, remote_port); - } else { - remote_port = 0; - ipX_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); - } - netbuf_fromport(&buf) = remote_port; - - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", - s, data, short_size, flags)); - ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), - SOCKETS_DEBUG, &buf.addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); - - /* make the buffer point to the data that should be sent */ -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&buf, short_size) == NULL) { - err = ERR_MEM; - } else { -#if LWIP_CHECKSUM_ON_COPY - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { - u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); - netbuf_set_chksum(&buf, chksum); - err = ERR_OK; - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - err = netbuf_take(&buf, data, short_size); - } - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - err = netbuf_ref(&buf, data, short_size); -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) { - /* send the data */ - err = netconn_send(sock->conn, &buf); - } - - /* deallocated the buffer */ - netbuf_free(&buf); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? short_size : -1); -} - -int -lwip_socket(int domain, int type, int protocol) -{ - struct netconn *conn; - int i; - -#if !LWIP_IPV6 - LWIP_UNUSED_ARG(domain); /* @todo: check this */ -#endif /* LWIP_IPV6 */ - - /* create a netconn */ - switch (type) { - case SOCK_RAW: - conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), - (u8_t)protocol, event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_DGRAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, - ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) , - event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_STREAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - if (conn != NULL) { - /* Prevent automatic window updates, we do this on our own! */ - netconn_set_noautorecved(conn, 1); - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", - domain, type, protocol)); - set_errno(EINVAL); - return -1; - } - - if (!conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); - set_errno(ENOBUFS); - return -1; - } - - i = alloc_socket(conn, 0); - - if (i == -1) { - netconn_delete(conn); - set_errno(ENFILE); - return -1; - } - conn->socket = i; - LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); - set_errno(0); - return i; -} - -int -lwip_write(int s, const void *data, size_t size) -{ - return lwip_send(s, data, size, 0); -} - -/** - * Go through the readset and writeset lists and see which socket of the sockets - * set in the sets has events. On return, readset, writeset and exceptset have - * the sockets enabled that had events. - * - * exceptset is not used for now!!! - * - * @param maxfdp1 the highest socket index in the sets - * @param readset_in: set of sockets to check for read events - * @param writeset_in: set of sockets to check for write events - * @param exceptset_in: set of sockets to check for error events - * @param readset_out: set of sockets that had read events - * @param writeset_out: set of sockets that had write events - * @param exceptset_out: set os sockets that had error events - * @return number of sockets that had events (read/write/exception) (>= 0) - */ -static int -lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, - fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) -{ - int i, nready = 0; - fd_set lreadset, lwriteset, lexceptset; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - FD_ZERO(&lreadset); - FD_ZERO(&lwriteset); - FD_ZERO(&lexceptset); - - /* Go through each socket in each list to count number of sockets which - currently match */ - for(i = 0; i < maxfdp1; i++) { - void* lastdata = NULL; - s16_t rcvevent = 0; - u16_t sendevent = 0; - u16_t errevent = 0; - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket(i); - if (sock != NULL) { - lastdata = sock->lastdata; - rcvevent = sock->rcvevent; - sendevent = sock->sendevent; - errevent = sock->errevent; - } - SYS_ARCH_UNPROTECT(lev); - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { - FD_SET(i, &lreadset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); - nready++; - } - /* See if netconn of this socket is ready for write */ - if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { - FD_SET(i, &lwriteset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); - nready++; - } - /* See if netconn of this socket had an error */ - if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { - FD_SET(i, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); - nready++; - } - } - /* copy local sets to the ones provided as arguments */ - *readset_out = lreadset; - *writeset_out = lwriteset; - *exceptset_out = lexceptset; - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; -} - -/** - * Processing exceptset is not yet implemented. - */ -int -lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout) -{ - u32_t waitres = 0; - int nready; - fd_set lreadset, lwriteset, lexceptset; - u32_t msectimeout; - struct lwip_select_cb select_cb; - err_t err; - int i; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", - maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, - timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, - timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); - - /* Go through each socket in each list to count number of sockets which - currently match */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - - /* If we don't have any current events, then suspend if we are supposed to */ - if (!nready) { - if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables. */ - - select_cb.next = NULL; - select_cb.prev = NULL; - select_cb.readset = readset; - select_cb.writeset = writeset; - select_cb.exceptset = exceptset; - select_cb.sem_signalled = 0; - err = sys_sem_new(&select_cb.sem, 0); - if (err != ERR_OK) { - /* failed to create semaphore */ - set_errno(ENOMEM); - return -1; - } - - /* Protect the select_cb_list */ - SYS_ARCH_PROTECT(lev); - - /* Put this select_cb on top of list */ - select_cb.next = select_cb_list; - if (select_cb_list != NULL) { - select_cb_list->prev = &select_cb; - } - select_cb_list = &select_cb; - /* Increasing this counter tells even_callback that the list has changed. */ - select_cb_ctr++; - - /* Now we can safely unprotect */ - SYS_ARCH_UNPROTECT(lev); - - /* Increase select_waiting for each socket we are interested in */ - for(i = 0; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock = tryget_socket(i); - LWIP_ASSERT("sock != NULL", sock != NULL); - SYS_ARCH_PROTECT(lev); - sock->select_waiting++; - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - SYS_ARCH_UNPROTECT(lev); - } - } - - /* Call lwip_selscan again: there could have been events between - the last scan (whithout us on the list) and putting us on the list! */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - if (!nready) { - /* Still none ready, just wait to be woken */ - if (timeout == 0) { - /* Wait forever */ - msectimeout = 0; - } else { - msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); - if (msectimeout == 0) { - /* Wait 1ms at least (0 means wait forever) */ - msectimeout = 1; - } - } - - waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout); - } - /* Increase select_waiting for each socket we are interested in */ - for(i = 0; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock = tryget_socket(i); - LWIP_ASSERT("sock != NULL", sock != NULL); - SYS_ARCH_PROTECT(lev); - sock->select_waiting--; - LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0); - SYS_ARCH_UNPROTECT(lev); - } - } - /* Take us off the list */ - SYS_ARCH_PROTECT(lev); - if (select_cb.next != NULL) { - select_cb.next->prev = select_cb.prev; - } - if (select_cb_list == &select_cb) { - LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); - select_cb_list = select_cb.next; - } else { - LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); - select_cb.prev->next = select_cb.next; - } - /* Increasing this counter tells even_callback that the list has changed. */ - select_cb_ctr++; - SYS_ARCH_UNPROTECT(lev); - - sys_sem_free(&select_cb.sem); - if (waitres == SYS_ARCH_TIMEOUT) { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* See what's set */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); -return_copy_fdsets: - set_errno(0); - if (readset) { - *readset = lreadset; - } - if (writeset) { - *writeset = lwriteset; - } - if (exceptset) { - *exceptset = lexceptset; - } - return nready; -} - -/** - * Callback registered in the netconn layer for each socket-netconn. - * Processes recvevent (data available) and wakes up tasks waiting for select. - */ -static void -event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) -{ - int s; - struct lwip_sock *sock; - struct lwip_select_cb *scb; - int last_select_cb_ctr; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(len); - - /* Get socket */ - if (conn) { - s = conn->socket; - if (s < 0) { - /* Data comes in right away after an accept, even though - * the server task might not have created a new socket yet. - * Just count down (or up) if that's the case and we - * will use the data later. Note that only receive events - * can happen before the new socket is set up. */ - SYS_ARCH_PROTECT(lev); - if (conn->socket < 0) { - if (evt == NETCONN_EVT_RCVPLUS) { - conn->socket--; - } - SYS_ARCH_UNPROTECT(lev); - return; - } - s = conn->socket; - SYS_ARCH_UNPROTECT(lev); - } - - sock = get_socket(s); - if (!sock) { - return; - } - } else { - return; - } - - SYS_ARCH_PROTECT(lev); - /* Set event as required */ - switch (evt) { - case NETCONN_EVT_RCVPLUS: - sock->rcvevent++; - break; - case NETCONN_EVT_RCVMINUS: - sock->rcvevent--; - break; - case NETCONN_EVT_SENDPLUS: - sock->sendevent = 1; - break; - case NETCONN_EVT_SENDMINUS: - sock->sendevent = 0; - break; - case NETCONN_EVT_ERROR: - sock->errevent = 1; - break; - default: - LWIP_ASSERT("unknown event", 0); - break; - } - - if (sock->select_waiting == 0) { - /* noone is waiting for this socket, no need to check select_cb_list */ - SYS_ARCH_UNPROTECT(lev); - return; - } - - /* Now decide if anyone is waiting for this socket */ - /* NOTE: This code goes through the select_cb_list list multiple times - ONLY IF a select was actually waiting. We go through the list the number - of waiting select calls + 1. This list is expected to be small. */ - - /* At this point, SYS_ARCH is still protected! */ -again: - for (scb = select_cb_list; scb != NULL; scb = scb->next) { - if (scb->sem_signalled == 0) { - /* semaphore not signalled yet */ - int do_signal = 0; - /* Test this select call for our socket */ - if (sock->rcvevent > 0) { - if (scb->readset && FD_ISSET(s, scb->readset)) { - do_signal = 1; - } - } - if (sock->sendevent != 0) { - if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { - do_signal = 1; - } - } - if (sock->errevent != 0) { - if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { - do_signal = 1; - } - } - if (do_signal) { - scb->sem_signalled = 1; - /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might - lead to the select thread taking itself off the list, invalidagin the semaphore. */ - sys_sem_signal(&scb->sem); - } - } - /* unlock interrupts with each step */ - last_select_cb_ctr = select_cb_ctr; - SYS_ARCH_UNPROTECT(lev); - /* this makes sure interrupt protection time is short */ - SYS_ARCH_PROTECT(lev); - if (last_select_cb_ctr != select_cb_ctr) { - /* someone has changed select_cb_list, restart at the beginning */ - goto again; - } - } - SYS_ARCH_UNPROTECT(lev); -} - -/** - * Unimplemented: Close one end of a full-duplex connection. - * Currently, the full connection is closed. - */ -int -lwip_shutdown(int s, int how) -{ - struct lwip_sock *sock; - err_t err; - u8_t shut_rx = 0, shut_tx = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return EOPNOTSUPP; - } - } else { - sock_set_errno(sock, ENOTCONN); - return ENOTCONN; - } - - if (how == SHUT_RD) { - shut_rx = 1; - } else if (how == SHUT_WR) { - shut_tx = 1; - } else if(how == SHUT_RDWR) { - shut_rx = 1; - shut_tx = 1; - } else { - sock_set_errno(sock, EINVAL); - return EINVAL; - } - err = netconn_shutdown(sock->conn, shut_rx, shut_tx); - - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? 0 : -1); -} - -static int -lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) -{ - struct lwip_sock *sock; - union sockaddr_aligned saddr; - ipX_addr_t naddr; - u16_t port; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* get the IP address and port */ - /* @todo: this does not work for IPv6, yet */ - netconn_getaddr(sock->conn, ipX_2_ip(&naddr), &port, local); - IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), - &saddr, &naddr, port); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), - SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); - - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; - } - MEMCPY(name, &saddr, *namelen); - - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 0); -} - -int -lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 1); -} - -int -lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - err_t err = ERR_OK; - struct lwip_sock *sock = get_socket(s); - struct lwip_setgetsockopt_data data; - - if (!sock) { - return -1; - } - - if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); - return -1; - } - - /* Do length and type checks for the various options first, to keep it readable. */ - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - case SO_ACCEPTCONN: - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_ERROR: - case SO_KEEPALIVE: - /* UNIMPL case SO_CONTIMEO: */ -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: -#endif /* LWIP_SO_RCVBUF */ - /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_SNDBUF: */ - /* UNIMPL case SO_RCVLOWAT: */ - /* UNIMPL case SO_SNDLOWAT: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - case SO_TYPE: - /* UNIMPL case SO_USELOOPBACK: */ - if (*optlen < sizeof(int)) { - err = EINVAL; - } - break; - - case SO_NO_CHECK: - if (*optlen < sizeof(int)) { - err = EINVAL; - } -#if LWIP_UDP - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP || - ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { - /* this flag is only available for UDP, not for UDP lite */ - err = EAFNOSUPPORT; - } -#endif /* LWIP_UDP */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - /* UNIMPL case IP_HDRINCL: */ - /* UNIMPL case IP_RCVDSTADDR: */ - /* UNIMPL case IP_RCVIF: */ - case IP_TTL: - case IP_TOS: - if (*optlen < sizeof(int)) { - err = EINVAL; - } - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - if (*optlen < sizeof(u8_t)) { - err = EINVAL; - } - break; - case IP_MULTICAST_IF: - if (*optlen < sizeof(struct in_addr)) { - err = EINVAL; - } - break; - case IP_MULTICAST_LOOP: - if (*optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; -#endif /* LWIP_IGMP */ - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - if (*optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no TCP socket, ignore any options. */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - return 0; - - switch (optname) { - case TCP_NODELAY: - case TCP_KEEPALIVE: -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - case TCP_KEEPINTVL: - case TCP_KEEPCNT: -#endif /* LWIP_TCP_KEEPALIVE */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - if (*optlen < sizeof(int)) { - err = EINVAL; - } - /* @todo: this does not work for datagram sockets, yet */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - return 0; - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - if (*optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { - return 0; - } - - switch (optname) { - case UDPLITE_SEND_CSCOV: - case UDPLITE_RECV_CSCOV: - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP && LWIP_UDPLITE*/ -/* UNDEFINED LEVEL */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - } /* switch */ - - - if (err != ERR_OK) { - sock_set_errno(sock, err); - return -1; - } - - /* Now do the actual option processing */ - data.sock = sock; -#ifdef LWIP_DEBUG - data.s = s; -#endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = optval; - data.optlen = optlen; - data.err = err; - tcpip_callback(lwip_getsockopt_internal, &data); - sys_arch_sem_wait(&sock->conn->op_completed, 0); - /* maybe lwip_getsockopt_internal has changed err */ - err = data.err; - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -static void -lwip_getsockopt_internal(void *arg) -{ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - int s; -#endif /* LWIP_DEBUG */ - int level, optname; - void *optval; - struct lwip_setgetsockopt_data *data; - - LWIP_ASSERT("arg != NULL", arg != NULL); - - data = (struct lwip_setgetsockopt_data*)arg; - sock = data->sock; -#ifdef LWIP_DEBUG - s = data->s; -#endif /* LWIP_DEBUG */ - level = data->level; - optname = data->optname; - optval = data->optval; - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* The option flags */ - case SO_ACCEPTCONN: - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case SO_OOBINCLUDE: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /*case SO_USELOOPBACK: UNIMPL */ - *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", - s, optname, (*(int*)optval?"on":"off"))); - break; - - case SO_TYPE: - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { - case NETCONN_RAW: - *(int*)optval = SOCK_RAW; - break; - case NETCONN_TCP: - *(int*)optval = SOCK_STREAM; - break; - case NETCONN_UDP: - *(int*)optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int*)optval = netconn_type(sock->conn); - LWIP_DEBUGF(SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", - s, *(int *)optval)); - } /* switch (netconn_type(sock->conn)) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", - s, *(int *)optval)); - break; - - case SO_ERROR: - /* only overwrite ERR_OK or tempoary errors */ - if ((sock->err == 0) || (sock->err == EINPROGRESS)) { - sock_set_errno(sock, err_to_errno(sock->conn->last_err)); - } - *(int *)optval = sock->err; - sock->err = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - *(int *)optval = netconn_get_sendtimeout(sock->conn); - break; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - *(int *)optval = netconn_get_recvtimeout(sock->conn); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - *(int *)optval = netconn_get_recvbufsize(sock->conn); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_UDP - case SO_NO_CHECK: - *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; - break; -#endif /* LWIP_UDP*/ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - *(int*)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_TOS: - *(int*)optval = sock->conn->pcb.ip->tos; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", - s, *(int *)optval)); - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - *(u8_t*)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_MULTICAST_IF: - inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", - s, *(u32_t *)optval)); - break; - case IP_MULTICAST_LOOP: - if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { - *(u8_t*)optval = 1; - } else { - *(u8_t*)optval = 0; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_IGMP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - switch (optname) { - case TCP_NODELAY: - *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", - s, (*(int*)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPINTVL: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPCNT: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - *(int*)optval = ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", - s, *(int *)optval)); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - switch (optname) { - case UDPLITE_SEND_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled level", 0); - break; - } /* switch (level) */ - sys_sem_signal(&sock->conn->op_completed); -} - -int -lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - struct lwip_sock *sock = get_socket(s); - err_t err = ERR_OK; - struct lwip_setgetsockopt_data data; - - if (!sock) { - return -1; - } - - if (NULL == optval) { - sock_set_errno(sock, EFAULT); - return -1; - } - - /* Do length and type checks for the various options first, to keep it readable. */ - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case case SO_CONTIMEO: */ -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: -#endif /* LWIP_SO_RCVBUF */ - /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_SNDBUF: */ - /* UNIMPL case SO_RCVLOWAT: */ - /* UNIMPL case SO_SNDLOWAT: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /* UNIMPL case SO_USELOOPBACK: */ - if (optlen < sizeof(int)) { - err = EINVAL; - } - break; - case SO_NO_CHECK: - if (optlen < sizeof(int)) { - err = EINVAL; - } -#if LWIP_UDP - if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) || - ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { - /* this flag is only available for UDP, not for UDP lite */ - err = EAFNOSUPPORT; - } -#endif /* LWIP_UDP */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - /* UNIMPL case IP_HDRINCL: */ - /* UNIMPL case IP_RCVDSTADDR: */ - /* UNIMPL case IP_RCVIF: */ - case IP_TTL: - case IP_TOS: - if (optlen < sizeof(int)) { - err = EINVAL; - } - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - if (optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_MULTICAST_IF: - if (optlen < sizeof(struct in_addr)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_MULTICAST_LOOP: - if (optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - if (optlen < sizeof(struct ip_mreq)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - if (optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no TCP socket, ignore any options. */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - return 0; - - switch (optname) { - case TCP_NODELAY: - case TCP_KEEPALIVE: -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - case TCP_KEEPINTVL: - case TCP_KEEPCNT: -#endif /* LWIP_TCP_KEEPALIVE */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - if (optlen < sizeof(int)) { - err = EINVAL; - } - - /* @todo: this does not work for datagram sockets, yet */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - return 0; - - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - if (optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) - return 0; - - switch (optname) { - case UDPLITE_SEND_CSCOV: - case UDPLITE_RECV_CSCOV: - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP && LWIP_UDPLITE */ -/* UNDEFINED LEVEL */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - } /* switch (level) */ - - - if (err != ERR_OK) { - sock_set_errno(sock, err); - return -1; - } - - - /* Now do the actual option processing */ - data.sock = sock; -#ifdef LWIP_DEBUG - data.s = s; -#endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = (void*)optval; - data.optlen = &optlen; - data.err = err; - tcpip_callback(lwip_setsockopt_internal, &data); - sys_arch_sem_wait(&sock->conn->op_completed, 0); - /* maybe lwip_setsockopt_internal has changed err */ - err = data.err; - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -static void -lwip_setsockopt_internal(void *arg) -{ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - int s; -#endif /* LWIP_DEBUG */ - int level, optname; - const void *optval; - struct lwip_setgetsockopt_data *data; - - LWIP_ASSERT("arg != NULL", arg != NULL); - - data = (struct lwip_setgetsockopt_data*)arg; - sock = data->sock; -#ifdef LWIP_DEBUG - s = data->s; -#endif /* LWIP_DEBUG */ - level = data->level; - optname = data->optname; - optval = data->optval; - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* The option flags */ - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case SO_OOBINCLUDE: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /* UNIMPL case SO_USELOOPBACK: */ - if (*(int*)optval) { - ip_set_option(sock->conn->pcb.ip, optname); - } else { - ip_reset_option(sock->conn->pcb.ip, optname); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", - s, optname, (*(int*)optval?"on":"off"))); - break; -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval); - break; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - netconn_set_recvtimeout(sock->conn, *(int*)optval); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - netconn_set_recvbufsize(sock->conn, *(int*)optval); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_UDP - case SO_NO_CHECK: - if (*(int*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); - } - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", - s, sock->conn->pcb.ip->ttl)); - break; - case IP_TOS: - sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", - s, sock->conn->pcb.ip->tos)); - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); - break; - case IP_MULTICAST_IF: - inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); - break; - case IP_MULTICAST_LOOP: - if (*(u8_t*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); - } - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* If this is a TCP or a RAW socket, ignore these options. */ - struct ip_mreq *imr = (struct ip_mreq *)optval; - ip_addr_t if_addr; - ip_addr_t multi_addr; - inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); - inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); - if(optname == IP_ADD_MEMBERSHIP){ - data->err = igmp_joingroup(&if_addr, &multi_addr); - } else { - data->err = igmp_leavegroup(&if_addr, &multi_addr); - } - if(data->err != ERR_OK) { - data->err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - switch (optname) { - case TCP_NODELAY: - if (*(int*)optval) { - tcp_nagle_disable(sock->conn->pcb.tcp); - } else { - tcp_nagle_enable(sock->conn->pcb.tcp); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", - s, (*(int *)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - case TCP_KEEPINTVL: - sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_intvl)); - break; - case TCP_KEEPCNT: - sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_cnt)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP*/ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - if (*(int*)optval) { - sock->conn->flags |= NETCONN_FLAG_IPV6_V6ONLY; - } else { - sock->conn->flags &= ~NETCONN_FLAG_IPV6_V6ONLY; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", - s, ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0))); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - switch (optname) { - case UDPLITE_SEND_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_tx = 8; - } else { - sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", - s, (*(int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_rx = 8; - } else { - sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", - s, (*(int*)optval)) ); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled level", 0); - break; - } /* switch (level) */ - sys_sem_signal(&sock->conn->op_completed); -} - -int -lwip_ioctl(int s, long cmd, void *argp) -{ - struct lwip_sock *sock = get_socket(s); - u8_t val; -#if LWIP_SO_RCVBUF - u16_t buflen = 0; - s16_t recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - if (!sock) { - return -1; - } - - switch (cmd) { -#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE - case FIONREAD: - if (!argp) { - sock_set_errno(sock, EINVAL); - return -1; - } -#if LWIP_FIONREAD_LINUXMODE - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - struct pbuf *p; - if (sock->lastdata) { - p = ((struct netbuf *)sock->lastdata)->p; - } else { - struct netbuf *rxbuf; - err_t err; - if (sock->rcvevent <= 0) { - *((u16_t*)argp) = 0; - } else { - err = netconn_recv(sock->conn, &rxbuf); - if (err != ERR_OK) { - *((u16_t*)argp) = 0; - } else { - sock->lastdata = rxbuf; - *((u16_t*)argp) = rxbuf->p->tot_len; - } - } - } - return 0; - } -#endif /* LWIP_FIONREAD_LINUXMODE */ - -#if LWIP_SO_RCVBUF - /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ - SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); - if (recv_avail < 0) { - recv_avail = 0; - } - *((u16_t*)argp) = (u16_t)recv_avail; - - /* Check if there is data left from the last recv operation. /maq 041215 */ - if (sock->lastdata) { - struct pbuf *p = (struct pbuf *)sock->lastdata; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - p = ((struct netbuf *)p)->p; - } - buflen = p->tot_len; - buflen -= sock->lastoffset; - - *((u16_t*)argp) += buflen; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); - sock_set_errno(sock, 0); - return 0; -#else /* LWIP_SO_RCVBUF */ - break; -#endif /* LWIP_SO_RCVBUF */ -#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ - - case FIONBIO: - val = 0; - if (argp && *(u32_t*)argp) { - val = 1; - } - netconn_set_nonblocking(sock->conn, val); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); - sock_set_errno(sock, 0); - return 0; - - default: - break; - } /* switch (cmd) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - return -1; -} - -/** A minimal implementation of fcntl. - * Currently only the commands F_GETFL and F_SETFL are implemented. - * Only the flag O_NONBLOCK is implemented. - */ -int -lwip_fcntl(int s, int cmd, int val) -{ - struct lwip_sock *sock = get_socket(s); - int ret = -1; - - if (!sock || !sock->conn) { - return -1; - } - - switch (cmd) { - case F_GETFL: - ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; - break; - case F_SETFL: - if ((val & ~O_NONBLOCK) == 0) { - /* only O_NONBLOCK, all other bits are zero */ - netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); - ret = 0; - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); - break; - } - return ret; -} - -#endif /* LWIP_SOCKET */ diff --git a/external/badvpn_dns/lwip/src/api/tcpip.c b/external/badvpn_dns/lwip/src/api/tcpip.c deleted file mode 100644 index 7c1c9ca..0000000 --- a/external/badvpn_dns/lwip/src/api/tcpip.c +++ /dev/null @@ -1,492 +0,0 @@ -/** - * @file - * Sequential API Main thread module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/memp.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/tcpip.h" -#include "lwip/init.h" -#include "netif/etharp.h" -#include "netif/ppp_oe.h" - -/* global variables */ -static tcpip_init_done_fn tcpip_init_done; -static void *tcpip_init_done_arg; -static sys_mbox_t mbox; - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -sys_mutex_t lock_tcpip_core; -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - -/** - * The main lwIP thread. This thread has exclusive access to lwIP core functions - * (unless access to them is not locked). Other threads communicate with this - * thread using message boxes. - * - * It also starts all the timers to make sure they are running in the right - * thread context. - * - * @param arg unused argument - */ -static void -tcpip_thread(void *arg) -{ - struct tcpip_msg *msg; - LWIP_UNUSED_ARG(arg); - - if (tcpip_init_done != NULL) { - tcpip_init_done(tcpip_init_done_arg); - } - - LOCK_TCPIP_CORE(); - while (1) { /* MAIN Loop */ - UNLOCK_TCPIP_CORE(); - LWIP_TCPIP_THREAD_ALIVE(); - /* wait for a message, timeouts are processed while waiting */ - sys_timeouts_mbox_fetch(&mbox, (void **)&msg); - LOCK_TCPIP_CORE(); - switch (msg->type) { -#if LWIP_NETCONN - case TCPIP_MSG_API: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); - msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); - break; -#endif /* LWIP_NETCONN */ - -#if !LWIP_TCPIP_CORE_LOCKING_INPUT - case TCPIP_MSG_INPKT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); -#if LWIP_ETHERNET - if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); - } else -#endif /* LWIP_ETHERNET */ -#if LWIP_IPV6 - if ((*((unsigned char *)(msg->msg.inp.p->payload)) & 0xf0) == 0x60) { - ip6_input(msg->msg.inp.p, msg->msg.inp.netif); - } else -#endif /* LWIP_IPV6 */ - { - ip_input(msg->msg.inp.p, msg->msg.inp.netif); - } - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - break; -#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ - -#if LWIP_NETIF_API - case TCPIP_MSG_NETIFAPI: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); - msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); - break; -#endif /* LWIP_NETIF_API */ - -#if LWIP_TCPIP_TIMEOUT - case TCPIP_MSG_TIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); - sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - case TCPIP_MSG_UNTIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); - sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; -#endif /* LWIP_TCPIP_TIMEOUT */ - - case TCPIP_MSG_CALLBACK: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - - case TCPIP_MSG_CALLBACK_STATIC: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - break; - - default: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); - LWIP_ASSERT("tcpip_thread: invalid message", 0); - break; - } - } -} - -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet, p->payload pointing to the Ethernet header or - * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or - * NETIF_FLAG_ETHERNET flags) - * @param inp the network interface on which the packet was received - */ -err_t -tcpip_input(struct pbuf *p, struct netif *inp) -{ -#if LWIP_TCPIP_CORE_LOCKING_INPUT - err_t ret; - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); - LOCK_TCPIP_CORE(); -#if LWIP_ETHERNET - if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - ret = ethernet_input(p, inp); - } else -#endif /* LWIP_ETHERNET */ - { - ret = ip_input(p, inp); - } - UNLOCK_TCPIP_CORE(); - return ret; -#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ - struct tcpip_msg *msg; - - if (!sys_mbox_valid(&mbox)) { - return ERR_VAL; - } - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_INPKT; - msg->msg.inp.p = p; - msg->msg.inp.netif = inp; - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - return ERR_MEM; - } - return ERR_OK; -#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ -} - -/** - * Call a specific function in the thread context of - * tcpip_thread for easy access synchronization. - * A function called in that way may access lwIP core code - * without fearing concurrent access. - * - * @param f the function to call - * @param ctx parameter passed to f - * @param block 1 to block until the request is posted, 0 to non-blocking mode - * @return ERR_OK if the function was called, another err_t if not - */ -err_t -tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) -{ - struct tcpip_msg *msg; - - if (sys_mbox_valid(&mbox)) { - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_CALLBACK; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - if (block) { - sys_mbox_post(&mbox, msg); - } else { - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_API, msg); - return ERR_MEM; - } - } - return ERR_OK; - } - return ERR_VAL; -} - -#if LWIP_TCPIP_TIMEOUT -/** - * call sys_timeout in tcpip_thread - * - * @param msec time in milliseconds for timeout - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - if (sys_mbox_valid(&mbox)) { - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_TIMEOUT; - msg->msg.tmo.msecs = msecs; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&mbox, msg); - return ERR_OK; - } - return ERR_VAL; -} - -/** - * call sys_untimeout in tcpip_thread - * - * @param msec time in milliseconds for timeout - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_untimeout(sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - if (sys_mbox_valid(&mbox)) { - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_UNTIMEOUT; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&mbox, msg); - return ERR_OK; - } - return ERR_VAL; -} -#endif /* LWIP_TCPIP_TIMEOUT */ - -#if LWIP_NETCONN -/** - * Call the lower part of a netconn_* function - * This function is then running in the thread context - * of tcpip_thread and has exclusive access to lwIP core code. - * - * @param apimsg a struct containing the function to call and its parameters - * @return ERR_OK if the function was called, another err_t if not - */ -err_t -tcpip_apimsg(struct api_msg *apimsg) -{ - struct tcpip_msg msg; -#ifdef LWIP_DEBUG - /* catch functions that don't set err */ - apimsg->msg.err = ERR_VAL; -#endif - - if (sys_mbox_valid(&mbox)) { - msg.type = TCPIP_MSG_API; - msg.msg.apimsg = apimsg; - sys_mbox_post(&mbox, &msg); - sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0); - return apimsg->msg.err; - } - return ERR_VAL; -} - -#endif /* LWIP_NETCONN */ - -#if LWIP_NETIF_API -#if !LWIP_TCPIP_CORE_LOCKING -/** - * Much like tcpip_apimsg, but calls the lower part of a netifapi_* - * function. - * - * @param netifapimsg a struct containing the function to call and its parameters - * @return error code given back by the function that was called - */ -err_t -tcpip_netifapi(struct netifapi_msg* netifapimsg) -{ - struct tcpip_msg msg; - - if (sys_mbox_valid(&mbox)) { - err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); - if (err != ERR_OK) { - netifapimsg->msg.err = err; - return err; - } - - msg.type = TCPIP_MSG_NETIFAPI; - msg.msg.netifapimsg = netifapimsg; - sys_mbox_post(&mbox, &msg); - sys_sem_wait(&netifapimsg->msg.sem); - sys_sem_free(&netifapimsg->msg.sem); - return netifapimsg->msg.err; - } - return ERR_VAL; -} -#else /* !LWIP_TCPIP_CORE_LOCKING */ -/** - * Call the lower part of a netifapi_* function - * This function has exclusive access to lwIP core code by locking it - * before the function is called. - * - * @param netifapimsg a struct containing the function to call and its parameters - * @return ERR_OK (only for compatibility fo tcpip_netifapi()) - */ -err_t -tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) -{ - LOCK_TCPIP_CORE(); - netifapimsg->function(&(netifapimsg->msg)); - UNLOCK_TCPIP_CORE(); - return netifapimsg->msg.err; -} -#endif /* !LWIP_TCPIP_CORE_LOCKING */ -#endif /* LWIP_NETIF_API */ - -/** - * Allocate a structure for a static callback message and initialize it. - * This is intended to be used to send "static" messages from interrupt context. - * - * @param function the function to call - * @param ctx parameter passed to function - * @return a struct pointer to pass to tcpip_trycallback(). - */ -struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) -{ - struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return NULL; - } - msg->type = TCPIP_MSG_CALLBACK_STATIC; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - return (struct tcpip_callback_msg*)msg; -} - -/** - * Free a callback message allocated by tcpip_callbackmsg_new(). - * - * @param msg the message to free - */ -void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) -{ - memp_free(MEMP_TCPIP_MSG_API, msg); -} - -/** - * Try to post a callback-message to the tcpip_thread mbox - * This is intended to be used to send "static" messages from interrupt context. - * - * @param msg pointer to the message to post - * @return sys_mbox_trypost() return code - */ -err_t -tcpip_trycallback(struct tcpip_callback_msg* msg) -{ - if (!sys_mbox_valid(&mbox)) { - return ERR_VAL; - } - return sys_mbox_trypost(&mbox, msg); -} - -/** - * Initialize this module: - * - initialize all sub modules - * - start the tcpip_thread - * - * @param initfunc a function to call when tcpip_thread is running and finished initializing - * @param arg argument to pass to initfunc - */ -void -tcpip_init(tcpip_init_done_fn initfunc, void *arg) -{ - lwip_init(); - - tcpip_init_done = initfunc; - tcpip_init_done_arg = arg; - if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { - LWIP_ASSERT("failed to create tcpip_thread mbox", 0); - } -#if LWIP_TCPIP_CORE_LOCKING - if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) { - LWIP_ASSERT("failed to create lock_tcpip_core", 0); - } -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); -} - -/** - * Simple callback function used with tcpip_callback to free a pbuf - * (pbuf_free has a wrong signature for tcpip_callback) - * - * @param p The pbuf (chain) to be dereferenced. - */ -static void -pbuf_free_int(void *p) -{ - struct pbuf *q = (struct pbuf *)p; - pbuf_free(q); -} - -/** - * A simple wrapper function that allows you to free a pbuf from interrupt context. - * - * @param p The pbuf (chain) to be dereferenced. - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -pbuf_free_callback(struct pbuf *p) -{ - return tcpip_callback_with_block(pbuf_free_int, p, 0); -} - -/** - * A simple wrapper function that allows you to free heap memory from - * interrupt context. - * - * @param m the heap memory to free - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -mem_free_callback(void *m) -{ - return tcpip_callback_with_block(mem_free, m, 0); -} - -#endif /* !NO_SYS */ diff --git a/external/badvpn_dns/lwip/src/core/def.c b/external/badvpn_dns/lwip/src/core/def.c deleted file mode 100644 index 352b552..0000000 --- a/external/badvpn_dns/lwip/src/core/def.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file - * Common functions used throughout the stack. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" -#include "lwip/def.h" - -/** - * These are reference implementations of the byte swapping functions. - * Again with the aim of being simple, correct and fully portable. - * Byte swapping is the second thing you would want to optimize. You will - * need to port it to your architecture and in your cc.h: - * - * #define LWIP_PLATFORM_BYTESWAP 1 - * #define LWIP_PLATFORM_HTONS(x) <your_htons> - * #define LWIP_PLATFORM_HTONL(x) <your_htonl> - * - * Note ntohs() and ntohl() are merely references to the htonx counterparts. - */ - -#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) - -/** - * Convert an u16_t from host- to network byte order. - * - * @param n u16_t in host byte order - * @return n in network byte order - */ -u16_t -lwip_htons(u16_t n) -{ - return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); -} - -/** - * Convert an u16_t from network- to host byte order. - * - * @param n u16_t in network byte order - * @return n in host byte order - */ -u16_t -lwip_ntohs(u16_t n) -{ - return lwip_htons(n); -} - -/** - * Convert an u32_t from host- to network byte order. - * - * @param n u32_t in host byte order - * @return n in network byte order - */ -u32_t -lwip_htonl(u32_t n) -{ - return ((n & 0xff) << 24) | - ((n & 0xff00) << 8) | - ((n & 0xff0000UL) >> 8) | - ((n & 0xff000000UL) >> 24); -} - -/** - * Convert an u32_t from network- to host byte order. - * - * @param n u32_t in network byte order - * @return n in host byte order - */ -u32_t -lwip_ntohl(u32_t n) -{ - return lwip_htonl(n); -} - -#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ diff --git a/external/badvpn_dns/lwip/src/core/dhcp.c b/external/badvpn_dns/lwip/src/core/dhcp.c deleted file mode 100644 index 21fd784..0000000 --- a/external/badvpn_dns/lwip/src/core/dhcp.c +++ /dev/null @@ -1,1771 +0,0 @@ -/** - * @file - * Dynamic Host Configuration Protocol client - * - */ - -/* - * - * Copyright (c) 2001-2004 Leon Woestenberg leon.woestenberg@gmx.net - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. - * - * Author: Leon Woestenberg leon.woestenberg@gmx.net - * - * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform - * with RFC 2131 and RFC 2132. - * - * TODO: - * - Support for interfaces other than Ethernet (SLIP, PPP, ...) - * - * Please coordinate changes and requests with Leon Woestenberg - * leon.woestenberg@gmx.net - * - * Integration with your code: - * - * In lwip/dhcp.h - * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) - * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) - * - * Then have your application call dhcp_coarse_tmr() and - * dhcp_fine_tmr() on the defined intervals. - * - * dhcp_start(struct netif *netif); - * starts a DHCP client instance which configures the interface by - * obtaining an IP address lease and maintaining it. - * - * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif) - * to remove the DHCP client. - * - */ - -#include "lwip/opt.h" - -#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/dns.h" -#include "netif/etharp.h" - -#include <string.h> - -/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using - * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) - */ -#ifndef DHCP_CREATE_RAND_XID -#define DHCP_CREATE_RAND_XID 1 -#endif - -/** Default for DHCP_GLOBAL_XID is 0xABCD0000 - * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. - * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" - * #define DHCP_GLOBAL_XID rand() - */ -#ifdef DHCP_GLOBAL_XID_HEADER -#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ -#endif - -/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU - * MTU is checked to be big enough in dhcp_start */ -#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) -#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 -/** Minimum length for reply before packet is parsed */ -#define DHCP_MIN_REPLY_LEN 44 - -#define REBOOT_TRIES 2 - -/** Option handling: options are parsed in dhcp_parse_reply - * and saved in an array where other functions can load them from. - * This might be moved into the struct dhcp (not necessarily since - * lwIP is single-threaded and the array is only used while in recv - * callback). */ -#define DHCP_OPTION_IDX_OVERLOAD 0 -#define DHCP_OPTION_IDX_MSG_TYPE 1 -#define DHCP_OPTION_IDX_SERVER_ID 2 -#define DHCP_OPTION_IDX_LEASE_TIME 3 -#define DHCP_OPTION_IDX_T1 4 -#define DHCP_OPTION_IDX_T2 5 -#define DHCP_OPTION_IDX_SUBNET_MASK 6 -#define DHCP_OPTION_IDX_ROUTER 7 -#define DHCP_OPTION_IDX_DNS_SERVER 8 -#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS) - -/** Holds the decoded option values, only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; -/** Holds a flag which option was received and is contained in dhcp_rx_options_val, - only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; - -#ifdef DHCP_GLOBAL_XID -static u32_t xid; -static u8_t xid_initialised; -#endif /* DHCP_GLOBAL_XID */ - -#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) -#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) -#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) -#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) -#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) -#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) - - -/* DHCP client state machine functions */ -static err_t dhcp_discover(struct netif *netif); -static err_t dhcp_select(struct netif *netif); -static void dhcp_bind(struct netif *netif); -#if DHCP_DOES_ARP_CHECK -static err_t dhcp_decline(struct netif *netif); -#endif /* DHCP_DOES_ARP_CHECK */ -static err_t dhcp_rebind(struct netif *netif); -static err_t dhcp_reboot(struct netif *netif); -static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); - -/* receive, unfold, parse and free incoming messages */ -static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); - -/* set the DHCP timers */ -static void dhcp_timeout(struct netif *netif); -static void dhcp_t1_timeout(struct netif *netif); -static void dhcp_t2_timeout(struct netif *netif); - -/* build outgoing messages */ -/* create a DHCP message, fill in common headers */ -static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type); -/* free a DHCP request */ -static void dhcp_delete_msg(struct dhcp *dhcp); -/* add a DHCP option (type, then length in bytes) */ -static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); -/* add option values */ -static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); -static void dhcp_option_short(struct dhcp *dhcp, u16_t value); -static void dhcp_option_long(struct dhcp *dhcp, u32_t value); -#if LWIP_NETIF_HOSTNAME -static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); -#endif /* LWIP_NETIF_HOSTNAME */ -/* always add the DHCP options trailer to end and pad */ -static void dhcp_option_trailer(struct dhcp *dhcp); - -/** - * Back-off the DHCP client (because of a received NAK response). - * - * Back-off the DHCP client because of a received NAK. Receiving a - * NAK means the client asked for something non-sensible, for - * example when it tries to renew a lease obtained on another network. - * - * We clear any existing set IP address and restart DHCP negotiation - * afresh (as per RFC2131 3.2.3). - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_nak(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* Set the interface down since the address must no longer be used, as per RFC2131 */ - netif_set_down(netif); - /* remove IP address from interface */ - netif_set_ipaddr(netif, IP_ADDR_ANY); - netif_set_gw(netif, IP_ADDR_ANY); - netif_set_netmask(netif, IP_ADDR_ANY); - /* Change to a defined state */ - dhcp_set_state(dhcp, DHCP_BACKING_OFF); - /* We can immediately restart discovery */ - dhcp_discover(netif); -} - -#if DHCP_DOES_ARP_CHECK -/** - * Checks if the offered IP address is already in use. - * - * It does so by sending an ARP request for the offered address and - * entering CHECKING state. If no ARP reply is received within a small - * interval, the address is assumed to be free for use by us. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_check(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], - (s16_t)netif->name[1])); - dhcp_set_state(dhcp, DHCP_CHECKING); - /* create an ARP query for the offered IP address, expecting that no host - responds, as the IP address should not be in use. */ - result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); - if (result != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); - } - dhcp->tries++; - msecs = 500; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); -} -#endif /* DHCP_DOES_ARP_CHECK */ - -/** - * Remember the configuration offered by a DHCP server. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_offer(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* obtain the server address */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { - ip4_addr_set_u32(&dhcp->server_ip_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->server_ip_addr))); - /* remember offered address */ - ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif)); - } -} - -/** - * Select a DHCP server offer out of all offers. - * - * Simply select the first offer received. - * - * @param netif the netif under DHCP control - * @return lwIP specific error (see error.h) - */ -static err_t -dhcp_select(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - dhcp_set_state(dhcp, DHCP_REQUESTING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - /* MUST request the offered IP address */ - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); - dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr))); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); - dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); - dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); - dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); - dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - dhcp_option_trailer(dhcp); - /* shrink the pbuf to the actual content length */ - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - /* send broadcast to any DHCP server */ - udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); - } - dhcp->tries++; - msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * The DHCP timer that checks for lease renewal/rebind timeouts. - */ -void -dhcp_coarse_tmr() -{ - struct netif *netif = netif_list; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); - /* iterate through all network interfaces */ - while (netif != NULL) { - /* only act on DHCP configured interfaces */ - if (netif->dhcp != NULL) { - /* timer is active (non zero), and triggers (zeroes) now? */ - if (netif->dhcp->t2_timeout-- == 1) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); - /* this clients' rebind timeout triggered */ - dhcp_t2_timeout(netif); - /* timer is active (non zero), and triggers (zeroes) now */ - } else if (netif->dhcp->t1_timeout-- == 1) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); - /* this clients' renewal timeout triggered */ - dhcp_t1_timeout(netif); - } - } - /* proceed to next netif */ - netif = netif->next; - } -} - -/** - * DHCP transaction timeout handling - * - * A DHCP server is expected to respond within a short period of time. - * This timer checks whether an outstanding DHCP request is timed out. - */ -void -dhcp_fine_tmr() -{ - struct netif *netif = netif_list; - /* loop through netif's */ - while (netif != NULL) { - /* only act on DHCP configured interfaces */ - if (netif->dhcp != NULL) { - /* timer is active (non zero), and is about to trigger now */ - if (netif->dhcp->request_timeout > 1) { - netif->dhcp->request_timeout--; - } - else if (netif->dhcp->request_timeout == 1) { - netif->dhcp->request_timeout--; - /* { netif->dhcp->request_timeout == 0 } */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); - /* this client's request timeout triggered */ - dhcp_timeout(netif); - } - } - /* proceed to next network interface */ - netif = netif->next; - } -} - -/** - * A DHCP negotiation transaction, or ARP request, has timed out. - * - * The timer that was started with the DHCP or ARP request has - * timed out, indicating no response was received in time. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); - /* back-off period has passed, or server selection timed out */ - if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); - dhcp_discover(netif); - /* receiving the requested lease timed out */ - } else if (dhcp->state == DHCP_REQUESTING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); - if (dhcp->tries <= 5) { - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); - dhcp_release(netif); - dhcp_discover(netif); - } -#if DHCP_DOES_ARP_CHECK - /* received no ARP reply for the offered address (which is good) */ - } else if (dhcp->state == DHCP_CHECKING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); - if (dhcp->tries <= 1) { - dhcp_check(netif); - /* no ARP replies on the offered address, - looks like the IP address is indeed free */ - } else { - /* bind the interface to the offered address */ - dhcp_bind(netif); - } -#endif /* DHCP_DOES_ARP_CHECK */ - } - /* did not get response to renew request? */ - else if (dhcp->state == DHCP_RENEWING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); - /* just retry renewal */ - /* note that the rebind timer will eventually time-out if renew does not work */ - dhcp_renew(netif); - /* did not get response to rebind request? */ - } else if (dhcp->state == DHCP_REBINDING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); - if (dhcp->tries <= 8) { - dhcp_rebind(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); - dhcp_release(netif); - dhcp_discover(netif); - } - } else if (dhcp->state == DHCP_REBOOTING) { - if (dhcp->tries < REBOOT_TRIES) { - dhcp_reboot(netif); - } else { - dhcp_discover(netif); - } - } -} - -/** - * The renewal period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t1_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); - if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || - (dhcp->state == DHCP_RENEWING)) { - /* just retry to renew - note that the rebind timer (t2) will - * eventually time-out if renew tries fail. */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t1_timeout(): must renew\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_RENEWING, not DHCP_BOUND */ - dhcp_renew(netif); - } -} - -/** - * The rebind period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t2_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); - if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || - (dhcp->state == DHCP_RENEWING)) { - /* just retry to rebind */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t2_timeout(): must rebind\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_REBINDING, not DHCP_BOUND */ - dhcp_rebind(netif); - } -} - -/** - * Handle a DHCP ACK packet - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_ack(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; -#if LWIP_DNS - u8_t n; -#endif /* LWIP_DNS */ - - /* clear options we might not get from the ACK */ - ip_addr_set_zero(&dhcp->offered_sn_mask); - ip_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* lease time given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { - /* remember offered lease time */ - dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); - } - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { - /* remember given renewal period */ - dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); - } else { - /* calculate safe periods for renewal */ - dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; - } - - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { - /* remember given rebind period */ - dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); - } else { - /* calculate safe periods for rebinding */ - dhcp->offered_t2_rebind = dhcp->offered_t0_lease; - } - - /* (y)our internet address */ - ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); - -#if LWIP_DHCP_BOOTP_FILE - /* copy boot server address, - boot file name copied in dhcp_parse_reply if not overloaded */ - ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* subnet mask given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { - /* remember given subnet mask */ - ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); - dhcp->subnet_mask_given = 1; - } else { - dhcp->subnet_mask_given = 0; - } - - /* gateway router */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { - ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); - } - -#if LWIP_DNS - /* DNS servers */ - for(n = 0; (n < DNS_MAX_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { - ip_addr_t dns_addr; - ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); - dns_setserver(n, &dns_addr); - } -#endif /* LWIP_DNS */ -} - -/** Set a statically allocated struct dhcp to work with. - * Using this prevents dhcp_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct dhcp - * @param dhcp (uninitialised) dhcp struct allocated by the application - */ -void -dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) -{ - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("dhcp != NULL", dhcp != NULL); - LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL); - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_OFF); */ - netif->dhcp = dhcp; -} - -/** Removes a struct dhcp from a netif. - * - * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the - * struct dhcp since the memory is passed back to the heap. - * - * @param netif the netif from which to remove the struct dhcp - */ -void dhcp_cleanup(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", netif != NULL); - - if (netif->dhcp != NULL) { - mem_free(netif->dhcp); - netif->dhcp = NULL; - } -} - -/** - * Start DHCP negotiation for a network interface. - * - * If no DHCP client instance was attached to this interface, - * a new client is created first. If a DHCP client instance - * was already present, it restarts negotiation. - * - * @param netif The lwIP network interface - * @return lwIP error code - * - ERR_OK - No error - * - ERR_MEM - Out of memory - */ -err_t -dhcp_start(struct netif *netif) -{ - struct dhcp *dhcp; - err_t result = ERR_OK; - - LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); - dhcp = netif->dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* Remove the flag that says this netif is handled by DHCP, - it is set when we succeeded starting. */ - netif->flags &= ~NETIF_FLAG_DHCP; - - /* check hwtype of the netif */ - if ((netif->flags & NETIF_FLAG_ETHARP) == 0) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n")); - return ERR_ARG; - } - - /* check MTU of the netif */ - if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); - return ERR_MEM; - } - - /* no DHCP client attached yet? */ - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); - dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); - return ERR_MEM; - } - /* store this dhcp client in the netif */ - netif->dhcp = dhcp; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); - /* already has DHCP client attached */ - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); - if (dhcp->pcb != NULL) { - udp_remove(dhcp->pcb); - } - LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); - } - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_OFF); */ - /* allocate UDP PCB */ - dhcp->pcb = udp_new(); - if (dhcp->pcb == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); - return ERR_MEM; - } - ip_set_option(dhcp->pcb, SOF_BROADCAST); - /* set up local and remote port for the pcb */ - udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); - udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); - /* set up the recv callback and argument */ - udp_recv(dhcp->pcb, dhcp_recv, netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); - /* (re)start the DHCP negotiation */ - result = dhcp_discover(netif); - if (result != ERR_OK) { - /* free resources allocated above */ - dhcp_stop(netif); - return ERR_MEM; - } - /* Set the flag that says this netif is handled by DHCP. */ - netif->flags |= NETIF_FLAG_DHCP; - return result; -} - -/** - * Inform a DHCP server of our manual configuration. - * - * This informs DHCP servers of our fixed IP address configuration - * by sending an INFORM message. It does not involve DHCP address - * configuration, it is just here to be nice to the network. - * - * @param netif The lwIP network interface - */ -void -dhcp_inform(struct netif *netif) -{ - struct dhcp dhcp; - err_t result = ERR_OK; - struct udp_pcb *pcb; - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - memset(&dhcp, 0, sizeof(struct dhcp)); - dhcp_set_state(&dhcp, DHCP_INFORM); - - if ((netif->dhcp != NULL) && (netif->dhcp->pcb != NULL)) { - /* re-use existing pcb */ - pcb = netif->dhcp->pcb; - } else { - pcb = udp_new(); - if (pcb == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); - return; - } - dhcp.pcb = pcb; - ip_set_option(dhcp.pcb, SOF_BROADCAST); - udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); - } - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM); - if (result == ERR_OK) { - dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option_trailer(&dhcp); - - pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); - udp_sendto_if(pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(&dhcp); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); - } - - if (dhcp.pcb != NULL) { - /* otherwise, the existing pcb was used */ - udp_remove(dhcp.pcb); - } -} - -/** Handle a possible change in the network configuration. - * - * This enters the REBOOTING state to verify that the currently bound - * address is still valid. - */ -void -dhcp_network_changed(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - if (!dhcp) - return; - switch (dhcp->state) { - case DHCP_REBINDING: - case DHCP_RENEWING: - case DHCP_BOUND: - case DHCP_REBOOTING: - netif_set_down(netif); - dhcp->tries = 0; - dhcp_reboot(netif); - break; - case DHCP_OFF: - /* stay off */ - break; - default: - dhcp->tries = 0; -#if LWIP_DHCP_AUTOIP_COOP - if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - dhcp_discover(netif); - break; - } -} - -#if DHCP_DOES_ARP_CHECK -/** - * Match an ARP reply with the offered IP address. - * - * @param netif the network interface on which the reply was received - * @param addr The IP address we received a reply from - */ -void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr) -{ - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); - /* is a DHCP client doing an ARP check? */ - if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", - ip4_addr_get_u32(addr))); - /* did a host respond with the address we - were offered by the DHCP server? */ - if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { - /* we will not accept the offered address */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); - dhcp_decline(netif); - } - } -} - -/** - * Decline an offered lease. - * - * Tell the DHCP server we do not accept the offered address. - * One reason to decline the lease is when we find out the address - * is already in use by another host (through ARP). - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_decline(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result = ERR_OK; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); - dhcp_set_state(dhcp, DHCP_BACKING_OFF); - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option_trailer(dhcp); - /* resize pbuf to reflect true size of options */ - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - /* per section 4.4.4, broadcast DECLINE messages */ - udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_decline: could not allocate DHCP request\n")); - } - dhcp->tries++; - msecs = 10*1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} -#endif /* DHCP_DOES_ARP_CHECK */ - - -/** - * Start the DHCP process, discover a DHCP server. - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_discover(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result = ERR_OK; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); - ip_addr_set_any(&dhcp->offered_ip_addr); - dhcp_set_state(dhcp, DHCP_SELECTING); - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER); - if (result == ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); - - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); - dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); - dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); - dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); - dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); - - dhcp_option_trailer(dhcp); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); - udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); - } - dhcp->tries++; -#if LWIP_DHCP_AUTOIP_COOP - if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; - autoip_start(netif); - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - - -/** - * Bind the interface to the offered IP address. - * - * @param netif network interface to bind to the offered address - */ -static void -dhcp_bind(struct netif *netif) -{ - u32_t timeout; - struct dhcp *dhcp; - ip_addr_t sn_mask, gw_addr; - LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); - dhcp = netif->dhcp; - LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - /* temporary DHCP lease? */ - if (dhcp->offered_t1_renew != 0xffffffffUL) { - /* set renewal period timer */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); - timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if(timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t1_timeout = (u16_t)timeout; - if (dhcp->t1_timeout == 0) { - dhcp->t1_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); - } - /* set renewal period timer */ - if (dhcp->offered_t2_rebind != 0xffffffffUL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); - timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if(timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t2_timeout = (u16_t)timeout; - if (dhcp->t2_timeout == 0) { - dhcp->t2_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); - } - - /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ - if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { - dhcp->t1_timeout = 0; - } - - if (dhcp->subnet_mask_given) { - /* copy offered network mask */ - ip_addr_copy(sn_mask, dhcp->offered_sn_mask); - } else { - /* subnet mask not given, choose a safe subnet mask given the network class */ - u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); - if (first_octet <= 127) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); - } else if (first_octet >= 192) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); - } else { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); - } - } - - ip_addr_copy(gw_addr, dhcp->offered_gw_addr); - /* gateway address not given? */ - if (ip_addr_isany(&gw_addr)) { - /* copy network address */ - ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); - /* use first host address on network as gateway */ - ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); - } - -#if LWIP_DHCP_AUTOIP_COOP - if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr))); - netif_set_ipaddr(netif, &dhcp->offered_ip_addr); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", - ip4_addr_get_u32(&sn_mask))); - netif_set_netmask(netif, &sn_mask); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", - ip4_addr_get_u32(&gw_addr))); - netif_set_gw(netif, &gw_addr); - /* bring the interface up */ - netif_set_up(netif); - /* netif is now bound to DHCP leased address */ - dhcp_set_state(dhcp, DHCP_BOUND); -} - -/** - * Renew an existing DHCP lease at the involved DHCP server. - * - * @param netif network interface which must renew its lease - */ -err_t -dhcp_renew(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); - dhcp_set_state(dhcp, DHCP_RENEWING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - -#if 0 - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); -#endif - -#if 0 - dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); - dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); -#endif - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - /* append DHCP message trailer */ - dhcp_option_trailer(dhcp); - - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); - } - dhcp->tries++; - /* back-off on retries, but to a maximum of 20 seconds */ - msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Rebind with a DHCP server for an existing DHCP lease. - * - * @param netif network interface which must rebind with a DHCP server - */ -static err_t -dhcp_rebind(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); - dhcp_set_state(dhcp, DHCP_REBINDING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - -#if 0 - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); - - dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); - dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); -#endif - - dhcp_option_trailer(dhcp); - - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - /* broadcast to server */ - udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); - } - dhcp->tries++; - msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Enter REBOOTING state to verify an existing lease - * - * @param netif network interface which must reboot - */ -static err_t -dhcp_reboot(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); - dhcp_set_state(dhcp, DHCP_REBOOTING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, 576); - - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option_trailer(dhcp); - - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - /* broadcast to server */ - udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); - } - dhcp->tries++; - msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - - -/** - * Release a DHCP lease. - * - * @param netif network interface which must release its lease - */ -err_t -dhcp_release(struct netif *netif) -{ - struct dhcp *dhcp = netif->dhcp; - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); - if (dhcp == NULL) { - return ERR_ARG; - } - - /* idle DHCP client */ - dhcp_set_state(dhcp, DHCP_OFF); - /* clean old DHCP offer */ - ip_addr_set_zero(&dhcp->server_ip_addr); - ip_addr_set_zero(&dhcp->offered_ip_addr); - ip_addr_set_zero(&dhcp->offered_sn_mask); - ip_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); - if (result == ERR_OK) { - dhcp_option_trailer(dhcp); - - pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); - - udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); - } - dhcp->tries++; - msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; - dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); - /* bring the interface down */ - netif_set_down(netif); - /* remove IP address from interface */ - netif_set_ipaddr(netif, IP_ADDR_ANY); - netif_set_gw(netif, IP_ADDR_ANY); - netif_set_netmask(netif, IP_ADDR_ANY); - - return result; -} - -/** - * Remove the DHCP client from the interface. - * - * @param netif The network interface to stop DHCP on - */ -void -dhcp_stop(struct netif *netif) -{ - struct dhcp *dhcp; - LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); - dhcp = netif->dhcp; - /* Remove the flag that says this netif is handled by DHCP. */ - netif->flags &= ~NETIF_FLAG_DHCP; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); - /* netif is DHCP configured? */ - if (dhcp != NULL) { -#if LWIP_DHCP_AUTOIP_COOP - if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - if (dhcp->pcb != NULL) { - udp_remove(dhcp->pcb); - dhcp->pcb = NULL; - } - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); - dhcp_set_state(dhcp, DHCP_OFF); - } -} - -/* - * Set the DHCP state of a DHCP client. - * - * If the state changed, reset the number of tries. - */ -static void -dhcp_set_state(struct dhcp *dhcp, u8_t new_state) -{ - if (new_state != dhcp->state) { - dhcp->state = new_state; - dhcp->tries = 0; - dhcp->request_timeout = 0; - } -} - -/* - * Concatenate an option type and length field to the outgoing - * DHCP message. - * - */ -static void -dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) -{ - LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = option_type; - dhcp->msg_out->options[dhcp->options_out_len++] = option_len; -} -/* - * Concatenate a single byte to the outgoing DHCP message. - * - */ -static void -dhcp_option_byte(struct dhcp *dhcp, u8_t value) -{ - LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = value; -} - -static void -dhcp_option_short(struct dhcp *dhcp, u16_t value) -{ - LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); -} - -static void -dhcp_option_long(struct dhcp *dhcp, u32_t value) -{ - LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); -} - -#if LWIP_NETIF_HOSTNAME -static void -dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) -{ - if (netif->hostname != NULL) { - size_t namelen = strlen(netif->hostname); - if (namelen > 0) { - u8_t len; - const char *p = netif->hostname; - /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME - and 1 byte for trailer) */ - size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; - LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); - len = LWIP_MIN(namelen, available); - dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len); - while (len--) { - dhcp_option_byte(dhcp, *p++); - } - } - } -} -#endif /* LWIP_NETIF_HOSTNAME */ - -/** - * Extract the DHCP message and the DHCP options. - * - * Extract the DHCP message and the DHCP options, each into a contiguous - * piece of memory. As a DHCP message is variable sized by its options, - * and also allows overriding some fields for options, the easy approach - * is to first unfold the options into a conitguous piece of memory, and - * use that further on. - * - */ -static err_t -dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) -{ - u8_t *options; - u16_t offset; - u16_t offset_max; - u16_t options_idx; - u16_t options_idx_max; - struct pbuf *q; - int parse_file_as_options = 0; - int parse_sname_as_options = 0; - - /* clear received options */ - dhcp_clear_all_options(dhcp); - /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ - if (p->len < DHCP_SNAME_OFS) { - return ERR_BUF; - } - dhcp->msg_in = (struct dhcp_msg *)p->payload; -#if LWIP_DHCP_BOOTP_FILE - /* clear boot file name */ - dhcp->boot_file_name[0] = 0; -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* parse options */ - - /* start with options field */ - options_idx = DHCP_OPTIONS_OFS; - /* parse options to the end of the received packet */ - options_idx_max = p->tot_len; -again: - q = p; - while((q != NULL) && (options_idx >= q->len)) { - options_idx -= q->len; - options_idx_max -= q->len; - q = q->next; - } - if (q == NULL) { - return ERR_BUF; - } - offset = options_idx; - offset_max = options_idx_max; - options = (u8_t*)q->payload; - /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ - while((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) { - u8_t op = options[offset]; - u8_t len; - u8_t decode_len = 0; - int decode_idx = -1; - u16_t val_offset = offset + 2; - /* len byte might be in the next pbuf */ - if (offset + 1 < q->len) { - len = options[offset + 1]; - } else { - len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0); - } - /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ - decode_len = len; - switch(op) { - /* case(DHCP_OPTION_END): handled above */ - case(DHCP_OPTION_PAD): - /* special option: no len encoded */ - decode_len = len = 0; - /* will be increased below */ - offset--; - break; - case(DHCP_OPTION_SUBNET_MASK): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; - break; - case(DHCP_OPTION_ROUTER): - decode_len = 4; /* only copy the first given router */ - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_ROUTER; - break; - case(DHCP_OPTION_DNS_SERVER): - /* special case: there might be more than one server */ - LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;); - /* limit number of DNS servers */ - decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_DNS_SERVER; - break; - case(DHCP_OPTION_LEASE_TIME): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_LEASE_TIME; - break; - case(DHCP_OPTION_OVERLOAD): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_OVERLOAD; - break; - case(DHCP_OPTION_MESSAGE_TYPE): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_MSG_TYPE; - break; - case(DHCP_OPTION_SERVER_ID): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SERVER_ID; - break; - case(DHCP_OPTION_T1): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T1; - break; - case(DHCP_OPTION_T2): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T2; - break; - default: - decode_len = 0; - LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op)); - break; - } - offset += len + 2; - if (decode_len > 0) { - u32_t value = 0; - u16_t copy_len; -decode_next: - LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); - if (!dhcp_option_given(dhcp, decode_idx)) { - copy_len = LWIP_MIN(decode_len, 4); - pbuf_copy_partial(q, &value, copy_len, val_offset); - if (decode_len > 4) { - /* decode more than one u32_t */ - LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, htonl(value)); - decode_len -= 4; - val_offset += 4; - decode_idx++; - goto decode_next; - } else if (decode_len == 4) { - value = ntohl(value); - } else { - LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); - value = ((u8_t*)&value)[0]; - } - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, value); - } - } - if (offset >= q->len) { - offset -= q->len; - offset_max -= q->len; - if ((offset < offset_max) && offset_max) { - q = q->next; - LWIP_ASSERT("next pbuf was null", q); - options = (u8_t*)q->payload; - } else { - /* We've run out of bytes, probably no end marker. Don't proceed. */ - break; - } - } - } - /* is this an overloaded message? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { - u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); - dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); - if (overload == DHCP_OVERLOAD_FILE) { - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME) { - parse_sname_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { - parse_sname_as_options = 1; - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); - } -#if LWIP_DHCP_BOOTP_FILE - if (!parse_file_as_options) { - /* only do this for ACK messages */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && - (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) - /* copy bootp file name, don't care for sname (server hostname) */ - pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS); - /* make sure the string is really NULL-terminated */ - dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; - } -#endif /* LWIP_DHCP_BOOTP_FILE */ - } - if (parse_file_as_options) { - /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ - parse_file_as_options = 0; - options_idx = DHCP_FILE_OFS; - options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; - goto again; - } else if (parse_sname_as_options) { - parse_sname_as_options = 0; - options_idx = DHCP_SNAME_OFS; - options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; - goto again; - } - return ERR_OK; -} - -/** - * If an incoming DHCP message is in response to us, then trigger the state machine - */ -static void -dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - struct netif *netif = (struct netif *)arg; - struct dhcp *dhcp = netif->dhcp; - struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; - u8_t msg_type; - u8_t i; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, - ip4_addr1_16(addr), ip4_addr2_16(addr), ip4_addr3_16(addr), ip4_addr4_16(addr), port)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); - /* prevent warnings about unused arguments */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); - - if (p->len < DHCP_MIN_REPLY_LEN) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); - goto free_pbuf_and_return; - } - - if (reply_msg->op != DHCP_BOOTREPLY) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); - goto free_pbuf_and_return; - } - /* iterate through hardware address and match against DHCP message */ - for (i = 0; i < netif->hwaddr_len; i++) { - if (netif->hwaddr[i] != reply_msg->chaddr[i]) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", - (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); - goto free_pbuf_and_return; - } - } - /* match transaction ID against what we expected */ - if (ntohl(reply_msg->xid) != dhcp->xid) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid)); - goto free_pbuf_and_return; - } - /* option fields could be unfold? */ - if (dhcp_parse_reply(dhcp, p) != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("problem unfolding DHCP message - too short on memory?\n")); - goto free_pbuf_and_return; - } - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); - /* obtain pointer to DHCP message type */ - if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); - goto free_pbuf_and_return; - } - - /* read DHCP message type */ - msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); - /* message type is DHCP ACK? */ - if (msg_type == DHCP_ACK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); - /* in requesting state? */ - if (dhcp->state == DHCP_REQUESTING) { - dhcp_handle_ack(netif); -#if DHCP_DOES_ARP_CHECK - /* check if the acknowledged lease address is already in use */ - dhcp_check(netif); -#else - /* bind interface to the acknowledged lease address */ - dhcp_bind(netif); -#endif - } - /* already bound to the given lease address? */ - else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { - dhcp_bind(netif); - } - } - /* received a DHCP_NAK in appropriate state? */ - else if ((msg_type == DHCP_NAK) && - ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || - (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); - dhcp_handle_nak(netif); - } - /* received a DHCP_OFFER in DHCP_SELECTING state? */ - else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n")); - dhcp->request_timeout = 0; - /* remember offered lease */ - dhcp_handle_offer(netif); - } -free_pbuf_and_return: - dhcp->msg_in = NULL; - pbuf_free(p); -} - -/** - * Create a DHCP request, fill in common headers - * - * @param netif the netif under DHCP control - * @param dhcp dhcp control struct - * @param message_type message type of the request - */ -static err_t -dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) -{ - u16_t i; -#ifndef DHCP_GLOBAL_XID - /** default global transaction identifier starting value (easy to match - * with a packet analyser). We simply increment for each new request. - * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one - * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - static u32_t xid; -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - static u32_t xid = 0xABCD0000; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ -#else - if (!xid_initialised) { - xid = DHCP_GLOBAL_XID; - xid_initialised = !xid_initialised; - } -#endif - LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;); - LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); - LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL); - LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL); - dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); - if (dhcp->p_out == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_create_msg(): could not allocate pbuf\n")); - return ERR_MEM; - } - LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", - (dhcp->p_out->len >= sizeof(struct dhcp_msg))); - - /* reuse transaction identifier in retransmissions */ - if (dhcp->tries == 0) { -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - xid = LWIP_RAND(); -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - xid++; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - } - dhcp->xid = xid; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, - ("transaction id xid(%"X32_F")\n", xid)); - - dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; - - dhcp->msg_out->op = DHCP_BOOTREQUEST; - /* TODO: make link layer independent */ - dhcp->msg_out->htype = DHCP_HTYPE_ETH; - dhcp->msg_out->hlen = netif->hwaddr_len; - dhcp->msg_out->hops = 0; - dhcp->msg_out->xid = htonl(dhcp->xid); - dhcp->msg_out->secs = 0; - /* we don't need the broadcast flag since we can receive unicast traffic - before being fully configured! */ - dhcp->msg_out->flags = 0; - ip_addr_set_zero(&dhcp->msg_out->ciaddr); - /* set ciaddr to netif->ip_addr based on message_type and state */ - if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || - ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */ - ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) { - ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr); - } - ip_addr_set_zero(&dhcp->msg_out->yiaddr); - ip_addr_set_zero(&dhcp->msg_out->siaddr); - ip_addr_set_zero(&dhcp->msg_out->giaddr); - for (i = 0; i < DHCP_CHADDR_LEN; i++) { - /* copy netif hardware address, pad with zeroes */ - dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN) ? netif->hwaddr[i] : 0/* pad byte*/; - } - for (i = 0; i < DHCP_SNAME_LEN; i++) { - dhcp->msg_out->sname[i] = 0; - } - for (i = 0; i < DHCP_FILE_LEN; i++) { - dhcp->msg_out->file[i] = 0; - } - dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); - dhcp->options_out_len = 0; - /* fill options field with an incrementing array (for debugging purposes) */ - for (i = 0; i < DHCP_OPTIONS_LEN; i++) { - dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ - } - /* Add option MESSAGE_TYPE */ - dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); - dhcp_option_byte(dhcp, message_type); - return ERR_OK; -} - -/** - * Free previously allocated memory used to send a DHCP request. - * - * @param dhcp the dhcp struct to free the request from - */ -static void -dhcp_delete_msg(struct dhcp *dhcp) -{ - LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;); - LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL); - LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL); - if (dhcp->p_out != NULL) { - pbuf_free(dhcp->p_out); - } - dhcp->p_out = NULL; - dhcp->msg_out = NULL; -} - -/** - * Add a DHCP message trailer - * - * Adds the END option to the DHCP message, and if - * necessary, up to three padding bytes. - * - * @param dhcp DHCP state structure - */ -static void -dhcp_option_trailer(struct dhcp *dhcp) -{ - LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); - LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); - LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; - /* packet is too small, or not 4 byte aligned? */ - while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && - (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { - /* add a fill/padding byte */ - dhcp->msg_out->options[dhcp->options_out_len++] = 0; - } -} - -#endif /* LWIP_DHCP */ diff --git a/external/badvpn_dns/lwip/src/core/dns.c b/external/badvpn_dns/lwip/src/core/dns.c deleted file mode 100644 index 90821a6..0000000 --- a/external/badvpn_dns/lwip/src/core/dns.c +++ /dev/null @@ -1,988 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - * - */ - -/** - - * This file implements a DNS host name to IP address resolver. - - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - - * uIP version Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * DNS.C - * - * The lwIP DNS resolver functions are used to lookup a host name and - * map it to a numerical IP address. It maintains a list of resolved - * hostnames that can be queried with the dns_lookup() function. - * New hostnames can be resolved using the dns_query() function. - * - * The lwIP version of the resolver also adds a non-blocking version of - * gethostbyname() that will work with a raw API application. This function - * checks for an IP address string first and converts it if it is valid. - * gethostbyname() then does a dns_lookup() to see if the name is - * already in the table. If so, the IP is returned. If not, a query is - * issued and the function returns with a ERR_INPROGRESS status. The app - * using the dns client must then go into a waiting state. - * - * Once a hostname has been resolved (or found to be non-existent), - * the resolver code calls a specified callback function (which - * must be implemented by the module that uses the resolver). - */ - -/*----------------------------------------------------------------------------- - * RFC 1035 - Domain names - implementation and specification - * RFC 2181 - Clarifications to the DNS Specification - *----------------------------------------------------------------------------*/ - -/** @todo: define good default values (rfc compliance) */ -/** @todo: improve answer parsing, more checkings... */ -/** @todo: check RFC1035 - 7.3. Processing responses */ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/dns.h" - -#include <string.h> - -/** DNS server IP address */ -#ifndef DNS_SERVER_ADDRESS -#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */ -#endif - -/** DNS server port address */ -#ifndef DNS_SERVER_PORT -#define DNS_SERVER_PORT 53 -#endif - -/** DNS maximum number of retries when asking for a name, before "timeout". */ -#ifndef DNS_MAX_RETRIES -#define DNS_MAX_RETRIES 4 -#endif - -/** DNS resource record max. TTL (one week as default) */ -#ifndef DNS_MAX_TTL -#define DNS_MAX_TTL 604800 -#endif - -/* DNS protocol flags */ -#define DNS_FLAG1_RESPONSE 0x80 -#define DNS_FLAG1_OPCODE_STATUS 0x10 -#define DNS_FLAG1_OPCODE_INVERSE 0x08 -#define DNS_FLAG1_OPCODE_STANDARD 0x00 -#define DNS_FLAG1_AUTHORATIVE 0x04 -#define DNS_FLAG1_TRUNC 0x02 -#define DNS_FLAG1_RD 0x01 -#define DNS_FLAG2_RA 0x80 -#define DNS_FLAG2_ERR_MASK 0x0f -#define DNS_FLAG2_ERR_NONE 0x00 -#define DNS_FLAG2_ERR_NAME 0x03 - -/* DNS protocol states */ -#define DNS_STATE_UNUSED 0 -#define DNS_STATE_NEW 1 -#define DNS_STATE_ASKING 2 -#define DNS_STATE_DONE 3 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** DNS message header */ -struct dns_hdr { - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u8_t flags1); - PACK_STRUCT_FIELD(u8_t flags2); - PACK_STRUCT_FIELD(u16_t numquestions); - PACK_STRUCT_FIELD(u16_t numanswers); - PACK_STRUCT_FIELD(u16_t numauthrr); - PACK_STRUCT_FIELD(u16_t numextrarr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define SIZEOF_DNS_HDR 12 - -/** DNS query message structure. - No packing needed: only used locally on the stack. */ -struct dns_query { - /* DNS query record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; -}; -#define SIZEOF_DNS_QUERY 4 - -/** DNS answer message structure. - No packing needed: only used locally on the stack. */ -struct dns_answer { - /* DNS answer record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; - u32_t ttl; - u16_t len; -}; -#define SIZEOF_DNS_ANSWER 10 - -/** DNS table entry */ -struct dns_table_entry { - u8_t state; - u8_t numdns; - u8_t tmr; - u8_t retries; - u8_t seqno; - u8_t err; - u32_t ttl; - char name[DNS_MAX_NAME_LENGTH]; - ip_addr_t ipaddr; - /* pointer to callback on DNS query done */ - dns_found_callback found; - void *arg; -}; - -#if DNS_LOCAL_HOSTLIST - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Local host-list. For hostnames in this list, no - * external name resolution is performed */ -static struct local_hostlist_entry *local_hostlist_dynamic; -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE -#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST -#define DNS_LOCAL_HOSTLIST_STORAGE_POST -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ -DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] - DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; - -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -static void dns_init_local(); -#endif /* DNS_LOCAL_HOSTLIST */ - - -/* forward declarations */ -static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); -static void dns_check_entries(void); - -/*----------------------------------------------------------------------------- - * Globales - *----------------------------------------------------------------------------*/ - -/* DNS variables */ -static struct udp_pcb *dns_pcb; -static u8_t dns_seqno; -static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; -static ip_addr_t dns_servers[DNS_MAX_SERVERS]; -/** Contiguous buffer for processing responses */ -static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)]; -static u8_t* dns_payload; - -/** - * Initialize the resolver: set up the UDP pcb and configure the default server - * (DNS_SERVER_ADDRESS). - */ -void -dns_init() -{ - ip_addr_t dnsserver; - - dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer); - - /* initialize default DNS server address */ - DNS_SERVER_ADDRESS(&dnsserver); - - LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); - - /* if dns client not yet initialized... */ - if (dns_pcb == NULL) { - dns_pcb = udp_new(); - - if (dns_pcb != NULL) { - /* initialize DNS table not needed (initialized to zero since it is a - * global variable) */ - LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", - DNS_STATE_UNUSED == 0); - - /* initialize DNS client */ - udp_bind(dns_pcb, IP_ADDR_ANY, 0); - udp_recv(dns_pcb, dns_recv, NULL); - - /* initialize default DNS primary server */ - dns_setserver(0, &dnsserver); - } - } -#if DNS_LOCAL_HOSTLIST - dns_init_local(); -#endif -} - -/** - * Initialize one of the DNS servers. - * - * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS - * @param dnsserver IP address of the DNS server to set - */ -void -dns_setserver(u8_t numdns, ip_addr_t *dnsserver) -{ - if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) && - (dnsserver != NULL) && !ip_addr_isany(dnsserver)) { - dns_servers[numdns] = (*dnsserver); - } -} - -/** - * Obtain one of the currently configured DNS server. - * - * @param numdns the index of the DNS server - * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS - * server has not been configured. - */ -ip_addr_t -dns_getserver(u8_t numdns) -{ - if (numdns < DNS_MAX_SERVERS) { - return dns_servers[numdns]; - } else { - return *IP_ADDR_ANY; - } -} - -/** - * The DNS resolver client timer - handle retries and timeouts and should - * be called every DNS_TMR_INTERVAL milliseconds (every second by default). - */ -void -dns_tmr(void) -{ - if (dns_pcb != NULL) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); - dns_check_entries(); - } -} - -#if DNS_LOCAL_HOSTLIST -static void -dns_init_local() -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) - int i; - struct local_hostlist_entry *entry; - /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ - struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; - size_t namelen; - for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { - struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; - LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); - namelen = strlen(init_entry->name); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); - if (entry != NULL) { - entry->name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY((char*)entry->name, init_entry->name, namelen); - ((char*)entry->name)[namelen] = 0; - entry->addr = init_entry->addr; - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ -} - -/** - * Scans the local host-list for a hostname. - * - * @param hostname Hostname to look for in the local host-list - * @return The first IP address for the hostname in the local host-list or - * IPADDR_NONE if not found. - */ -static u32_t -dns_lookup_local(const char *hostname) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - while(entry != NULL) { - if(strcmp(entry->name, hostname) == 0) { - return ip4_addr_get_u32(&entry->addr); - } - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - int i; - for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { - if(strcmp(local_hostlist_static[i].name, hostname) == 0) { - return ip4_addr_get_u32(&local_hostlist_static[i].addr); - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return IPADDR_NONE; -} - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Remove all entries from the local host-list for a specific hostname - * and/or IP addess - * - * @param hostname hostname for which entries shall be removed from the local - * host-list - * @param addr address for which entries shall be removed from the local host-list - * @return the number of removed entries - */ -int -dns_local_removehost(const char *hostname, const ip_addr_t *addr) -{ - int removed = 0; - struct local_hostlist_entry *entry = local_hostlist_dynamic; - struct local_hostlist_entry *last_entry = NULL; - while (entry != NULL) { - if (((hostname == NULL) || !strcmp(entry->name, hostname)) && - ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { - struct local_hostlist_entry *free_entry; - if (last_entry != NULL) { - last_entry->next = entry->next; - } else { - local_hostlist_dynamic = entry->next; - } - free_entry = entry; - entry = entry->next; - memp_free(MEMP_LOCALHOSTLIST, free_entry); - removed++; - } else { - last_entry = entry; - entry = entry->next; - } - } - return removed; -} - -/** - * Add a hostname/IP address pair to the local host-list. - * Duplicates are not checked. - * - * @param hostname hostname of the new entry - * @param addr IP address of the new entry - * @return ERR_OK if succeeded or ERR_MEM on memory error - */ -err_t -dns_local_addhost(const char *hostname, const ip_addr_t *addr) -{ - struct local_hostlist_entry *entry; - size_t namelen; - LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); - namelen = strlen(hostname); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - if (entry == NULL) { - return ERR_MEM; - } - entry->name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY((char*)entry->name, hostname, namelen); - ((char*)entry->name)[namelen] = 0; - ip_addr_copy(entry->addr, *addr); - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - return ERR_OK; -} -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** - * Look up a hostname in the array of known hostnames. - * - * @note This function only looks in the internal array of known - * hostnames, it does not send out a query for the hostname if none - * was found. The function dns_enqueue() can be used to send a query - * for a hostname. - * - * @param name the hostname to look up - * @return the hostname's IP address, as u32_t (instead of ip_addr_t to - * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname - * was not found in the cached dns_table. - */ -static u32_t -dns_lookup(const char *name) -{ - u8_t i; -#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) - u32_t addr; -#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ -#if DNS_LOCAL_HOSTLIST - if ((addr = dns_lookup_local(name)) != IPADDR_NONE) { - return addr; - } -#endif /* DNS_LOCAL_HOSTLIST */ -#ifdef DNS_LOOKUP_LOCAL_EXTERN - if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { - return addr; - } -#endif /* DNS_LOOKUP_LOCAL_EXTERN */ - - /* Walk through name list, return entry if found. If not, return NULL. */ - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - if ((dns_table[i].state == DNS_STATE_DONE) && - (strcmp(name, dns_table[i].name) == 0)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: "%s": found = ", name)); - ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - return ip4_addr_get_u32(&dns_table[i].ipaddr); - } - } - - return IPADDR_NONE; -} - -#if DNS_DOES_NAME_CHECK -/** - * Compare the "dotted" name "query" with the encoded name "response" - * to make sure an answer from the DNS server matches the current dns_table - * entry (otherwise, answers might arrive late for hostname not on the list - * any more). - * - * @param query hostname (not encoded) from the dns_table - * @param response encoded hostname in the DNS response - * @return 0: names equal; 1: names differ - */ -static u8_t -dns_compare_name(unsigned char *query, unsigned char *response) -{ - unsigned char n; - - do { - n = *response++; - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name */ - break; - } else { - /* Not compressed name */ - while (n > 0) { - if ((*query) != (*response)) { - return 1; - } - ++response; - ++query; - --n; - }; - ++query; - } - } while (*response != 0); - - return 0; -} -#endif /* DNS_DOES_NAME_CHECK */ - -/** - * Walk through a compact encoded DNS name and return the end of the name. - * - * @param query encoded DNS name in the DNS server response - * @return end of the name - */ -static unsigned char * -dns_parse_name(unsigned char *query) -{ - unsigned char n; - - do { - n = *query++; - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name */ - break; - } else { - /* Not compressed name */ - while (n > 0) { - ++query; - --n; - }; - } - } while (*query != 0); - - return query + 1; -} - -/** - * Send a DNS query packet. - * - * @param numdns index of the DNS server in the dns_servers table - * @param name hostname to query - * @param id index of the hostname in dns_table, used as transaction ID in the - * DNS query packet - * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise - */ -static err_t -dns_send(u8_t numdns, const char* name, u8_t id) -{ - err_t err; - struct dns_hdr *hdr; - struct dns_query qry; - struct pbuf *p; - char *query, *nptr; - const char *pHostname; - u8_t n; - - LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] "%s": request\n", - (u16_t)(numdns), name)); - LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); - LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns])); - - /* if here, we have either a new query or a retry on a previous query to process */ - p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH + 1 + - SIZEOF_DNS_QUERY, PBUF_RAM); - if (p != NULL) { - u16_t realloc_size; - LWIP_ASSERT("pbuf must be in one piece", p->next == NULL); - /* fill dns header */ - hdr = (struct dns_hdr*)p->payload; - memset(hdr, 0, SIZEOF_DNS_HDR); - hdr->id = htons(id); - hdr->flags1 = DNS_FLAG1_RD; - hdr->numquestions = PP_HTONS(1); - query = (char*)hdr + SIZEOF_DNS_HDR; - pHostname = name; - --pHostname; - - /* convert hostname into suitable query format. */ - do { - ++pHostname; - nptr = query; - ++query; - for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) { - *query = *pHostname; - ++query; - ++n; - } - *nptr = n; - } while(*pHostname != 0); - *query++='\0'; - - /* fill dns query */ - qry.type = PP_HTONS(DNS_RRTYPE_A); - qry.cls = PP_HTONS(DNS_RRCLASS_IN); - SMEMCPY(query, &qry, SIZEOF_DNS_QUERY); - - /* resize pbuf to the exact dns query */ - realloc_size = (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload))); - LWIP_ASSERT("p->tot_len >= realloc_size", p->tot_len >= realloc_size); - pbuf_realloc(p, realloc_size); - - /* connect to the server for faster receiving */ - udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT); - /* send dns packet */ - err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT); - - /* free pbuf */ - pbuf_free(p); - } else { - err = ERR_MEM; - } - - return err; -} - -/** - * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. - * Check an entry in the dns_table: - * - send out query for new entries - * - retry old pending entries on timeout (also with different servers) - * - remove completed entries from the table if their TTL has expired - * - * @param i index of the dns_table entry to check - */ -static void -dns_check_entry(u8_t i) -{ - err_t err; - struct dns_table_entry *pEntry = &dns_table[i]; - - LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); - - switch(pEntry->state) { - - case DNS_STATE_NEW: { - /* initialize new entry */ - pEntry->state = DNS_STATE_ASKING; - pEntry->numdns = 0; - pEntry->tmr = 1; - pEntry->retries = 0; - - /* send DNS packet for this entry */ - err = dns_send(pEntry->numdns, pEntry->name, i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - break; - } - - case DNS_STATE_ASKING: { - if (--pEntry->tmr == 0) { - if (++pEntry->retries == DNS_MAX_RETRIES) { - if ((pEntry->numdns+1<DNS_MAX_SERVERS) && !ip_addr_isany(&dns_servers[pEntry->numdns+1])) { - /* change of server */ - pEntry->numdns++; - pEntry->tmr = 1; - pEntry->retries = 0; - break; - } else { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: "%s": timeout\n", pEntry->name)); - /* call specified callback function if provided */ - if (pEntry->found) - (*pEntry->found)(pEntry->name, NULL, pEntry->arg); - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - break; - } - } - - /* wait longer for the next retry */ - pEntry->tmr = pEntry->retries; - - /* send DNS packet for this entry */ - err = dns_send(pEntry->numdns, pEntry->name, i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - } - break; - } - - case DNS_STATE_DONE: { - /* if the time to live is nul */ - if ((pEntry->ttl == 0) || (--pEntry->ttl == 0)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: "%s": flush\n", pEntry->name)); - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - } - break; - } - case DNS_STATE_UNUSED: - /* nothing to do */ - break; - default: - LWIP_ASSERT("unknown dns_table entry state:", 0); - break; - } -} - -/** - * Call dns_check_entry for each entry in dns_table - check all entries. - */ -static void -dns_check_entries(void) -{ - u8_t i; - - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - dns_check_entry(i); - } -} - -/** - * Receive input function for DNS response packets arriving for the dns UDP pcb. - * - * @params see udp.h - */ -static void -dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - u16_t i; - char *pHostname; - struct dns_hdr *hdr; - struct dns_answer ans; - struct dns_table_entry *pEntry; - u16_t nquestions, nanswers; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - /* is the dns message too big ? */ - if (p->tot_len > DNS_MSG_SIZE) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); - /* free pbuf and return */ - goto memerr; - } - - /* is the dns message big enough ? */ - if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); - /* free pbuf and return */ - goto memerr; - } - - /* copy dns payload inside static buffer for processing */ - if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) { - /* The ID in the DNS header should be our entry into the name table. */ - hdr = (struct dns_hdr*)dns_payload; - i = htons(hdr->id); - if (i < DNS_TABLE_SIZE) { - pEntry = &dns_table[i]; - if(pEntry->state == DNS_STATE_ASKING) { - /* This entry is now completed. */ - pEntry->state = DNS_STATE_DONE; - pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; - - /* We only care about the question(s) and the answers. The authrr - and the extrarr are simply discarded. */ - nquestions = htons(hdr->numquestions); - nanswers = htons(hdr->numanswers); - - /* Check for error. If so, call callback to inform. */ - if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: "%s": error in flags\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } - -#if DNS_DOES_NAME_CHECK - /* Check if the name in the "question" part match with the name in the entry. */ - if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: "%s": response not match to query\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } -#endif /* DNS_DOES_NAME_CHECK */ - - /* Skip the name in the "question" part */ - pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY; - - while (nanswers > 0) { - /* skip answer resource record's host name */ - pHostname = (char *) dns_parse_name((unsigned char *)pHostname); - - /* Check for IP address type and Internet class. Others are discarded. */ - SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER); - if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && - (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) { - /* read the answer resource record's TTL, and maximize it if needed */ - pEntry->ttl = ntohl(ans.ttl); - if (pEntry->ttl > DNS_MAX_TTL) { - pEntry->ttl = DNS_MAX_TTL; - } - /* read the IP address after answer resource record's header */ - SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(ip_addr_t)); - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: "%s": response = ", pEntry->name)); - ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr))); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - /* call specified callback function if provided */ - if (pEntry->found) { - (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg); - } - if (pEntry->ttl == 0) { - /* RFC 883, page 29: "Zero values are - interpreted to mean that the RR can only be used for the - transaction in progress, and should not be cached." - -> flush this entry now */ - goto flushentry; - } - /* deallocate memory and return */ - goto memerr; - } else { - pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len); - } - --nanswers; - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: "%s": error in response\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } - } - } - - /* deallocate memory and return */ - goto memerr; - -responseerr: - /* ERROR: call specified callback function with NULL as name to indicate an error */ - if (pEntry->found) { - (*pEntry->found)(pEntry->name, NULL, pEntry->arg); - } -flushentry: - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - -memerr: - /* free pbuf */ - pbuf_free(p); - return; -} - -/** - * Queues a new hostname to resolve and sends out a DNS query for that hostname - * - * @param name the hostname that is to be queried - * @param hostnamelen length of the hostname - * @param found a callback founction to be called on success, failure or timeout - * @param callback_arg argument to pass to the callback function - * @return @return a err_t return code. - */ -static err_t -dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, - void *callback_arg) -{ - u8_t i; - u8_t lseq, lseqi; - struct dns_table_entry *pEntry = NULL; - size_t namelen; - - /* search an unused entry, or the oldest one */ - lseq = lseqi = 0; - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - pEntry = &dns_table[i]; - /* is it an unused entry ? */ - if (pEntry->state == DNS_STATE_UNUSED) - break; - - /* check if this is the oldest completed entry */ - if (pEntry->state == DNS_STATE_DONE) { - if ((dns_seqno - pEntry->seqno) > lseq) { - lseq = dns_seqno - pEntry->seqno; - lseqi = i; - } - } - } - - /* if we don't have found an unused entry, use the oldest completed one */ - if (i == DNS_TABLE_SIZE) { - if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { - /* no entry can't be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: "%s": DNS entries table is full\n", name)); - return ERR_MEM; - } else { - /* use the oldest completed one */ - i = lseqi; - pEntry = &dns_table[i]; - } - } - - /* use this entry */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: "%s": use DNS entry %"U16_F"\n", name, (u16_t)(i))); - - /* fill the entry */ - pEntry->state = DNS_STATE_NEW; - pEntry->seqno = dns_seqno++; - pEntry->found = found; - pEntry->arg = callback_arg; - namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH-1); - MEMCPY(pEntry->name, name, namelen); - pEntry->name[namelen] = 0; - - /* force to send query without waiting timer */ - dns_check_entry(i); - - /* dns query is enqueued */ - return ERR_INPROGRESS; -} - -/** - * Resolve a hostname (string) into an IP address. - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param addr pointer to a ip_addr_t where to store the address if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -err_t -dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, - void *callback_arg) -{ - u32_t ipaddr; - size_t hostnamelen; - /* not initialized or no valid server yet, or invalid addr pointer - * or invalid hostname or invalid hostname length */ - if ((dns_pcb == NULL) || (addr == NULL) || - (!hostname) || (!hostname[0])) { - return ERR_ARG; - } - hostnamelen = strlen(hostname); - if (hostnamelen >= DNS_MAX_NAME_LENGTH) { - return ERR_ARG; - } - - -#if LWIP_HAVE_LOOPIF - if (strcmp(hostname, "localhost")==0) { - ip_addr_set_loopback(addr); - return ERR_OK; - } -#endif /* LWIP_HAVE_LOOPIF */ - - /* host name already in octet notation? set ip addr and return ERR_OK */ - ipaddr = ipaddr_addr(hostname); - if (ipaddr == IPADDR_NONE) { - /* already have this address cached? */ - ipaddr = dns_lookup(hostname); - } - if (ipaddr != IPADDR_NONE) { - ip4_addr_set_u32(addr, ipaddr); - return ERR_OK; - } - - /* queue query with specified callback */ - return dns_enqueue(hostname, hostnamelen, found, callback_arg); -} - -#endif /* LWIP_DNS */ diff --git a/external/badvpn_dns/lwip/src/core/inet_chksum.c b/external/badvpn_dns/lwip/src/core/inet_chksum.c deleted file mode 100644 index 8bc42c1..0000000 --- a/external/badvpn_dns/lwip/src/core/inet_chksum.c +++ /dev/null @@ -1,545 +0,0 @@ -/** - * @file - * Incluse internet checksum functions. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/inet_chksum.h" -#include "lwip/def.h" - -#include <stddef.h> -#include <string.h> - -/* These are some reference implementations of the checksum algorithm, with the - * aim of being simple, correct and fully portable. Checksumming is the - * first thing you would want to optimize for your platform. If you create - * your own version, link it in and in your cc.h put: - * - * #define LWIP_CHKSUM <your_checksum_routine> - * - * Or you can select from the implementations below by defining - * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. - */ - -#ifndef LWIP_CHKSUM -# define LWIP_CHKSUM lwip_standard_chksum -# ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 2 -# endif -u16_t lwip_standard_chksum(void *dataptr, int len); -#endif -/* If none set: */ -#ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 0 -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ -/** - * lwip checksum - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * @note accumulator size limits summable length to 64k - * @note host endianess is irrelevant (p3 RFC1071) - */ -u16_t -lwip_standard_chksum(void *dataptr, u16_t len) -{ - u32_t acc; - u16_t src; - u8_t *octetptr; - - acc = 0; - /* dataptr may be at odd or even addresses */ - octetptr = (u8_t*)dataptr; - while (len > 1) { - /* declare first octet as most significant - thus assume network order, ignoring host order */ - src = (*octetptr) << 8; - octetptr++; - /* declare second octet as least significant */ - src |= (*octetptr); - octetptr++; - acc += src; - len -= 2; - } - if (len > 0) { - /* accumulate remaining octet */ - src = (*octetptr) << 8; - acc += src; - } - /* add deferred carry bits */ - acc = (acc >> 16) + (acc & 0x0000ffffUL); - if ((acc & 0xffff0000UL) != 0) { - acc = (acc >> 16) + (acc & 0x0000ffffUL); - } - /* This maybe a little confusing: reorder sum using htons() - instead of ntohs() since it has a little less call overhead. - The caller must invert bits for Internet sum ! */ - return htons((u16_t)acc); -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ -/* - * Curt McDowell - * Broadcom Corp. - * csm@broadcom.com - * - * IP checksum two bytes at a time with support for - * unaligned buffer. - * Works for len up to and including 0x20000. - * by Curt McDowell, Broadcom Corp. 12/08/2005 - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - */ - -u16_t -lwip_standard_chksum(void *dataptr, int len) -{ - u8_t *pb = (u8_t *)dataptr; - u16_t *ps, t = 0; - u32_t sum = 0; - int odd = ((mem_ptr_t)pb & 1); - - /* Get aligned to u16_t */ - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - /* Add the bulk of the data */ - ps = (u16_t *)(void *)pb; - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* Consume left-over byte, if any */ - if (len > 0) { - ((u8_t *)&t)[0] = *(u8_t *)ps; - } - - /* Add end bytes */ - sum += t; - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - /* Swap if alignment was odd */ - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ -/** - * An optimized checksum routine. Basically, it uses loop-unrolling on - * the checksum loop, treating the head and tail bytes specially, whereas - * the inner loop acts on 8 bytes at a time. - * - * @arg start of buffer to be checksummed. May be an odd byte address. - * @len number of bytes in the buffer to be checksummed. - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * by Curt McDowell, Broadcom Corp. December 8th, 2005 - */ - -u16_t -lwip_standard_chksum(void *dataptr, int len) -{ - u8_t *pb = (u8_t *)dataptr; - u16_t *ps, t = 0; - u32_t *pl; - u32_t sum = 0, tmp; - /* starts at odd byte address? */ - int odd = ((mem_ptr_t)pb & 1); - - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - ps = (u16_t *)pb; - - if (((mem_ptr_t)ps & 3) && len > 1) { - sum += *ps++; - len -= 2; - } - - pl = (u32_t *)ps; - - while (len > 7) { - tmp = sum + *pl++; /* ping */ - if (tmp < sum) { - tmp++; /* add back carry */ - } - - sum = tmp + *pl++; /* pong */ - if (sum < tmp) { - sum++; /* add back carry */ - } - - len -= 8; - } - - /* make room in upper bits */ - sum = FOLD_U32T(sum); - - ps = (u16_t *)pl; - - /* 16-bit aligned word remaining? */ - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* dangling tail byte remaining? */ - if (len > 0) { /* include odd byte */ - ((u8_t *)&t)[0] = *(u8_t *)ps; - } - - sum += t; /* add end bytes */ - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc) -{ - struct pbuf *q; - u8_t swapped = 0; - - /* iterate through all pbuf in chain */ - for(q = p; q != NULL; q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - acc += LWIP_CHKSUM(q->payload, q->len); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* just executing this next line is probably faster that the if statement needed - to check whether we really need to execute it, and does no harm */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)htons((u16_t)proto); - acc += (u32_t)htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -/* inet_chksum_pseudo: - * - * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip_addr_t *src, ip_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dst destination ipv6 address (used for checksum of pseudo header) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip6_addr_t *src, ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#endif /* LWIP_IPV6 */ - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, u32_t acc) -{ - struct pbuf *q; - u8_t swapped = 0; - u16_t chklen; - - /* iterate through all pbuf in chain */ - for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - chklen = q->len; - if (chklen > chksum_len) { - chklen = chksum_len; - } - acc += LWIP_CHKSUM(q->payload, chklen); - chksum_len -= chklen; - LWIP_ASSERT("delete me", chksum_len < 0x7fff); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* fold the upper bit down */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)htons((u16_t)proto); - acc += (u32_t)htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is propably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -/* inet_chksum_pseudo_partial: - * - * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} - -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. Will only compute for a - * portion of the payload. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dst destination ipv6 address (used for checksum of pseudo header) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param chksum_len number of payload bytes used to compute chksum - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} -#endif /* LWIP_IPV6 */ - -/* inet_chksum: - * - * Calculates the Internet checksum over a portion of memory. Used primarily for IP - * and ICMP. - * - * @param dataptr start of the buffer to calculate the checksum (no alignment needed) - * @param len length of the buffer to calculate the checksum - * @return checksum (as u16_t) to be saved directly in the protocol header - */ - -u16_t -inet_chksum(void *dataptr, u16_t len) -{ - return ~LWIP_CHKSUM(dataptr, len); -} - -/** - * Calculate a checksum over a chain of pbufs (without pseudo-header, much like - * inet_chksum only pbufs are used). - * - * @param p pbuf chain over that the checksum should be calculated - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pbuf(struct pbuf *p) -{ - u32_t acc; - struct pbuf *q; - u8_t swapped; - - acc = 0; - swapped = 0; - for(q = p; q != NULL; q = q->next) { - acc += LWIP_CHKSUM(q->payload, q->len); - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - return (u16_t)~(acc & 0xffffUL); -} - -/* These are some implementations for LWIP_CHKSUM_COPY, which copies data - * like MEMCPY but generates a checksum at the same time. Since this is a - * performance-sensitive function, you might want to create your own version - * in assembly targeted at your hardware by defining it in lwipopts.h: - * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) - */ - -#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ -/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. - * For architectures with big caches, data might still be in cache when - * generating the checksum after copying. - */ -u16_t -lwip_chksum_copy(void *dst, const void *src, u16_t len) -{ - MEMCPY(dst, src, len); - return LWIP_CHKSUM(dst, len); -} -#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/external/badvpn_dns/lwip/src/core/init.c b/external/badvpn_dns/lwip/src/core/init.c deleted file mode 100644 index c24c027..0000000 --- a/external/badvpn_dns/lwip/src/core/init.c +++ /dev/null @@ -1,345 +0,0 @@ -/** - * @file - * Modules initialization - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/init.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/sockets.h" -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp_impl.h" -#include "lwip/snmp_msg.h" -#include "lwip/autoip.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/timers.h" -#include "netif/etharp.h" -#include "lwip/ip6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/api.h" - -/* Compile-time sanity checks for configuration errors. - * These can be done independently of LWIP_DEBUG, without penalty. - */ -#ifndef BYTE_ORDER - #error "BYTE_ORDER is not defined, you have to define it in your cc.h" -#endif -#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) - #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_UDPLITE) - #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_SNMP) - #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DHCP) - #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_IGMP) - #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_SNMP) - #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DNS) - #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ -#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) - #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" -#endif -#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) - #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) - #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) - #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) - #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" -#endif -#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) - #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" -#endif -/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ -#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0))) - #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" -#endif -#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) - #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" -#endif -#endif /* !MEMP_MEM_MALLOC */ -#if (LWIP_TCP && (TCP_WND > 0xffff)) - #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) - #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) - #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" -#endif -#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) - #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" -#endif -#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) - #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" -#endif -#if (LWIP_NETIF_API && (NO_SYS==1)) - #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) - #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if (!LWIP_NETCONN && LWIP_SOCKET) - #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) - #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) - #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" -#endif -#if (!LWIP_ARP && LWIP_AUTOIP) - #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" -#endif -#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) - #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" -#endif -#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) - #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) - #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" -#endif -#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) - #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" -#endif -#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) - #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" -#endif -#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) - #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" -#endif -#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) - #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" -#endif -#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT - #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on" -#endif -#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) - #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" -#endif -#if (LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) - #error "When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value" -#endif -#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING - #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" -#endif -#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE - #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" -#endif -#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF - #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues" -#endif -#if LWIP_NETCONN && LWIP_TCP -#if NETCONN_COPY != TCP_WRITE_FLAG_COPY - #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" -#endif -#if NETCONN_MORE != TCP_WRITE_FLAG_MORE - #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" -#endif -#endif /* LWIP_NETCONN && LWIP_TCP */ -#if LWIP_SOCKET -/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ -#if SO_ACCEPTCONN != SOF_ACCEPTCONN - #error "SO_ACCEPTCONN != SOF_ACCEPTCONN" -#endif -#if SO_REUSEADDR != SOF_REUSEADDR - #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" -#endif -#if SO_KEEPALIVE != SOF_KEEPALIVE - #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" -#endif -#if SO_BROADCAST != SOF_BROADCAST - #error "WARNING: SO_BROADCAST != SOF_BROADCAST" -#endif -#if SO_LINGER != SOF_LINGER - #error "WARNING: SO_LINGER != SOF_LINGER" -#endif -#endif /* LWIP_SOCKET */ - - -/* Compile-time checks for deprecated options. - */ -#ifdef MEMP_NUM_TCPIP_MSG - #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef MEMP_NUM_API_MSG - #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef TCP_REXMIT_DEBUG - #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef RAW_STATS - #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_QUEUE_FIRST - #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_ALWAYS_INSERT - #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." -#endif - -#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS -#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 -#endif -#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS -#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 -#endif - -/* MEMP sanity checks */ -#if !LWIP_DISABLE_MEMP_SANITY_CHECKS -#if LWIP_NETCONN -#if MEMP_MEM_MALLOC -#if !MEMP_NUM_NETCONN && LWIP_SOCKET -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" -#endif -#else /* MEMP_MEM_MALLOC */ -#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* MEMP_MEM_MALLOC */ -#endif /* LWIP_NETCONN */ -#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ - -/* TCP sanity checks */ -#if !LWIP_DISABLE_TCP_SANITY_CHECKS -#if LWIP_TCP -#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) - #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_BUF < (2 * TCP_MSS) - #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) - #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDLOWAT >= TCP_SND_BUF - #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN - #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) - #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) - #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_WND < TCP_MSS - #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* LWIP_TCP */ -#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ - -/** - * Perform Sanity check of user-configurable values, and initialize all modules. - */ -void -lwip_init(void) -{ - /* Modules initialization */ - stats_init(); -#if !NO_SYS - sys_init(); -#endif /* !NO_SYS */ - mem_init(); - memp_init(); - pbuf_init(); - netif_init(); -#if LWIP_SOCKET - lwip_socket_init(); -#endif /* LWIP_SOCKET */ - ip_init(); -#if LWIP_ARP - etharp_init(); -#endif /* LWIP_ARP */ -#if LWIP_RAW - raw_init(); -#endif /* LWIP_RAW */ -#if LWIP_UDP - udp_init(); -#endif /* LWIP_UDP */ -#if LWIP_TCP - tcp_init(); -#endif /* LWIP_TCP */ -#if LWIP_SNMP - snmp_init(); -#endif /* LWIP_SNMP */ -#if LWIP_AUTOIP - autoip_init(); -#endif /* LWIP_AUTOIP */ -#if LWIP_IGMP - igmp_init(); -#endif /* LWIP_IGMP */ -#if LWIP_DNS - dns_init(); -#endif /* LWIP_DNS */ -#if LWIP_IPV6 - ip6_init(); - nd6_init(); -#if LWIP_IPV6_MLD - mld6_init(); -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6 */ - -#if LWIP_TIMERS - sys_timeouts_init(); -#endif /* LWIP_TIMERS */ -} diff --git a/external/badvpn_dns/lwip/src/core/ipv4/autoip.c b/external/badvpn_dns/lwip/src/core/ipv4/autoip.c deleted file mode 100644 index b122da2..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/autoip.c +++ /dev/null @@ -1,528 +0,0 @@ -/** - * @file - * AutoIP Automatic LinkLocal IP Configuration - * - */ - -/* - * - * Copyright (c) 2007 Dominik Spies kontakt@dspies.de - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies kontakt@dspies.de - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - * - * Please coordinate changes and requests with Dominik Spies - * kontakt@dspies.de - */ - -/******************************************************************************* - * USAGE: - * - * define LWIP_AUTOIP 1 in your lwipopts.h - * - * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): - * - First, call autoip_init(). - * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, - * that should be defined in autoip.h. - * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. - * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... - * - * Without DHCP: - * - Call autoip_start() after netif_add(). - * - * With DHCP: - * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. - * - Configure your DHCP Client. - * - */ - -#include "lwip/opt.h" - -#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/autoip.h" -#include "netif/etharp.h" - -#include <stdlib.h> -#include <string.h> - -/* 169.254.0.0 */ -#define AUTOIP_NET 0xA9FE0000 -/* 169.254.1.0 */ -#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) -/* 169.254.254.255 */ -#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) - - -/** Pseudo random macro based on netif informations. - * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ -#ifndef LWIP_AUTOIP_RAND -#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ - ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ - ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ - ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ - (netif->autoip?netif->autoip->tried_llipaddr:0)) -#endif /* LWIP_AUTOIP_RAND */ - -/** - * Macro that generates the initial IP address to be tried by AUTOIP. - * If you want to override this, define it to something else in lwipopts.h. - */ -#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR -#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ - htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ - ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) -#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ - -/* static functions */ -static void autoip_handle_arp_conflict(struct netif *netif); - -/* creates a pseudo random LL IP-Address for a network interface */ -static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr); - -/* sends an ARP probe */ -static err_t autoip_arp_probe(struct netif *netif); - -/* sends an ARP announce */ -static err_t autoip_arp_announce(struct netif *netif); - -/* configure interface for use with current LL IP-Address */ -static err_t autoip_bind(struct netif *netif); - -/* start sending probes for llipaddr */ -static void autoip_start_probing(struct netif *netif); - - -/** Set a statically allocated struct autoip to work with. - * Using this prevents autoip_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct autoip - * @param dhcp (uninitialised) dhcp struct allocated by the application - */ -void -autoip_set_struct(struct netif *netif, struct autoip *autoip) -{ - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("autoip != NULL", autoip != NULL); - LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL); - - /* clear data structure */ - memset(autoip, 0, sizeof(struct autoip)); - /* autoip->state = AUTOIP_STATE_OFF; */ - netif->autoip = autoip; -} - -/** Restart AutoIP client and check the next address (conflict detected) - * - * @param netif The netif under AutoIP control - */ -static void -autoip_restart(struct netif *netif) -{ - netif->autoip->tried_llipaddr++; - autoip_start(netif); -} - -/** - * Handle a IP address conflict after an ARP conflict detection - */ -static void -autoip_handle_arp_conflict(struct netif *netif) -{ - /* Somehow detect if we are defending or retreating */ - unsigned char defend = 1; /* tbd */ - - if (defend) { - if (netif->autoip->lastconflict > 0) { - /* retreat, there was a conflicting ARP in the last - * DEFEND_INTERVAL seconds - */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); - - /* TODO: close all TCP sessions */ - autoip_restart(netif); - } else { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); - autoip_arp_announce(netif); - netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } - } else { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); - /* TODO: close all TCP sessions */ - autoip_restart(netif); - } -} - -/** - * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * - * @param netif network interface on which create the IP-Address - * @param ipaddr ip address to initialize - */ -static void -autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr) -{ - /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * compliant to RFC 3927 Section 2.1 - * We have 254 * 256 possibilities */ - - u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); - addr += netif->autoip->tried_llipaddr; - addr = AUTOIP_NET | (addr & 0xffff); - /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ - - if (addr < AUTOIP_RANGE_START) { - addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - if (addr > AUTOIP_RANGE_END) { - addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && - (addr <= AUTOIP_RANGE_END)); - ip4_addr_set_u32(ipaddr, htonl(addr)); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), - ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); -} - -/** - * Sends an ARP probe from a network interface - * - * @param netif network interface used to send the probe - */ -static err_t -autoip_arp_probe(struct netif *netif) -{ - return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, - (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, - &netif->autoip->llipaddr, ARP_REQUEST); -} - -/** - * Sends an ARP announce from a network interface - * - * @param netif network interface used to send the announce - */ -static err_t -autoip_arp_announce(struct netif *netif) -{ - return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, - (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, - &netif->autoip->llipaddr, ARP_REQUEST); -} - -/** - * Configure interface for use with current LL IP-Address - * - * @param netif network interface to configure with current LL IP-Address - */ -static err_t -autoip_bind(struct netif *netif) -{ - struct autoip *autoip = netif->autoip; - ip_addr_t sn_mask, gw_addr; - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - - IP4_ADDR(&sn_mask, 255, 255, 0, 0); - IP4_ADDR(&gw_addr, 0, 0, 0, 0); - - netif_set_ipaddr(netif, &autoip->llipaddr); - netif_set_netmask(netif, &sn_mask); - netif_set_gw(netif, &gw_addr); - - /* bring the interface up */ - netif_set_up(netif); - - return ERR_OK; -} - -/** - * Start AutoIP client - * - * @param netif network interface on which start the AutoIP client - */ -err_t -autoip_start(struct netif *netif) -{ - struct autoip *autoip = netif->autoip; - err_t result = ERR_OK; - - if (netif_is_up(netif)) { - netif_set_down(netif); - } - - /* Set IP-Address, Netmask and Gateway to 0 to make sure that - * ARP Packets are formed correctly - */ - ip_addr_set_zero(&netif->ip_addr); - ip_addr_set_zero(&netif->netmask); - ip_addr_set_zero(&netif->gw); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], - netif->name[1], (u16_t)netif->num)); - if (autoip == NULL) { - /* no AutoIP client attached yet? */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): starting new AUTOIP client\n")); - autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); - if (autoip == NULL) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): could not allocate autoip\n")); - return ERR_MEM; - } - memset(autoip, 0, sizeof(struct autoip)); - /* store this AutoIP client in the netif */ - netif->autoip = autoip; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); - } else { - autoip->state = AUTOIP_STATE_OFF; - autoip->ttw = 0; - autoip->sent_num = 0; - ip_addr_set_zero(&autoip->llipaddr); - autoip->lastconflict = 0; - } - - autoip_create_addr(netif, &(autoip->llipaddr)); - autoip_start_probing(netif); - - return result; -} - -static void -autoip_start_probing(struct netif *netif) -{ - struct autoip *autoip = netif->autoip; - - autoip->state = AUTOIP_STATE_PROBING; - autoip->sent_num = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), - ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); - - /* time to wait to first probe, this is randomly - * choosen out of 0 to PROBE_WAIT seconds. - * compliant to RFC 3927 Section 2.2.1 - */ - autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); - - /* - * if we tried more then MAX_CONFLICTS we must limit our rate for - * accquiring and probing address - * compliant to RFC 3927 Section 2.2.1 - */ - if (autoip->tried_llipaddr > MAX_CONFLICTS) { - autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } -} - -/** - * Handle a possible change in the network configuration. - * - * If there is an AutoIP address configured, take the interface down - * and begin probing with the same address. - */ -void -autoip_network_changed(struct netif *netif) -{ - if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) { - netif_set_down(netif); - autoip_start_probing(netif); - } -} - -/** - * Stop AutoIP client - * - * @param netif network interface on which stop the AutoIP client - */ -err_t -autoip_stop(struct netif *netif) -{ - netif->autoip->state = AUTOIP_STATE_OFF; - netif_set_down(netif); - return ERR_OK; -} - -/** - * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds - */ -void -autoip_tmr() -{ - struct netif *netif = netif_list; - /* loop through netif's */ - while (netif != NULL) { - /* only act on AutoIP configured interfaces */ - if (netif->autoip != NULL) { - if (netif->autoip->lastconflict > 0) { - netif->autoip->lastconflict--; - } - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", - (u16_t)(netif->autoip->state), netif->autoip->ttw)); - - switch(netif->autoip->state) { - case AUTOIP_STATE_PROBING: - if (netif->autoip->ttw > 0) { - netif->autoip->ttw--; - } else { - if (netif->autoip->sent_num >= PROBE_NUM) { - netif->autoip->state = AUTOIP_STATE_ANNOUNCING; - netif->autoip->sent_num = 0; - netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), - ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); - } else { - autoip_arp_probe(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_tmr() PROBING Sent Probe\n")); - netif->autoip->sent_num++; - /* calculate time to wait to next probe */ - netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % - ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + - PROBE_MIN * AUTOIP_TICKS_PER_SECOND); - } - } - break; - - case AUTOIP_STATE_ANNOUNCING: - if (netif->autoip->ttw > 0) { - netif->autoip->ttw--; - } else { - if (netif->autoip->sent_num == 0) { - /* We are here the first time, so we waited ANNOUNCE_WAIT seconds - * Now we can bind to an IP address and use it. - * - * autoip_bind calls netif_set_up. This triggers a gratuitous ARP - * which counts as an announcement. - */ - autoip_bind(netif); - } else { - autoip_arp_announce(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_tmr() ANNOUNCING Sent Announce\n")); - } - netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; - netif->autoip->sent_num++; - - if (netif->autoip->sent_num >= ANNOUNCE_NUM) { - netif->autoip->state = AUTOIP_STATE_BOUND; - netif->autoip->sent_num = 0; - netif->autoip->ttw = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), - ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); - } - } - break; - } - } - /* proceed to next network interface */ - netif = netif->next; - } -} - -/** - * Handles every incoming ARP Packet, called by etharp_arp_input. - * - * @param netif network interface to use for autoip processing - * @param hdr Incoming ARP packet - */ -void -autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) -{ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); - if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) { - /* when ip.src == llipaddr && hw.src != netif->hwaddr - * - * when probing ip.dst == llipaddr && hw.src != netif->hwaddr - * we have a conflict and must solve it - */ - ip_addr_t sipaddr, dipaddr; - struct eth_addr netifaddr; - ETHADDR16_COPY(netifaddr.addr, netif->hwaddr); - - /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). - */ - IPADDR2_COPY(&sipaddr, &hdr->sipaddr); - IPADDR2_COPY(&dipaddr, &hdr->dipaddr); - - if ((netif->autoip->state == AUTOIP_STATE_PROBING) || - ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && - (netif->autoip->sent_num == 0))) { - /* RFC 3927 Section 2.2.1: - * from beginning to after ANNOUNCE_WAIT - * seconds we have a conflict if - * ip.src == llipaddr OR - * ip.dst == llipaddr && hw.src != own hwaddr - */ - if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) || - (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Probe Conflict detected\n")); - autoip_restart(netif); - } - } else { - /* RFC 3927 Section 2.5: - * in any state we have a conflict if - * ip.src == llipaddr && hw.src != own hwaddr - */ - if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); - autoip_handle_arp_conflict(netif); - } - } - } -} - -#endif /* LWIP_AUTOIP */ diff --git a/external/badvpn_dns/lwip/src/core/ipv4/icmp.c b/external/badvpn_dns/lwip/src/core/ipv4/icmp.c deleted file mode 100644 index af47153..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/icmp.c +++ /dev/null @@ -1,338 +0,0 @@ -/** - * @file - * ICMP - Internet Control Message Protocol - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -/* Some ICMP messages should be passed to the transport protocols. This - is not implemented. */ - -#include "lwip/opt.h" - -#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" - -#include <string.h> - -/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be - * used to modify and send a response packet (and to 1 if this is not the case, - * e.g. when link header is stripped of when receiving) */ -#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN -#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - -/* The amount of data from the original packet to return in a dest-unreachable */ -#define ICMP_DEST_UNREACH_DATASIZE 8 - -static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); - -/** - * Processes ICMP input packets, called from ip_input(). - * - * Currently only processes icmp echo requests and sends - * out the echo response. - * - * @param p the icmp echo request packet, p->payload pointing to the icmp header - * @param inp the netif on which this packet was received - */ -void -icmp_input(struct pbuf *p, struct netif *inp) -{ - u8_t type; -#ifdef LWIP_DEBUG - u8_t code; -#endif /* LWIP_DEBUG */ - struct icmp_echo_hdr *iecho; - struct ip_hdr *iphdr; - s16_t hlen; - - ICMP_STATS_INC(icmp.recv); - snmp_inc_icmpinmsgs(); - - iphdr = (struct ip_hdr *)ip_current_header(); - hlen = IPH_HL(iphdr) * 4; - if (p->len < sizeof(u16_t)*2) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); - goto lenerr; - } - - type = *((u8_t *)p->payload); -#ifdef LWIP_DEBUG - code = *(((u8_t *)p->payload)+1); -#endif /* LWIP_DEBUG */ - switch (type) { - case ICMP_ER: - /* This is OK, echo reply might have been parsed by a raw PCB - (as obviously, an echo request has been sent, too). */ - break; - case ICMP_ECHO: -#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING - { - int accepted = 1; -#if !LWIP_MULTICAST_PING - /* multicast destination address? */ - if (ip_addr_ismulticast(ip_current_dest_addr())) { - accepted = 0; - } -#endif /* LWIP_MULTICAST_PING */ -#if !LWIP_BROADCAST_PING - /* broadcast destination address? */ - if (ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { - accepted = 0; - } -#endif /* LWIP_BROADCAST_PING */ - /* broadcast or multicast destination address not acceptd? */ - if (!accepted) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); - ICMP_STATS_INC(icmp.err); - pbuf_free(p); - return; - } - } -#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); - if (p->tot_len < sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); - goto lenerr; - } - if (inet_chksum_pbuf(p) != 0) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); - pbuf_free(p); - ICMP_STATS_INC(icmp.chkerr); - snmp_inc_icmpinerrors(); - return; - } -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { - /* p is not big enough to contain link headers - * allocate a new one and copy p into it - */ - struct pbuf *r; - /* switch p->payload to ip header */ - if (pbuf_header(p, hlen)) { - LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); - goto memerr; - } - /* allocate new packet buffer with space for link headers */ - r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (r == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); - goto memerr; - } - LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", - (r->len >= hlen + sizeof(struct icmp_echo_hdr))); - /* copy the whole packet including ip header */ - if (pbuf_copy(r, p) != ERR_OK) { - LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); - goto memerr; - } - iphdr = (struct ip_hdr *)r->payload; - /* switch r->payload back to icmp header */ - if (pbuf_header(r, -hlen)) { - LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); - goto memerr; - } - /* free the original p */ - pbuf_free(p); - /* we now have an identical copy of p that has room for link headers */ - p = r; - } else { - /* restore p->payload to point to icmp header */ - if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { - LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); - goto memerr; - } - } -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - /* At this point, all checks are OK. */ - /* We generate an answer by switching the dest and src ip addresses, - * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ - iecho = (struct icmp_echo_hdr *)p->payload; - ip_addr_copy(iphdr->src, *ip_current_dest_addr()); - ip_addr_copy(iphdr->dest, *ip_current_src_addr()); - ICMPH_TYPE_SET(iecho, ICMP_ER); -#if CHECKSUM_GEN_ICMP - /* adjust the checksum */ - if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { - iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; - } else { - iecho->chksum += PP_HTONS(ICMP_ECHO << 8); - } -#else /* CHECKSUM_GEN_ICMP */ - iecho->chksum = 0; -#endif /* CHECKSUM_GEN_ICMP */ - - /* Set the correct TTL and recalculate the header checksum. */ - IPH_TTL_SET(iphdr, ICMP_TTL); - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); -#endif /* CHECKSUM_GEN_IP */ - - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - snmp_inc_icmpoutmsgs(); - /* increase number of echo replies attempted to send */ - snmp_inc_icmpoutechoreps(); - - if(pbuf_header(p, hlen)) { - LWIP_ASSERT("Can't move over header in packet", 0); - } else { - err_t ret; - /* send an ICMP packet, src addr is the dest addr of the curren packet */ - ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, - ICMP_TTL, 0, IP_PROTO_ICMP, inp); - if (ret != ERR_OK) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); - } - } - break; - default: - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", - (s16_t)type, (s16_t)code)); - ICMP_STATS_INC(icmp.proterr); - ICMP_STATS_INC(icmp.drop); - } - pbuf_free(p); - return; -lenerr: - pbuf_free(p); - ICMP_STATS_INC(icmp.lenerr); - snmp_inc_icmpinerrors(); - return; -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN -memerr: - pbuf_free(p); - ICMP_STATS_INC(icmp.err); - snmp_inc_icmpinerrors(); - return; -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ -} - -/** - * Send an icmp 'destination unreachable' packet, called from ip_input() if - * the transport layer protocol is unknown and from udp_input() if the local - * port is not bound. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'unreachable' packet - */ -void -icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) -{ - icmp_send_response(p, ICMP_DUR, t); -} - -#if IP_FORWARD || IP_REASSEMBLY -/** - * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. - * - * @param p the input packet for which the 'time exceeded' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'time exceeded' packet - */ -void -icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) -{ - icmp_send_response(p, ICMP_TE, t); -} - -#endif /* IP_FORWARD || IP_REASSEMBLY */ - -/** - * Send an icmp packet in response to an incoming packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param type Type of the ICMP header - * @param code Code of the ICMP header - */ -static void -icmp_send_response(struct pbuf *p, u8_t type, u8_t code) -{ - struct pbuf *q; - struct ip_hdr *iphdr; - /* we can use the echo header here */ - struct icmp_echo_hdr *icmphdr; - ip_addr_t iphdr_src; - - /* ICMP header + IP header + 8 bytes of data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp message", - (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); - - iphdr = (struct ip_hdr *)p->payload; - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); - ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); - LWIP_DEBUGF(ICMP_DEBUG, (" to ")); - ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); - LWIP_DEBUGF(ICMP_DEBUG, ("\n")); - - icmphdr = (struct icmp_echo_hdr *)q->payload; - icmphdr->type = type; - icmphdr->code = code; - icmphdr->id = 0; - icmphdr->seqno = 0; - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, - IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); - - /* calculate checksum */ - icmphdr->chksum = 0; - icmphdr->chksum = inet_chksum(icmphdr, q->len); - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - snmp_inc_icmpoutmsgs(); - /* increase number of destination unreachable messages attempted to send */ - snmp_inc_icmpouttimeexcds(); - ip_addr_copy(iphdr_src, iphdr->src); - ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); - pbuf_free(q); -} - -#endif /* LWIP_ICMP */ diff --git a/external/badvpn_dns/lwip/src/core/ipv4/igmp.c b/external/badvpn_dns/lwip/src/core/ipv4/igmp.c deleted file mode 100644 index bd52744..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/igmp.c +++ /dev/null @@ -1,805 +0,0 @@ -/** - * @file - * IGMP - Internet Group Management Protocol - * - */ - -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -/*------------------------------------------------------------- -Note 1) -Although the rfc requires V1 AND V2 capability -we will only support v2 since now V1 is very old (August 1989) -V1 can be added if required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 2) -A query for a specific group address (as opposed to ALLHOSTS) -has now been implemented as I am unsure if it is required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 3) -The router alert rfc 2113 is implemented in outgoing packets -but not checked rigorously incoming -------------------------------------------------------------- -Steve Reynolds -------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * RFC 988 - Host extensions for IP multicasting - V0 - * RFC 1054 - Host extensions for IP multicasting - - * RFC 1112 - Host extensions for IP multicasting - V1 - * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) - * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 - * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ - * RFC 2113 - IP Router Alert Option - - *----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/igmp.h" -#include "lwip/debug.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/stats.h" - -#include "string.h" - -/* - * IGMP constants - */ -#define IGMP_TTL 1 -#define IGMP_MINLEN 8 -#define ROUTER_ALERT 0x9404U -#define ROUTER_ALERTLEN 4 - -/* - * IGMP message types, including version number. - */ -#define IGMP_MEMB_QUERY 0x11 /* Membership query */ -#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ -#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ -#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ - -/* Group membership states */ -#define IGMP_GROUP_NON_MEMBER 0 -#define IGMP_GROUP_DELAYING_MEMBER 1 -#define IGMP_GROUP_IDLE_MEMBER 2 - -/** - * IGMP packet format. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct igmp_msg { - PACK_STRUCT_FIELD(u8_t igmp_msgtype); - PACK_STRUCT_FIELD(u8_t igmp_maxresp); - PACK_STRUCT_FIELD(u16_t igmp_checksum); - PACK_STRUCT_FIELD(ip_addr_p_t igmp_group_address); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr); -static err_t igmp_remove_group(struct igmp_group *group); -static void igmp_timeout( struct igmp_group *group); -static void igmp_start_timer(struct igmp_group *group, u8_t max_time); -static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); -static err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif); -static void igmp_send(struct igmp_group *group, u8_t type); - - -static struct igmp_group* igmp_group_list; -static ip_addr_t allsystems; -static ip_addr_t allrouters; - - -/** - * Initialize the IGMP module - */ -void -igmp_init(void) -{ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); - - IP4_ADDR(&allsystems, 224, 0, 0, 1); - IP4_ADDR(&allrouters, 224, 0, 0, 2); -} - -#ifdef LWIP_DEBUG -/** - * Dump global IGMP groups list - */ -void -igmp_dump_group_list() -{ - struct igmp_group *group = igmp_group_list; - - while (group != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state))); - ip_addr_debug_print(IGMP_DEBUG, &group->group_address); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); - group = group->next; - } - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); -} -#else -#define igmp_dump_group_list() -#endif /* LWIP_DEBUG */ - -/** - * Start IGMP processing on interface - * - * @param netif network interface on which start IGMP processing - */ -err_t -igmp_start(struct netif *netif) -{ - struct igmp_group* group; - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif)); - - group = igmp_lookup_group(netif, &allsystems); - - if (group != NULL) { - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->use++; - - /* Allow the igmp messages at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); - ip_addr_debug_print(IGMP_DEBUG, &allsystems); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); - netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER); - } - - return ERR_OK; - } - - return ERR_MEM; -} - -/** - * Stop IGMP processing on interface - * - * @param netif network interface on which stop IGMP processing - */ -err_t -igmp_stop(struct netif *netif) -{ - struct igmp_group *group = igmp_group_list; - struct igmp_group *prev = NULL; - struct igmp_group *next; - - /* look for groups joined on this interface further down the list */ - while (group != NULL) { - next = group->next; - /* is it a group joined on this interface? */ - if (group->netif == netif) { - /* is it the first group of the list? */ - if (group == igmp_group_list) { - igmp_group_list = next; - } - /* is there a "previous" group defined? */ - if (prev != NULL) { - prev->next = next; - } - /* disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); - ip_addr_debug_print(IGMP_DEBUG, &group->group_address); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); - netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER); - } - /* free group */ - memp_free(MEMP_IGMP_GROUP, group); - } else { - /* change the "previous" */ - prev = group; - } - /* move to "next" */ - group = next; - } - return ERR_OK; -} - -/** - * Report IGMP memberships for this interface - * - * @param netif network interface on which report IGMP memberships - */ -void -igmp_report_groups(struct netif *netif) -{ - struct igmp_group *group = igmp_group_list; - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); - - while (group != NULL) { - if (group->netif == netif) { - igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - } - group = group->next; - } -} - -/** - * Search for a group in the global igmp_group_list - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search for - * @return a struct igmp_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct igmp_group * -igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr) -{ - struct igmp_group *group = igmp_group_list; - - while (group != NULL) { - if ((group->netif == ifp) && (ip_addr_cmp(&(group->group_address), addr))) { - return group; - } - group = group->next; - } - - /* to be clearer, we return NULL here instead of - * 'group' (which is also NULL at this point). - */ - return NULL; -} - -/** - * Search for a specific igmp group and create a new one if not found- - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search - * @return a struct igmp_group*, - * NULL on memory error. - */ -struct igmp_group * -igmp_lookup_group(struct netif *ifp, ip_addr_t *addr) -{ - struct igmp_group *group = igmp_group_list; - - /* Search if the group already exists */ - group = igmp_lookfor_group(ifp, addr); - if (group != NULL) { - /* Group already exists. */ - return group; - } - - /* Group doesn't exist yet, create a new one */ - group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); - if (group != NULL) { - group->netif = ifp; - ip_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = IGMP_GROUP_NON_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - group->next = igmp_group_list; - - igmp_group_list = group; - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); - ip_addr_debug_print(IGMP_DEBUG, addr); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp)); - - return group; -} - -/** - * Remove a group in the global igmp_group_list - * - * @param group the group to remove from the global igmp_group_list - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -igmp_remove_group(struct igmp_group *group) -{ - err_t err = ERR_OK; - - /* Is it the first group? */ - if (igmp_group_list == group) { - igmp_group_list = group->next; - } else { - /* look for group further down the list */ - struct igmp_group *tmpGroup; - for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { - if (tmpGroup->next == group) { - tmpGroup->next = group->next; - break; - } - } - /* Group not found in the global igmp_group_list */ - if (tmpGroup == NULL) - err = ERR_ARG; - } - /* free group */ - memp_free(MEMP_IGMP_GROUP, group); - - return err; -} - -/** - * Called from ip_input() if a new IGMP packet is received. - * - * @param p received igmp packet, p->payload pointing to the igmp header - * @param inp network interface on which the packet was received - * @param dest destination ip address of the igmp packet - */ -void -igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest) -{ - struct igmp_msg* igmp; - struct igmp_group* group; - struct igmp_group* groupref; - - IGMP_STATS_INC(igmp.recv); - - /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ - if (p->len < IGMP_MINLEN) { - pbuf_free(p); - IGMP_STATS_INC(igmp.lenerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); - return; - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); - ip_addr_debug_print(IGMP_DEBUG, &(ip_current_header()->src)); - LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); - ip_addr_debug_print(IGMP_DEBUG, &(ip_current_header()->dest)); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp)); - - /* Now calculate and check the checksum */ - igmp = (struct igmp_msg *)p->payload; - if (inet_chksum(igmp, p->len)) { - pbuf_free(p); - IGMP_STATS_INC(igmp.chkerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); - return; - } - - /* Packet is ok so find an existing group */ - group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ - - /* If group can be found or create... */ - if (!group) { - pbuf_free(p); - IGMP_STATS_INC(igmp.drop); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); - return; - } - - /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ - switch (igmp->igmp_msgtype) { - case IGMP_MEMB_QUERY: { - /* IGMP_MEMB_QUERY to the "all systems" address ? */ - if ((ip_addr_cmp(dest, &allsystems)) && ip_addr_isany(&igmp->igmp_group_address)) { - /* THIS IS THE GENERAL QUERY */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on "ALL SYSTEMS" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - - if (igmp->igmp_maxresp == 0) { - IGMP_STATS_INC(igmp.rx_v1); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); - igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; - } else { - IGMP_STATS_INC(igmp.rx_general); - } - - groupref = igmp_group_list; - while (groupref) { - /* Do not send messages on the all systems group address! */ - if ((groupref->netif == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) { - igmp_delaying_member(groupref, igmp->igmp_maxresp); - } - groupref = groupref->next; - } - } else { - /* IGMP_MEMB_QUERY to a specific group ? */ - if (!ip_addr_isany(&igmp->igmp_group_address)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); - ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address); - if (ip_addr_cmp(dest, &allsystems)) { - ip_addr_t groupaddr; - LWIP_DEBUGF(IGMP_DEBUG, (" using "ALL SYSTEMS" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - /* we first need to re-look for the group since we used dest last time */ - ip_addr_copy(groupaddr, igmp->igmp_group_address); - group = igmp_lookfor_group(inp, &groupaddr); - } else { - LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - } - - if (group != NULL) { - IGMP_STATS_INC(igmp.rx_group); - igmp_delaying_member(group, igmp->igmp_maxresp); - } else { - IGMP_STATS_INC(igmp.drop); - } - } else { - IGMP_STATS_INC(igmp.proterr); - } - } - break; - } - case IGMP_V2_MEMB_REPORT: { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); - IGMP_STATS_INC(igmp.rx_report); - if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { - /* This is on a specific group we have already looked up */ - group->timer = 0; /* stopped */ - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - break; - } - default: { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", - igmp->igmp_msgtype, group->group_state, &group, group->netif)); - IGMP_STATS_INC(igmp.proterr); - break; - } - } - - pbuf_free(p); - return; -} - -/** - * Join a group on one network interface. - * - * @param ifaddr ip address of the network interface which should join a new group - * @param groupaddr the ip address of the group which to join - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct igmp_group *group; - struct netif *netif; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we join this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { - /* find group or create a new one if not found */ - group = igmp_lookup_group(netif, groupaddr); - - if (group != NULL) { - /* This should create a new group, check the state to make sure */ - if (group->group_state != IGMP_GROUP_NON_MEMBER) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n")); - } else { - /* OK - it was new group */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); - ip_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If first use of the group, allow the group at the MAC level */ - if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD ")); - ip_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); - netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER); - } - - IGMP_STATS_INC(igmp.tx_join); - igmp_send(group, IGMP_V2_MEMB_REPORT); - - igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - - /* Need to work out where this timer comes from */ - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } - /* Increment group use */ - group->use++; - /* Join on this interface */ - err = ERR_OK; - } else { - /* Return an error even if some network interfaces are joined */ - /** @todo undo any other netif already joined */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n")); - return ERR_MEM; - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * Leave a group on one network interface. - * - * @param ifaddr ip address of the network interface which should leave a group - * @param groupaddr the ip address of the group which to leave - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct igmp_group *group; - struct netif *netif; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we leave this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { - /* find group */ - group = igmp_lookfor_group(netif, groupaddr); - - if (group != NULL) { - /* Only send a leave if the flag is set according to the state diagram */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: ")); - ip_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If there is no other use of the group */ - if (group->use <= 1) { - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n")); - IGMP_STATS_INC(igmp.tx_leave); - igmp_send(group, IGMP_LEAVE_GROUP); - } - - /* Disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL ")); - ip_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); - netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER); - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: ")); - ip_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* Free the group */ - igmp_remove_group(group); - } else { - /* Decrement group use */ - group->use--; - } - /* Leave on this interface */ - err = ERR_OK; - } else { - /* It's not a fatal error on "leavegroup" */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n")); - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * The igmp timer function (both for NO_SYS=1 and =0) - * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). - */ -void -igmp_tmr(void) -{ - struct igmp_group *group = igmp_group_list; - - while (group != NULL) { - if (group->timer > 0) { - group->timer--; - if (group->timer == 0) { - igmp_timeout(group); - } - } - group = group->next; - } -} - -/** - * Called if a timeout for one group is reached. - * Sends a report for this group. - * - * @param group an igmp_group for which a timeout is reached - */ -static void -igmp_timeout(struct igmp_group *group) -{ - /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */ - if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); - ip_addr_debug_print(IGMP_DEBUG, &(group->group_address)); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); - - IGMP_STATS_INC(igmp.tx_report); - igmp_send(group, IGMP_V2_MEMB_REPORT); - } -} - -/** - * Start a timer for an igmp group - * - * @param group the igmp_group for which to start a timer - * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with - * every call to igmp_tmr()) - */ -static void -igmp_start_timer(struct igmp_group *group, u8_t max_time) -{ - /* ensure the input value is > 0 */ - if (max_time == 0) { - max_time = 1; - } -#ifdef LWIP_RAND - /* ensure the random value is > 0 */ - group->timer = (LWIP_RAND() % (max_time - 1)) + 1; -#endif /* LWIP_RAND */ -} - -/** - * Delaying membership report for a group if necessary - * - * @param group the igmp_group for which "delaying" membership report - * @param maxresp query delay - */ -static void -igmp_delaying_member(struct igmp_group *group, u8_t maxresp) -{ - if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || - ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && - ((group->timer == 0) || (maxresp < group->timer)))) { - igmp_start_timer(group, maxresp); - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } -} - - -/** - * Sends an IP packet on a network interface. This function constructs the IP header - * and calculates the IP header checksum. If the source IP address is NULL, - * the IP address of the outgoing network interface is filled in as source address. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an IP - header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - */ -static err_t -igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif) -{ - /* This is the "router alert" option */ - u16_t ra[2]; - ra[0] = PP_HTONS(ROUTER_ALERT); - ra[1] = 0x0000; /* Router shall examine packet */ - IGMP_STATS_INC(igmp.xmit); - return ip_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); -} - -/** - * Send an igmp packet to a specific group. - * - * @param group the group to which to send the packet - * @param type the type of igmp packet to send - */ -static void -igmp_send(struct igmp_group *group, u8_t type) -{ - struct pbuf* p = NULL; - struct igmp_msg* igmp = NULL; - ip_addr_t src = *IP_ADDR_ANY; - ip_addr_t* dest = NULL; - - /* IP header + "router alert" option + IGMP header */ - p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); - - if (p) { - igmp = (struct igmp_msg *)p->payload; - LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", - (p->len >= sizeof(struct igmp_msg))); - ip_addr_copy(src, group->netif->ip_addr); - - if (type == IGMP_V2_MEMB_REPORT) { - dest = &(group->group_address); - ip_addr_copy(igmp->igmp_group_address, group->group_address); - group->last_reporter_flag = 1; /* Remember we were the last to report */ - } else { - if (type == IGMP_LEAVE_GROUP) { - dest = &allrouters; - ip_addr_copy(igmp->igmp_group_address, group->group_address); - } - } - - if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { - igmp->igmp_msgtype = type; - igmp->igmp_maxresp = 0; - igmp->igmp_checksum = 0; - igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); - - igmp_ip_output_if(p, &src, dest, group->netif); - } - - pbuf_free(p); - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); - IGMP_STATS_INC(igmp.memerr); - } -} - -#endif /* LWIP_IGMP */ diff --git a/external/badvpn_dns/lwip/src/core/ipv4/ip4.c b/external/badvpn_dns/lwip/src/core/ipv4/ip4.c deleted file mode 100644 index 1acc255..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/ip4.c +++ /dev/null @@ -1,924 +0,0 @@ -/** - * @file - * This is the IPv4 layer implementation for incoming and outgoing IP traffic. - * - * @see ip_frag.c - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip_frag.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/igmp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp_impl.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/stats.h" -#include "arch/perf.h" - -#include <string.h> - -/** Set this to 0 in the rare case of wanting to call an extra function to - * generate the IP checksum (in contrast to calculating it on-the-fly). */ -#ifndef LWIP_INLINE_IP_CHKSUM -#define LWIP_INLINE_IP_CHKSUM 1 -#endif -#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP -#define CHECKSUM_GEN_IP_INLINE 1 -#else -#define CHECKSUM_GEN_IP_INLINE 0 -#endif - -#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 - -/** Some defines for DHCP to let link-layer-addressed packets through while the - * netif is down. - * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT - * to return 1 if the port is accepted and 0 if the port is not accepted. - */ -#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) -/* accept DHCP client port and custom port */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ - || (LWIP_IP_ACCEPT_UDP_PORT(port))) -#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept custom port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) -#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept DHCP client port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) -#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ - -#else /* LWIP_DHCP */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 -#endif /* LWIP_DHCP */ - -/** Global data for both IPv4 and IPv6 */ -struct ip_globals ip_data; - -/** The IP header ID of the next outgoing IP packet */ -static u16_t ip_id; - -/** - * Finds the appropriate network interface for a given IP address. It - * searches the list of network interfaces linearly. A match is found - * if the masked IP address of the network interface equals the masked - * IP address given to the function. - * - * @param dest the destination IP address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip_route(ip_addr_t *dest) -{ - struct netif *netif; - -#ifdef LWIP_HOOK_IP4_ROUTE - netif = LWIP_HOOK_IP4_ROUTE(dest); - if (netif != NULL) { - return netif; - } -#endif - - /* iterate through netifs */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - /* network mask matches? */ - if (netif_is_up(netif)) { - if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { - /* return netif on which to forward IP packet */ - return netif; - } - } - } - if ((netif_default == NULL) || (!netif_is_up(netif_default))) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - snmp_inc_ipoutnoroutes(); - return NULL; - } - /* no matching netif found, use default netif */ - return netif_default; -} - -#if IP_FORWARD -/** - * Determine whether an IP address is in a reserved set of addresses - * that may not be forwarded, or whether datagrams to that destination - * may be forwarded. - * @param p the packet to forward - * @param dest the destination IP address - * @return 1: can forward 0: discard - */ -static int -ip_canforward(struct pbuf *p) -{ - u32_t addr = htonl(ip4_addr_get_u32(ip_current_dest_addr())); - - if (p->flags & PBUF_FLAG_LLBCAST) { - /* don't route link-layer broadcasts */ - return 0; - } - if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { - /* don't route link-layer multicasts unless the destination address is an IP - multicast address */ - return 0; - } - if (IP_EXPERIMENTAL(addr)) { - return 0; - } - if (IP_CLASSA(addr)) { - u32_t net = addr & IP_CLASSA_NET; - if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { - /* don't route loopback packets */ - return 0; - } - } - return 1; -} - -/** - * Forwards an IP packet. It finds an appropriate route for the - * packet, decrements the TTL value of the packet, adjusts the - * checksum and outputs the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IP header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - PERF_START; - - if (!ip_canforward(p)) { - goto return_noroute; - } - - /* RFC3927 2.7: do not forward link-local addresses */ - if (ip_addr_islinklocal(ip_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), - ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); - goto return_noroute; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip_route(ip_current_dest_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", - ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), - ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); - /* @todo: send ICMP_DUR_NET? */ - goto return_noroute; - } -#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); - goto return_noroute; - } -#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ - - /* decrement TTL */ - IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); - /* send ICMP if TTL == 0 */ - if (IPH_TTL(iphdr) == 0) { - snmp_inc_ipinhdrerrors(); -#if LWIP_ICMP - /* Don't send ICMP messages in response to ICMP messages */ - if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { - icmp_time_exceeded(p, ICMP_TE_TTL); - } -#endif /* LWIP_ICMP */ - return; - } - - /* Incrementally update the IP checksum. */ - if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { - IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); - } else { - IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); - } - - LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), - ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); - - IP_STATS_INC(ip.fw); - IP_STATS_INC(ip.xmit); - snmp_inc_ipforwdatagrams(); - - PERF_STOP("ip_forward"); - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { -#if IP_FRAG - ip_frag(p, netif, ip_current_dest_addr()); -#else /* IP_FRAG */ - /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ -#endif /* IP_FRAG */ - } else { - /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ - icmp_dest_unreach(p, ICMP_DUR_FRAG); - } - return; - } - /* transmit pbuf on chosen interface */ - netif->output(netif, p, ip_current_dest_addr()); - return; -return_noroute: - snmp_inc_ipoutnoroutes(); -} -#endif /* IP_FORWARD */ - -/** - * This function is called by the network interface device driver when - * an IP packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip_forward). The IP checksum is always checked. - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IP packet (p->payload points to IP header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip_input(struct pbuf *p, struct netif *inp) -{ - struct ip_hdr *iphdr; - struct netif *netif; - u16_t iphdr_hlen; - u16_t iphdr_len; -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - int check_ip_src=1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - IP_STATS_INC(ip.recv); - snmp_inc_ipinreceives(); - - /* identify the IP header */ - iphdr = (struct ip_hdr *)p->payload; - if (IPH_V(iphdr) != 4) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); - ip_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.err); - IP_STATS_INC(ip.drop); - snmp_inc_ipinhdrerrors(); - return ERR_OK; - } - -#ifdef LWIP_HOOK_IP4_INPUT - if (LWIP_HOOK_IP4_INPUT(p, inp)) { - /* the packet has been eaten */ - return ERR_OK; - } -#endif - - /* obtain IP header length in number of 32-bit words */ - iphdr_hlen = IPH_HL(iphdr); - /* calculate IP header length in bytes */ - iphdr_hlen *= 4; - /* obtain ip length in bytes */ - iphdr_len = ntohs(IPH_LEN(iphdr)); - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { - if (iphdr_hlen > p->len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_hlen, p->len)); - } - if (iphdr_len > p->tot_len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_len, p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.lenerr); - IP_STATS_INC(ip.drop); - snmp_inc_ipindiscards(); - return ERR_OK; - } - - /* verify checksum */ -#if CHECKSUM_CHECK_IP - if (inet_chksum(iphdr, iphdr_hlen) != 0) { - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); - ip_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.chkerr); - IP_STATS_INC(ip.drop); - snmp_inc_ipinhdrerrors(); - return ERR_OK; - } -#endif - - /* Trim pbuf. This should have been done at the netif layer, - * but we'll do it anyway just to be sure that its done. */ - pbuf_realloc(p, iphdr_len); - - /* copy IP addresses to aligned ip_addr_t */ - ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_dest), iphdr->dest); - ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_src), iphdr->src); - - /* match packet against an interface, i.e. is this packet for us? */ -#if LWIP_IGMP - if (ip_addr_ismulticast(ip_current_dest_addr())) { - if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip_current_dest_addr()))) { - netif = inp; - } else { - netif = NULL; - } - } else -#endif /* LWIP_IGMP */ - { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", - ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr), - ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), - ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), - ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); - - /* interface is up and configured? */ - if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { - /* unicast to this interface address? */ - if (ip_addr_cmp(ip_current_dest_addr(), &(netif->ip_addr)) || - /* or broadcast on this interface network address? */ - ip_addr_isbroadcast(ip_current_dest_addr(), netif)) { - LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#if LWIP_AUTOIP - /* connections to link-local addresses must persist after changing - the netif's address (RFC3927 ch. 1.9) */ - if ((netif->autoip != NULL) && - ip_addr_cmp(ip_current_dest_addr(), &(netif->autoip->llipaddr))) { - LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#endif /* LWIP_AUTOIP */ - } - if (first) { - first = 0; - netif = netif_list; - } else { - netif = netif->next; - } - if (netif == inp) { - netif = netif->next; - } - } while(netif != NULL); - } - -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed - * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. - * According to RFC 1542 section 3.1.1, referred by RFC 2131). - * - * If you want to accept private broadcast communication while a netif is down, - * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: - * - * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) - */ - if (netif == NULL) { - /* remote port is DHCP server? */ - if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { - struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", - ntohs(udphdr->dest))); - if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); - netif = inp; - check_ip_src = 0; - } - } - } -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ - if (check_ip_src && !ip_addr_isany(ip_current_src_addr())) -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - { if ((ip_addr_isbroadcast(ip_current_src_addr(), inp)) || - (ip_addr_ismulticast(ip_current_src_addr()))) { - /* packet source is not valid */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.drop); - snmp_inc_ipinaddrerrors(); - snmp_inc_ipindiscards(); - return ERR_OK; - } - } - - /* if we're pretending we are everyone for TCP, assume the packet is for source interface if it - isn't for a local address */ - if (netif == NULL && (inp->flags & NETIF_FLAG_PRETEND_TCP) && IPH_PROTO(iphdr) == IP_PROTO_TCP) { - netif = inp; - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); -#if IP_FORWARD - /* non-broadcast packet? */ - if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { - /* try to forward IP packet on (other) interfaces */ - ip_forward(p, iphdr, inp); - } else -#endif /* IP_FORWARD */ - { - snmp_inc_ipinaddrerrors(); - snmp_inc_ipindiscards(); - } - pbuf_free(p); - return ERR_OK; - } - /* packet consists of multiple fragments? */ - if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { -#if IP_REASSEMBLY /* packet fragment reassembly code present? */ - LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", - ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); - /* reassemble the packet*/ - p = ip_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - return ERR_OK; - } - iphdr = (struct ip_hdr *)p->payload; -#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ - pbuf_free(p); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", - ntohs(IPH_OFFSET(iphdr)))); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - snmp_inc_ipinunknownprotos(); - return ERR_OK; -#endif /* IP_REASSEMBLY */ - } - -#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ - -#if LWIP_IGMP - /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ - if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { -#else - if (iphdr_hlen > IP_HLEN) { -#endif /* LWIP_IGMP */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); - pbuf_free(p); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - snmp_inc_ipinunknownprotos(); - return ERR_OK; - } -#endif /* IP_OPTIONS_ALLOWED == 0 */ - - /* send to upper layers */ - LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); - ip_debug_print(p); - LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); - - ip_data.current_netif = inp; - ip_data.current_ip4_header = iphdr; - ip_data.current_ip_header_tot_len = IPH_HL(iphdr) * 4; - -#if LWIP_RAW - /* raw input did not eat the packet? */ - if (raw_input(p, inp) == 0) -#endif /* LWIP_RAW */ - { - pbuf_header(p, -iphdr_hlen); /* Move to payload, no check necessary. */ - - switch (IPH_PROTO(iphdr)) { -#if LWIP_UDP - case IP_PROTO_UDP: -#if LWIP_UDPLITE - case IP_PROTO_UDPLITE: -#endif /* LWIP_UDPLITE */ - snmp_inc_ipindelivers(); - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP_PROTO_TCP: - snmp_inc_ipindelivers(); - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP - case IP_PROTO_ICMP: - snmp_inc_ipindelivers(); - icmp_input(p, inp); - break; -#endif /* LWIP_ICMP */ -#if LWIP_IGMP - case IP_PROTO_IGMP: - igmp_input(p, inp, ip_current_dest_addr()); - break; -#endif /* LWIP_IGMP */ - default: -#if LWIP_ICMP - /* send ICMP destination protocol unreachable unless is was a broadcast */ - if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp) && - !ip_addr_ismulticast(ip_current_dest_addr())) { - pbuf_header(p, iphdr_hlen); /* Move to ip header, no check necessary. */ - p->payload = iphdr; - icmp_dest_unreach(p, ICMP_DUR_PROTO); - } -#endif /* LWIP_ICMP */ - pbuf_free(p); - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); - - IP_STATS_INC(ip.proterr); - IP_STATS_INC(ip.drop); - snmp_inc_ipinunknownprotos(); - } - } - - /* @todo: this is not really necessary... */ - ip_data.current_netif = NULL; - ip_data.current_ip4_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip_addr_set_any(ip_current_src_addr()); - ip_addr_set_any(ip_current_dest_addr()); - - return ERR_OK; -} - -/** - * Sends an IP packet on a network interface. This function constructs - * the IP header and calculates the IP header checksum. If the source - * IP address is NULL, the IP address of the outgoing network - * interface is filled in as source address. - * If the destination IP address is IP_HDRINCL, p is assumed to already - * include an IP header and p->payload points to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an IP - header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - * - * @note ip_id: RFC791 "some host may be able to simply use - * unique identifiers independent of destination" - */ -err_t -ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, - u8_t proto, struct netif *netif) -{ -#if IP_OPTIONS_SEND - return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); -} - -/** - * Same as ip_output_if() but with the possibility to include IP options: - * - * @ param ip_options pointer to the IP options, copied into the IP header - * @ param optlen length of ip_options - */ -err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen) -{ -#endif /* IP_OPTIONS_SEND */ - struct ip_hdr *iphdr; - ip_addr_t dest_addr; -#if CHECKSUM_GEN_IP_INLINE - u32_t chk_sum = 0; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - /* pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - snmp_inc_ipoutrequests(); - - /* Should the IP header be generated or is it already included in p? */ - if (dest != IP_HDRINCL) { - u16_t ip_hlen = IP_HLEN; -#if IP_OPTIONS_SEND - u16_t optlen_aligned = 0; - if (optlen != 0) { -#if CHECKSUM_GEN_IP_INLINE - int i; -#endif /* CHECKSUM_GEN_IP_INLINE */ - /* round up to a multiple of 4 */ - optlen_aligned = ((optlen + 3) & ~3); - ip_hlen += optlen_aligned; - /* First write in the IP options */ - if (pbuf_header(p, optlen_aligned)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); - IP_STATS_INC(ip.err); - snmp_inc_ipoutdiscards(); - return ERR_BUF; - } - MEMCPY(p->payload, ip_options, optlen); - if (optlen < optlen_aligned) { - /* zero the remaining bytes */ - memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); - } -#if CHECKSUM_GEN_IP_INLINE - for (i = 0; i < optlen_aligned/2; i++) { - chk_sum += ((u16_t*)p->payload)[i]; - } -#endif /* CHECKSUM_GEN_IP_INLINE */ - } -#endif /* IP_OPTIONS_SEND */ - /* generate IP header */ - if (pbuf_header(p, IP_HLEN)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); - - IP_STATS_INC(ip.err); - snmp_inc_ipoutdiscards(); - return ERR_BUF; - } - - iphdr = (struct ip_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", - (p->len >= sizeof(struct ip_hdr))); - - IPH_TTL_SET(iphdr, ttl); - IPH_PROTO_SET(iphdr, proto); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += LWIP_MAKE_U16(proto, ttl); -#endif /* CHECKSUM_GEN_IP_INLINE */ - - /* dest cannot be NULL here */ - ip_addr_copy(iphdr->dest, *dest); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - IPH_VHL_SET(iphdr, 4, ip_hlen / 4); - IPH_TOS_SET(iphdr, tos); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_LEN_SET(iphdr, htons(p->tot_len)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_len; -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_OFFSET_SET(iphdr, 0); - IPH_ID_SET(iphdr, htons(ip_id)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_id; -#endif /* CHECKSUM_GEN_IP_INLINE */ - ++ip_id; - - if (ip_addr_isany(src)) { - ip_addr_copy(iphdr->src, netif->ip_addr); - } else { - /* src cannot be NULL here */ - ip_addr_copy(iphdr->src, *src); - } - -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; - chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); - chk_sum = (chk_sum >> 16) + chk_sum; - chk_sum = ~chk_sum; - iphdr->_chksum = chk_sum; /* network order */ -#else /* CHECKSUM_GEN_IP_INLINE */ - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); -#endif -#endif /* CHECKSUM_GEN_IP_INLINE */ - } else { - /* IP header already included in p */ - iphdr = (struct ip_hdr *)p->payload; - ip_addr_copy(dest_addr, iphdr->dest); - dest = &dest_addr; - } - - IP_STATS_INC(ip.xmit); - - LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); - ip_debug_print(p); - -#if ENABLE_LOOPBACK - if (ip_addr_cmp(dest, &netif->ip_addr)) { - /* Packet to self, enqueue it for loopback */ - LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); - return netif_loop_output(netif, p, dest); - } -#if LWIP_IGMP - if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { - netif_loop_output(netif, p, dest); - } -#endif /* LWIP_IGMP */ -#endif /* ENABLE_LOOPBACK */ -#if IP_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - return ip_frag(p, netif, dest); - } -#endif /* IP_FRAG */ - - LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); - return netif->output(netif, p, dest); -} - -/** - * Simple interface to ip_output_if. It finds the outgoing network - * interface and calls upon ip_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an IP - header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto) -{ - struct netif *netif; - - /* pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - if ((netif = ip_route(dest)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - return ip_output_if(p, src, dest, ttl, tos, proto, netif); -} - -#if LWIP_NETIF_HWADDRHINT -/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an IP - header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param addr_hint address hint pointer set to netif->addr_hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) -{ - struct netif *netif; - err_t err; - - /* pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - if ((netif = ip_route(dest)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - NETIF_SET_HWADDRHINT(netif, addr_hint); - err = ip_output_if(p, src, dest, ttl, tos, proto, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - return err; -} -#endif /* LWIP_NETIF_HWADDRHINT*/ - -#if IP_DEBUG -/* Print an IP header by using LWIP_DEBUGF - * @param p an IP packet, p->payload pointing to the IP header - */ -void -ip_debug_print(struct pbuf *p) -{ - struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - - LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", - IPH_V(iphdr), - IPH_HL(iphdr), - IPH_TOS(iphdr), - ntohs(IPH_LEN(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", - ntohs(IPH_ID(iphdr)), - ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, - ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, - ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, - ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", - IPH_TTL(iphdr), - IPH_PROTO(iphdr), - ntohs(IPH_CHKSUM(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", - ip4_addr1_16(&iphdr->src), - ip4_addr2_16(&iphdr->src), - ip4_addr3_16(&iphdr->src), - ip4_addr4_16(&iphdr->src))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", - ip4_addr1_16(&iphdr->dest), - ip4_addr2_16(&iphdr->dest), - ip4_addr3_16(&iphdr->dest), - ip4_addr4_16(&iphdr->dest))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP_DEBUG */ diff --git a/external/badvpn_dns/lwip/src/core/ipv4/ip4_addr.c b/external/badvpn_dns/lwip/src/core/ipv4/ip4_addr.c deleted file mode 100644 index 8f633ff..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/ip4_addr.c +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @file - * This is the IPv4 address tools implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ -const ip_addr_t ip_addr_any = { IPADDR_ANY }; -const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; - -/** - * Determine if an address is a broadcast address on a network interface - * - * @param addr address to be checked - * @param netif the network interface against which the address is checked - * @return returns non-zero if the address is a broadcast address - */ -u8_t -ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) -{ - ip_addr_t ipaddr; - ip4_addr_set_u32(&ipaddr, addr); - - /* all ones (broadcast) or all zeroes (old skool broadcast) */ - if ((~addr == IPADDR_ANY) || - (addr == IPADDR_ANY)) { - return 1; - /* no broadcast support on this network interface? */ - } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { - /* the given address cannot be a broadcast address - * nor can we check against any broadcast addresses */ - return 0; - /* address matches network interface address exactly? => no broadcast */ - } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { - return 0; - /* on the same (sub) network... */ - } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) - /* ...and host identifier bits are all ones? =>... */ - && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == - (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { - /* => network broadcast address */ - return 1; - } else { - return 0; - } -} - -/** Checks if a netmask is valid (starting with ones, then only zeros) - * - * @param netmask the IPv4 netmask to check (in network byte order!) - * @return 1 if the netmask is valid, 0 if it is not - */ -u8_t -ip4_addr_netmask_valid(u32_t netmask) -{ - u32_t mask; - u32_t nm_hostorder = lwip_htonl(netmask); - - /* first, check for the first zero */ - for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) == 0) { - break; - } - } - /* then check that there is no one */ - for (; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) != 0) { - /* there is a one after the first zero -> invalid */ - return 0; - } - } - /* no one after the first zero -> valid */ - return 1; -} - -/* Here for now until needed in other places in lwIP */ -#ifndef isprint -#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) -#define isprint(c) in_range(c, 0x20, 0x7f) -#define isdigit(c) in_range(c, '0', '9') -#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) -#define islower(c) in_range(c, 'a', 'z') -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') -#endif - -/** - * Ascii internet address interpretation routine. - * The value returned is in network order. - * - * @param cp IP address in ascii represenation (e.g. "127.0.0.1") - * @return ip address in network order - */ -u32_t -ipaddr_addr(const char *cp) -{ - ip_addr_t val; - - if (ipaddr_aton(cp, &val)) { - return ip4_addr_get_u32(&val); - } - return (IPADDR_NONE); -} - -/** - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - * - * @param cp IP address in ascii represenation (e.g. "127.0.0.1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ipaddr_aton(const char *cp, ip_addr_t *addr) -{ - u32_t val; - u8_t base; - char c; - u32_t parts[4]; - u32_t *pp = parts; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, 1-9=decimal. - */ - if (!isdigit(c)) - return (0); - val = 0; - base = 10; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') { - base = 16; - c = *++cp; - } else - base = 8; - } - for (;;) { - if (isdigit(c)) { - val = (val * base) + (int)(c - '0'); - c = *++cp; - } else if (base == 16 && isxdigit(c)) { - val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); - c = *++cp; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3) { - return (0); - } - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && !isspace(c)) { - return (0); - } - /* - * Concoct the address according to - * the number of parts specified. - */ - switch (pp - parts + 1) { - - case 0: - return (0); /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffffUL) { - return (0); - } - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) { - return (0); - } - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) { - return (0); - } - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - default: - LWIP_ASSERT("unhandled", 0); - break; - } - if (addr) { - ip4_addr_set_u32(addr, htonl(val)); - } - return (1); -} - -/** - * Convert numeric IP address into decimal dotted ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * represenation of addr - */ -char * -ipaddr_ntoa(const ip_addr_t *addr) -{ - static char str[16]; - return ipaddr_ntoa_r(addr, str, 16); -} - -/** - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) -{ - u32_t s_addr; - char inv[3]; - char *rp; - u8_t *ap; - u8_t rem; - u8_t n; - u8_t i; - int len = 0; - - s_addr = ip4_addr_get_u32(addr); - - rp = buf; - ap = (u8_t *)&s_addr; - for(n = 0; n < 4; n++) { - i = 0; - do { - rem = *ap % (u8_t)10; - *ap /= (u8_t)10; - inv[i++] = '0' + rem; - } while(*ap); - while(i--) { - if (len++ >= buflen) { - return NULL; - } - *rp++ = inv[i]; - } - if (len++ >= buflen) { - return NULL; - } - *rp++ = '.'; - ap++; - } - *--rp = 0; - return buf; -} diff --git a/external/badvpn_dns/lwip/src/core/ipv4/ip_frag.c b/external/badvpn_dns/lwip/src/core/ipv4/ip_frag.c deleted file mode 100644 index 8d18434..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv4/ip_frag.c +++ /dev/null @@ -1,863 +0,0 @@ -/** - * @file - * This is the IPv4 packet segmentation and reassembly implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses jani@iv.ro - * Simon Goldschmidt - * original reassembly code by Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" -#include "lwip/ip_frag.h" -#include "lwip/def.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/snmp.h" -#include "lwip/stats.h" -#include "lwip/icmp.h" - -#include <string.h> - -#if IP_REASSEMBLY -/** - * The IP reassembly code currently has the following limitations: - * - IP header options are not supported - * - fragments must not overlap (e.g. due to different routes), - * currently, overlapping or duplicate fragments are thrown away - * if IP_REASS_CHECK_OVERLAP=1 (the default)! - * - * @todo: work with IP header options - */ - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IP header, since it replaces - * the IP header in memory in incoming fragments (after copying it) to keep - * track of the various fragments. (-> If the IP header doesn't need packing, - * this struct doesn't need packing, too.) - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ - (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ - ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ - IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 - -/* global variables */ -static struct ip_reassdata *reassdatagrams; -static u16_t ip_reass_pbufcount; - -/* function prototypes */ -static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); -static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); - -/** - * Reassembly timer base function - * for both NO_SYS == 0 and 1 (!). - * - * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). - */ -void -ip_reass_tmr(void) -{ - struct ip_reassdata *r, *prev = NULL; - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); - prev = r; - r = r->next; - } else { - /* reassembly timed out */ - struct ip_reassdata *tmp; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip_reass_free_complete_datagram(tmp, prev); - } - } -} - -/** - * Free a datagram (struct ip_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip_reass_pbufcount), - * SNMP counters and sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - * @param prev the previous datagram in the linked list - * @return the number of pbufs freed - */ -static int -ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - u16_t pbufs_freed = 0; - u8_t clen; - struct pbuf *p; - struct ip_reass_helper *iprh; - - LWIP_ASSERT("prev != ipr", prev != ipr); - if (prev != NULL) { - LWIP_ASSERT("prev->next == ipr", prev->next == ipr); - } - - snmp_inc_ipreasmfails(); -#if LWIP_ICMP - iprh = (struct ip_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, copy the original header into it. */ - SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); - icmp_time_exceeded(p, ICMP_TE_FRAG); - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(p); - } -#endif /* LWIP_ICMP */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(pcur); - } - /* Then, unchain the struct ip_reassdata from the list and free it. */ - ip_reass_dequeue_datagram(ipr, prev); - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); - ip_reass_pbufcount -= pbufs_freed; - - return pbufs_freed; -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram 'fraghdr' belongs to is not freed! - * - * @param fraghdr IP header of the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - * @return the number of pbufs freed - */ -static int -ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) -{ - /* @todo Can't we simply remove the last datagram in the - * linked list behind reassdatagrams? - */ - struct ip_reassdata *r, *oldest, *prev; - int pbufs_freed = 0, pbufs_freed_current; - int other_datagrams; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the datagram that 'fraghdr' belongs to! */ - do { - oldest = NULL; - prev = NULL; - other_datagrams = 0; - r = reassdatagrams; - while (r != NULL) { - if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { - /* Not the same datagram as fraghdr */ - other_datagrams++; - if (oldest == NULL) { - oldest = r; - } else if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - } - } - if (r->next != NULL) { - prev = r; - } - r = r->next; - } - if (oldest != NULL) { - pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); - pbufs_freed += pbufs_freed_current; - } - } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); - return pbufs_freed; -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Enqueues a new fragment into the fragment queue - * @param fraghdr points to the new fragments IP hdr - * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) - * @return A pointer to the queue location into which the fragment was enqueued - */ -static struct ip_reassdata* -ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) -{ - struct ip_reassdata* ipr; - /* No matching previous fragment found, allocate a new reassdata struct */ - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - } - if (ipr == NULL) -#endif /* IP_REASS_FREE_OLDEST */ - { - IPFRAG_STATS_INC(ip_frag.memerr); - LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); - return NULL; - } - } - memset(ipr, 0, sizeof(struct ip_reassdata)); - ipr->timer = IP_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - /* copy the ip header for later tests and input */ - /* @todo: no ip options supported? */ - SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); - return ipr; -} - -/** - * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. - * @param ipr points to the queue entry to dequeue - */ -static void -ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - - /* dequeue the reass struct */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", prev != NULL); - prev->next = ipr->next; - } - - /* now we can free the ip_reass struct */ - memp_free(MEMP_REASSDATA, ipr); -} - -/** - * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list - * will grow over time as new pbufs are rx. - * Also checks that the datagram passes basic continuity checks (if the last - * fragment was received at least once). - * @param root_p points to the 'root' pbuf for the current datagram being assembled. - * @param new_p points to the pbuf for the current fragment - * @return 0 if invalid, >0 otherwise - */ -static int -ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) -{ - struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; - struct pbuf *q; - u16_t offset,len; - struct ip_hdr *fraghdr; - int valid = 1; - - /* Extract length and fragment offset from current fragment */ - fraghdr = (struct ip_hdr*)new_p->payload; - len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; - offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; - - /* overwrite the fragment's ip header from the pbuf with our helper struct, - * and setup the embedded helper structure. */ - /* make sure the struct ip_reass_helper fits into the IP header */ - LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", - sizeof(struct ip_reass_helper) <= IP_HLEN); - iprh = (struct ip_reass_helper*)new_p->payload; - iprh->next_pbuf = NULL; - iprh->start = offset; - iprh->end = offset + len; - - /* Iterate through until we either get to the end of the list (append), - * or we find on with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip_reass_helper*)q->payload; - if (iprh->start < iprh_tmp->start) { - /* the new pbuf should be inserted before this */ - iprh->next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ -#if IP_REASS_CHECK_OVERLAP - if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { - /* fragment overlaps with previous or following, throw away */ - goto freepbuf; - } -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - } else { - /* fragment with the lowest offset */ - ipr->p = new_p; - } - break; - } else if(iprh->start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - goto freepbuf; -#if IP_REASS_CHECK_OVERLAP - } else if(iprh->start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - goto freepbuf; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no wholes. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - if (iprh_prev->end != iprh->start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = new_p; - } - } - - /* At this point, the validation part begins: */ - /* If we already received the last fragment */ - if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { - /* and had no wholes so far */ - if (valid) { - /* then check if the rest of the fragments is here */ - /* Check if the queue starts with the first datagram */ - if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { - valid = 0; - } else { - /* and check that there are no wholes after this datagram */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while (q != NULL) { - iprh = (struct ip_reass_helper*)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - /* if still valid, all fragments are received - * (because to the MF==0 already arrived */ - if (valid) { - LWIP_ASSERT("sanity check", ipr->p != NULL); - LWIP_ASSERT("sanity check", - ((struct ip_reass_helper*)ipr->p->payload) != iprh); - LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", - iprh->next_pbuf == NULL); - LWIP_ASSERT("validate_datagram:datagram end!=datagram len", - iprh->end == ipr->datagram_len); - } - } - } - /* If valid is 0 here, there are some fragments missing in the middle - * (since MF == 0 has already arrived). Such datagrams simply time out if - * no more fragments are received... */ - return valid; - } - /* If we come here, not all fragments were received, yet! */ - return 0; /* not yet valid! */ -#if IP_REASS_CHECK_OVERLAP -freepbuf: - ip_reass_pbufcount -= pbuf_clen(new_p); - pbuf_free(new_p); - return 0; -#endif /* IP_REASS_CHECK_OVERLAP */ -} - -/** - * Reassembles incoming IP fragments into an IP datagram. - * - * @param p points to a pbuf chain of the fragment - * @return NULL if reassembly is incomplete, ? otherwise - */ -struct pbuf * -ip_reass(struct pbuf *p) -{ - struct pbuf *r; - struct ip_hdr *fraghdr; - struct ip_reassdata *ipr; - struct ip_reass_helper *iprh; - u16_t offset, len; - u8_t clen; - struct ip_reassdata *ipr_prev = NULL; - - IPFRAG_STATS_INC(ip_frag.recv); - snmp_inc_ipreasmreqds(); - - fraghdr = (struct ip_hdr*)p->payload; - - if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { - LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); - IPFRAG_STATS_INC(ip_frag.err); - goto nullreturn; - } - - offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; - len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; - - /* Check if we are allowed to enqueue more datagrams. */ - clen = pbuf_clen(p); - if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || - ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) -#endif /* IP_REASS_FREE_OLDEST */ - { - /* No datagram could be freed and still too many pbufs enqueued */ - LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", - ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); - IPFRAG_STATS_INC(ip_frag.memerr); - /* @todo: send ICMP time exceeded here? */ - /* drop this pbuf */ - goto nullreturn; - } - } - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", - ntohs(IPH_ID(fraghdr)))); - IPFRAG_STATS_INC(ip_frag.cachehit); - break; - } - ipr_prev = ipr; - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); - /* Bail if unable to enqueue */ - if(ipr == NULL) { - goto nullreturn; - } - } else { - if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && - ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { - /* ipr->iphdr is not the header from the first fragment, but fraghdr is - * -> copy fraghdr into ipr->iphdr since we want to have the header - * of the first fragment (for ICMP time exceeded and later, for copying - * all options, if supported)*/ - SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); - } - } - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time */ - ip_reass_pbufcount += clen; - - /* At this point, we have either created a new entry or pointing - * to an existing one */ - - /* check for 'no more fragments', and update queue entry*/ - if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { - ipr->flags |= IP_REASS_FLAG_LASTFRAG; - ipr->datagram_len = offset + len; - LWIP_DEBUGF(IP_REASS_DEBUG, - ("ip_reass: last fragment seen, total len %"S16_F"\n", - ipr->datagram_len)); - } - /* find the right place to insert this pbuf */ - /* @todo: trim pbufs if fragments are overlapping */ - if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { - /* the totally last fragment (flag more fragments = 0) was received at least - * once AND all fragments are received */ - ipr->datagram_len += IP_HLEN; - - /* save the second pbuf before copying the header over the pointer */ - r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; - - /* copy the original ip header back to the first pbuf */ - fraghdr = (struct ip_hdr*)(ipr->p->payload); - SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); - IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); - IPH_OFFSET_SET(fraghdr, 0); - IPH_CHKSUM_SET(fraghdr, 0); - /* @todo: do we need to set calculate the correct checksum? */ - IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); - - p = ipr->p; - - /* chain together the pbufs contained within the reass_data list. */ - while(r != NULL) { - iprh = (struct ip_reass_helper*)r->payload; - - /* hide the ip header for every succeding fragment */ - pbuf_header(r, -IP_HLEN); - pbuf_cat(p, r); - r = iprh->next_pbuf; - } - /* release the sources allocate for the fragment queue entry */ - ip_reass_dequeue_datagram(ipr, ipr_prev); - - /* and adjust the number of pbufs currently queued for reassembly. */ - ip_reass_pbufcount -= pbuf_clen(p); - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); - return NULL; - -nullreturn: - LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); - IPFRAG_STATS_INC(ip_frag.drop); - pbuf_free(p); - return NULL; -} -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if IP_FRAG_USES_STATIC_BUF -static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)]; -#else /* IP_FRAG_USES_STATIC_BUF */ - -#if !LWIP_NETIF_TX_SINGLE_PBUF -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref* -ip_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ipfrag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip_frag_free_pbuf_custom_ref(pcr); -} -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ -#endif /* IP_FRAG_USES_STATIC_BUF */ - -/** - * Fragment an IP datagram if too large for the netif. - * - * Chop the datagram in MTU sized chunks and send them in order - * by using a fixed size static memory buffer (PBUF_REF) or - * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF). - * - * @param p ip packet to send - * @param netif the netif on which to send - * @param dest destination ip address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) -{ - struct pbuf *rambuf; -#if IP_FRAG_USES_STATIC_BUF - struct pbuf *header; -#else -#if !LWIP_NETIF_TX_SINGLE_PBUF - struct pbuf *newpbuf; -#endif - struct ip_hdr *original_iphdr; -#endif - struct ip_hdr *iphdr; - u16_t nfb; - u16_t left, cop; - u16_t mtu = netif->mtu; - u16_t ofo, omf; - u16_t last; - u16_t poff = IP_HLEN; - u16_t tmp; -#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF - u16_t newpbuflen = 0; - u16_t left_to_copy; -#endif - - /* Get a RAM based MTU sized pbuf */ -#if IP_FRAG_USES_STATIC_BUF - /* When using a static buffer, we use a PBUF_REF, which we will - * use to reference the packet (without link header). - * Layer and length is irrelevant. - */ - rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF); - if (rambuf == NULL) { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n")); - return ERR_MEM; - } - rambuf->tot_len = rambuf->len = mtu; - rambuf->payload = LWIP_MEM_ALIGN((void *)buf); - - /* Copy the IP header in it */ - iphdr = (struct ip_hdr *)rambuf->payload; - SMEMCPY(iphdr, p->payload, IP_HLEN); -#else /* IP_FRAG_USES_STATIC_BUF */ - original_iphdr = (struct ip_hdr *)p->payload; - iphdr = original_iphdr; -#endif /* IP_FRAG_USES_STATIC_BUF */ - - /* Save original offset */ - tmp = ntohs(IPH_OFFSET(iphdr)); - ofo = tmp & IP_OFFMASK; - omf = tmp & IP_MF; - - left = p->tot_len - IP_HLEN; - - nfb = (mtu - IP_HLEN) / 8; - - while (left) { - last = (left <= mtu - IP_HLEN); - - /* Set new offset and MF flag */ - tmp = omf | (IP_OFFMASK & (ofo)); - if (!last) { - tmp = tmp | IP_MF; - } - - /* Fill this fragment */ - cop = last ? left : nfb * 8; - -#if IP_FRAG_USES_STATIC_BUF - poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); -#else /* IP_FRAG_USES_STATIC_BUF */ -#if LWIP_NETIF_TX_SINGLE_PBUF - rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM); - if (rambuf == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); - poff += pbuf_copy_partial(p, rambuf->payload, cop, poff); - /* make room for the IP header */ - if(pbuf_header(rambuf, IP_HLEN)) { - pbuf_free(rambuf); - return ERR_MEM; - } - /* fill in the IP header */ - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = rambuf->payload; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link and IP header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); - if (rambuf == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (p->len >= (IP_HLEN))); - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = (struct ip_hdr *)rambuf->payload; - - /* Can just adjust p directly for needed offset. */ - p->payload = (u8_t *)p->payload + poff; - p->len -= poff; - - left_to_copy = cop; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; - /* Is this pbuf already empty? */ - if (!newpbuflen) { - p = p->next; - continue; - } - pcr = ip_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - return ERR_MEM; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); - if (newpbuf == NULL) { - ip_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - return ERR_MEM; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy -= newpbuflen; - if (left_to_copy) { - p = p->next; - } - } - poff = newpbuflen; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ -#endif /* IP_FRAG_USES_STATIC_BUF */ - - /* Correct header */ - IPH_OFFSET_SET(iphdr, htons(tmp)); - IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); - IPH_CHKSUM_SET(iphdr, 0); - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); - -#if IP_FRAG_USES_STATIC_BUF - if (last) { - pbuf_realloc(rambuf, left + IP_HLEN); - } - - /* This part is ugly: we alloc a RAM based pbuf for - * the link level header for each chunk and then - * free it.A PBUF_ROM style pbuf for which pbuf_header - * worked would make things simpler. - */ - header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); - if (header != NULL) { - pbuf_chain(header, rambuf); - netif->output(netif, header, dest); - IPFRAG_STATS_INC(ip_frag.xmit); - snmp_inc_ipfragcreates(); - pbuf_free(header); - } else { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n")); - pbuf_free(rambuf); - return ERR_MEM; - } -#else /* IP_FRAG_USES_STATIC_BUF */ - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - netif->output(netif, rambuf, dest); - IPFRAG_STATS_INC(ip_frag.xmit); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); -#endif /* IP_FRAG_USES_STATIC_BUF */ - left -= cop; - ofo += nfb; - } -#if IP_FRAG_USES_STATIC_BUF - pbuf_free(rambuf); -#endif /* IP_FRAG_USES_STATIC_BUF */ - snmp_inc_ipfragoks(); - return ERR_OK; -} -#endif /* IP_FRAG */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/README b/external/badvpn_dns/lwip/src/core/ipv6/README deleted file mode 100644 index 3620004..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/README +++ /dev/null @@ -1 +0,0 @@ -IPv6 support in lwIP is very experimental. diff --git a/external/badvpn_dns/lwip/src/core/ipv6/dhcp6.c b/external/badvpn_dns/lwip/src/core/ipv6/dhcp6.c deleted file mode 100644 index 9656c3b..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/dhcp6.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file - * - * DHCPv6. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" - - -#endif /* LWIP_IPV6_DHCP6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/ethip6.c b/external/badvpn_dns/lwip/src/core/ipv6/ethip6.c deleted file mode 100644 index ab9783a..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/ethip6.c +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET - -#include "lwip/ethip6.h" -#include "lwip/nd6.h" -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" - -#include <string.h> - -#define ETHTYPE_IPV6 0x86DD - -/** The ethernet address */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct eth_addr { - PACK_STRUCT_FIELD(u8_t addr[6]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Ethernet header */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct eth_hdr { -#if ETH_PAD_SIZE - PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); -#endif - PACK_STRUCT_FIELD(struct eth_addr dest); - PACK_STRUCT_FIELD(struct eth_addr src); - PACK_STRUCT_FIELD(u16_t type); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) - -/** - * Send an IPv6 packet on the network using netif->linkoutput - * The ethernet header is filled in before sending. - * - * @params netif the lwIP network interface on which to send the packet - * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header - * @params src the source MAC address to be copied into the ethernet header - * @params dst the destination MAC address to be copied into the ethernet header - * @return ERR_OK if the packet was sent, any other err_t on failure - */ -static err_t -ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) -{ - struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; - - LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!", - (netif->hwaddr_len == 6)); - SMEMCPY(ðhdr->dest, dst, 6); - SMEMCPY(ðhdr->src, src, 6); - ethhdr->type = PP_HTONS(ETHTYPE_IPV6); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p)); - /* send the packet */ - return netif->linkoutput(netif, p); -} - -/** - * Resolve and fill-in Ethernet address header for outgoing IPv6 packet. - * - * For IPv6 multicast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, ... - * - * @TODO anycast addresses - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return - * - ERR_RTE No route to destination (no gateway to external networks), - * or the return type of either etharp_query() or etharp_send_ip(). - */ -err_t -ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr) -{ - struct eth_addr dest; - s8_t i; - - /* make room for Ethernet header - should not fail */ - if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { - /* bail out */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("etharp_output: could not allocate room for header.\n")); - return ERR_BUF; - } - - /* multicast destination IP address? */ - if (ip6_addr_ismulticast(ip6addr)) { - /* Hash IP multicast address to MAC address.*/ - dest.addr[0] = 0x33; - dest.addr[1] = 0x33; - dest.addr[2] = ((u8_t *)(&(ip6addr->addr[3])))[0]; - dest.addr[3] = ((u8_t *)(&(ip6addr->addr[3])))[1]; - dest.addr[4] = ((u8_t *)(&(ip6addr->addr[3])))[2]; - dest.addr[5] = ((u8_t *)(&(ip6addr->addr[3])))[3]; - - /* Send out. */ - return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest); - } - - /* We have a unicast destination IP address */ - /* TODO anycast? */ - /* Get next hop record. */ - i = nd6_get_next_hop_entry(ip6addr, netif); - if (i < 0) { - /* failed to get a next hop neighbor record. */ - return ERR_MEM; - } - - /* Now that we have a destination record, send or queue the packet. */ - if (neighbor_cache[i].state == ND6_STALE) { - /* Switch to delay state. */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; - } - /* TODO should we send or queue if PROBE? send for now, to let unicast NS pass. */ - if ((neighbor_cache[i].state == ND6_REACHABLE) || - (neighbor_cache[i].state == ND6_DELAY) || - (neighbor_cache[i].state == ND6_PROBE)) { - - /* Send out. */ - SMEMCPY(dest.addr, neighbor_cache[i].lladdr, 6); - return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest); - } - - /* We should queue packet on this interface. */ - pbuf_header(q, -(s16_t)SIZEOF_ETH_HDR); - return nd6_queue_packet(i, q); -} - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/icmp6.c b/external/badvpn_dns/lwip/src/core/ipv6/icmp6.c deleted file mode 100644 index ea82682..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/icmp6.c +++ /dev/null @@ -1,337 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/stats.h" - -#include <string.h> - -#ifndef LWIP_ICMP6_DATASIZE -#define LWIP_ICMP6_DATASIZE 8 -#endif -#if LWIP_ICMP6_DATASIZE == 0 -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/* Forward declarations */ -static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); - - -/** - * Process an input ICMPv6 message. Called by ip6_input. - * - * Will generate a reply for echo requests. Other messages are forwarded - * to nd6_input, or mld6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -icmp6_input(struct pbuf *p, struct netif *inp) -{ - struct icmp6_hdr *icmp6hdr; - struct pbuf * r; - ip6_addr_t * reply_src; - - ICMP6_STATS_INC(icmp6.recv); - - /* Check that ICMPv6 header fits in payload */ - if (p->len < sizeof(struct icmp6_hdr)) { - /* drop short packets */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.lenerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - -#if LWIP_ICMP6_CHECKSUM_CHECK - if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), - ip6_current_dest_addr()) != 0) { - /* Checksum failed */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.chkerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } -#endif /* LWIP_ICMP6_CHECKSUM_CHECK */ - - switch (icmp6hdr->type) { - case ICMP6_TYPE_NA: /* Neighbor advertisement */ - case ICMP6_TYPE_NS: /* Neighbor solicitation */ - case ICMP6_TYPE_RA: /* Router advertisement */ - case ICMP6_TYPE_RD: /* Redirect */ - case ICMP6_TYPE_PTB: /* Packet too big */ - nd6_input(p, inp); - return; - break; - case ICMP6_TYPE_RS: -#if LWIP_IPV6_FORWARD - /* TODO implement router functionality */ -#endif - break; -#if LWIP_IPV6_MLD - case ICMP6_TYPE_MLQ: - case ICMP6_TYPE_MLR: - case ICMP6_TYPE_MLD: - mld6_input(p, inp); - return; - break; -#endif - case ICMP6_TYPE_EREQ: -#if !LWIP_MULTICAST_PING - /* multicast destination address? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.drop); - return; - } -#endif /* LWIP_MULTICAST_PING */ - - /* Allocate reply. */ - r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM); - if (r == NULL) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - - /* Copy echo request. */ - if (pbuf_copy(r, p) != ERR_OK) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.err); - return; - } - - /* Determine reply source IPv6 address. */ -#if LWIP_MULTICAST_PING - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - reply_src = ip6_select_source_address(inp, ip6_current_src_addr()); - if (reply_src == NULL) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - else -#endif /* LWIP_MULTICAST_PING */ - { - reply_src = ip6_current_dest_addr(); - } - - /* Set fields in reply. */ - ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; - ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; - ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, - IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); - - /* Send reply. */ - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(r, reply_src, ip6_current_src_addr(), - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp); - pbuf_free(r); - - break; - default: - ICMP6_STATS_INC(icmp6.proterr); - ICMP6_STATS_INC(icmp6.drop); - break; - } - - pbuf_free(p); -} - - -/** - * Send an icmpv6 'destination unreachable' packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the unreachable type - */ -void -icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR); -} - -/** - * Send an icmpv6 'packet too big' packet. - * - * @param p the input packet for which the 'packet too big' should be sent, - * p->payload pointing to the IPv6 header - * @param mtu the maximum mtu that we can accept - */ -void -icmp6_packet_too_big(struct pbuf *p, u32_t mtu) -{ - icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB); -} - -/** - * Send an icmpv6 'time exceeded' packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the time exceeded type - */ -void -icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_TE); -} - -/** - * Send an icmpv6 'parameter problem' packet. - * - * @param p the input packet for which the 'param problem' should be sent, - * p->payload pointing to the IP header - * @param c ICMPv6 code for the param problem type - * @param pointer the pointer to the byte where the parameter is found - */ -void -icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) -{ - icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP); -} - -/** - * Send an ICMPv6 packet in response to an incoming packet. - * - * @param p the input packet for which the response should be sent, - * p->payload pointing to the IPv6 header - * @param code Code of the ICMPv6 header - * @param data Additional 32-bit parameter in the ICMPv6 header - * @param type Type of the ICMPv6 header - */ -static void -icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) -{ - struct pbuf *q; - struct icmp6_hdr *icmp6hdr; - ip6_addr_t *reply_src, *reply_dest; - ip6_addr_t reply_src_local, reply_dest_local; - struct ip6_hdr *ip6hdr; - struct netif *netif; - - /* ICMPv6 header + IPv6 header + data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n")); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp 6message", - (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE))); - - icmp6hdr = (struct icmp6_hdr *)q->payload; - icmp6hdr->type = type; - icmp6hdr->code = code; - icmp6hdr->data = data; - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, - IP6_HLEN + LWIP_ICMP6_DATASIZE); - - /* Get the destination address and netif for this ICMP message. */ - if ((ip_current_netif() == NULL) || - ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) { - /* Special case, as ip6_current_xxx is either NULL, or points - * to a different packet than the one that expired. - * We must use the addresses that are stored in the expired packet. */ - ip6hdr = (struct ip6_hdr *)p->payload; - /* copy from packed address to aligned address */ - ip6_addr_copy(reply_dest_local, ip6hdr->src); - ip6_addr_copy(reply_src_local, ip6hdr->dest); - reply_dest = &reply_dest_local; - reply_src = &reply_src_local; - netif = ip6_route(reply_src, reply_dest); - if (netif == NULL) { - /* drop */ - pbuf_free(q); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - else { - netif = ip_current_netif(); - reply_dest = ip6_current_src_addr(); - - /* Select an address to use as source. */ - reply_src = ip6_select_source_address(netif, reply_dest); - if (reply_src == NULL) { - /* drop */ - pbuf_free(q); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - - /* calculate checksum */ - icmp6hdr->chksum = 0; - icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, - reply_src, reply_dest); - - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(q); -} - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/inet6.c b/external/badvpn_dns/lwip/src/core/ipv6/inet6.c deleted file mode 100644 index bdf4ff4..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/inet6.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * - * INET v6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/inet6.h" - -/** @see ip6_addr.c for implementation of functions. */ - -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/ip6.c b/external/badvpn_dns/lwip/src/core/ipv6/ip6.c deleted file mode 100644 index 1eb91f9..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/ip6.c +++ /dev/null @@ -1,1034 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip6_frag.h" -#include "lwip/icmp6.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp_impl.h" -#include "lwip/dhcp6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/debug.h" -#include "lwip/stats.h" - - -/** - * Finds the appropriate network interface for a given IPv6 address. It tries to select - * a netif following a sequence of heuristics: - * 1) if there is only 1 netif, return it - * 2) if the destination is a link-local address, try to match the src address to a netif. - * this is a tricky case because with multiple netifs, link-local addresses only have - * meaning within a particular subnet/link. - * 3) tries to match the destination subnet to a configured address - * 4) tries to find a router - * 5) tries to match the source address to the netif - * 6) returns the default netif, if configured - * - * @param src the source IPv6 address, if known - * @param dest the destination IPv6 address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip6_route(struct ip6_addr *src, struct ip6_addr *dest) -{ - struct netif *netif; - s8_t i; - - /* If single netif configuration, fast return. */ - if ((netif_list != NULL) && (netif_list->next == NULL)) { - return netif_list; - } - - /* Special processing for link-local addresses. */ - if (ip6_addr_islinklocal(dest)) { - if (ip6_addr_isany(src)) { - /* Use default netif. */ - return netif_default; - } - - /* Try to find the netif for the source address. */ - for(netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - - /* netif not found, use default netif */ - return netif_default; - } - - /* See if the destination subnet matches a configured address. */ - for(netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - - /* Get the netif for a suitable router. */ - i = nd6_select_router(dest, NULL); - if (i >= 0) { - if (default_router_list[i].neighbor_entry != NULL) { - if (default_router_list[i].neighbor_entry->netif != NULL) { - return default_router_list[i].neighbor_entry->netif; - } - } - } - - /* try with the netif that matches the source address. */ - if (!ip6_addr_isany(src)) { - for(netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - } - - /* no matching netif found, use default netif */ - return netif_default; -} - -/** - * Select the best IPv6 source address for a given destination - * IPv6 address. Loosely follows RFC 3484. "Strong host" behavior - * is assumed. - * - * @param netif the netif on which to send a packet - * @param dest the destination we are trying to reach - * @return the most suitable source address to use, or NULL if no suitable - * source address is found - */ -ip6_addr_t * -ip6_select_source_address(struct netif *netif, ip6_addr_t * dest) -{ - ip6_addr_t * src = NULL; - u8_t i; - - /* If dest is link-local, choose a link-local source. */ - if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_linklocal(dest) || ip6_addr_ismulticast_iflocal(dest)) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_islinklocal(netif_ip6_addr(netif, i))) { - return netif_ip6_addr(netif, i); - } - } - } - - /* Choose a site-local with matching prefix. */ - if (ip6_addr_issitelocal(dest) || ip6_addr_ismulticast_sitelocal(dest)) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_issitelocal(netif_ip6_addr(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { - return netif_ip6_addr(netif, i); - } - } - } - - /* Choose a unique-local with matching prefix. */ - if (ip6_addr_isuniquelocal(dest) || ip6_addr_ismulticast_orglocal(dest)) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { - return netif_ip6_addr(netif, i); - } - } - } - - /* Choose a global with best matching prefix. */ - if (ip6_addr_isglobal(dest) || ip6_addr_ismulticast_global(dest)) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_isglobal(netif_ip6_addr(netif, i))) { - if (src == NULL) { - src = netif_ip6_addr(netif, i); - } - else { - /* Replace src only if we find a prefix match. */ - /* TODO find longest matching prefix. */ - if ((!(ip6_addr_netcmp(src, dest))) && - ip6_addr_netcmp(netif_ip6_addr(netif, i), dest)) { - src = netif_ip6_addr(netif, i); - } - } - } - } - if (src != NULL) { - return src; - } - } - - /* Last resort: see if arbitrary prefix matches. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { - return netif_ip6_addr(netif, i); - } - } - - return NULL; -} - -#if LWIP_IPV6_FORWARD -/** - * Forwards an IPv6 packet. It finds an appropriate route for the - * packet, decrements the HL value of the packet, and outputs - * the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IPv6 header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - /* do not forward link-local addresses */ - if (ip6_addr_islinklocal(ip6_current_dest_addr())) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip6_route(IP6_ADDR_ANY, ip6_current_dest_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* decrement HL */ - IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1); - /* send ICMP6 if HL == 0 */ - if (IP6H_HOPLIM(iphdr) == 0) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_time_exceeded(p, ICMP6_TE_HL); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - if (netif->mtu && (p->tot_len > netif->mtu)) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_packet_too_big(p, netif->mtu); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); - - /* transmit pbuf on chosen interface */ - netif->output_ip6(netif, p, ip6_current_dest_addr()); - IP6_STATS_INC(ip6.fw); - IP6_STATS_INC(ip6.xmit); - return; -} -#endif /* LWIP_IPV6_FORWARD */ - - -/** - * This function is called by the network interface device driver when - * an IPv6 packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip6_forward). - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IPv6 packet (p->payload points to IPv6 header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip6_input(struct pbuf *p, struct netif *inp) -{ - struct ip6_hdr *ip6hdr; - struct netif *netif; - u8_t nexth; - u16_t hlen; /* the current header length */ - u8_t i; -#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ - @todo - int check_ip_src=1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - IP6_STATS_INC(ip6.recv); - - /* identify the IP header */ - ip6hdr = (struct ip6_hdr *)p->payload; - if (IP6H_V(ip6hdr) != 6) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", - IP6H_V(ip6hdr))); - pbuf_free(p); - IP6_STATS_INC(ip6.err); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) { - if (IP6_HLEN > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - IP6_HLEN, p->len)); - } - if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - IP6H_PLEN(ip6hdr) + IP6_HLEN, p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* Trim pbuf. This should have been done at the netif layer, - * but we'll do it anyway just to be sure that its done. */ - pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr)); - - /* copy IP addresses to aligned ip6_addr_t */ - ip6_addr_copy(ip_data.current_iphdr_dest.ip6, ip6hdr->dest); - ip6_addr_copy(ip_data.current_iphdr_src.ip6, ip6hdr->src); - - /* current header pointer. */ - ip_data.current_ip6_header = ip6hdr; - - /* In netif, used in case we need to send ICMPv6 packets back. */ - ip_data.current_netif = inp; - - /* match packet against an interface, i.e. is this packet for us? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* Always joined to multicast if-local and link-local all-nodes group. */ - if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) || - ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) { - netif = inp; - } -#if LWIP_IPV6_MLD - else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) { - netif = inp; - } -#else /* LWIP_IPV6_MLD */ - else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { - /* Filter solicited node packets when MLD is not enabled - * (for Neighbor discovery). */ - netif = NULL; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { - netif = inp; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - break; - } - } - } -#endif /* LWIP_IPV6_MLD */ - else { - netif = NULL; - } - } - else { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - /* interface is up? */ - if (netif_is_up(netif)) { - /* unicast to this interface address? address configured? */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) { - /* exit outer loop */ - goto netif_found; - } - } - } - if (ip6_addr_islinklocal(ip6_current_dest_addr())) { - /* Do not match link-local addresses to other netifs. */ - netif = NULL; - break; - } - if (first) { - first = 0; - netif = netif_list; - } else { - netif = netif->next; - } - if (netif == inp) { - netif = netif->next; - } - } while(netif != NULL); -netif_found: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", - netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); - } - - /* "::" packet source address? (used in duplicate address detection) */ - if (ip6_addr_isany(ip6_current_src_addr()) && - (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) { - /* packet source is not valid */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - /* if we're pretending we are everyone for TCP, assume the packet is for source interface if it - isn't for a local address */ - if (netif == NULL && (inp->flags & NETIF_FLAG_PRETEND_TCP) && IP6H_NEXTH(ip6hdr) == IP6_NEXTH_TCP) { - netif = inp; - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n")); -#if LWIP_IPV6_FORWARD - /* non-multicast packet? */ - if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* try to forward IP packet on (other) interfaces */ - ip6_forward(p, ip6hdr, inp); - } -#endif /* LWIP_IPV6_FORWARD */ - pbuf_free(p); - goto ip6_input_cleanup; - } - - /* current netif pointer. */ - ip_data.current_netif = netif; - - /* Save next header type. */ - nexth = IP6H_NEXTH(ip6hdr); - - /* Init header length. */ - hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; - - /* Move to payload. */ - pbuf_header(p, -IP6_HLEN); - - /* Process known option extension headers, if present. */ - while (nexth != IP6_NEXTH_NONE) - { - switch (nexth) { - case IP6_NEXTH_HOPBYHOP: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -hlen); - break; - case IP6_NEXTH_DESTOPTS: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -hlen); - break; - case IP6_NEXTH_ROUTING: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -hlen); - break; - - case IP6_NEXTH_FRAGMENT: - { - struct ip6_frag_hdr * frag_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); - - frag_hdr = (struct ip6_frag_hdr *)p->payload; - - /* Get next header type. */ - nexth = frag_hdr->_nexth; - - /* Fragment Header length. */ - hlen = 8; - ip_data.current_ip_header_tot_len += hlen; - - /* Make sure this header fits in current pbuf. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_FRAG_STATS_INC(ip6_frag.lenerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto ip6_input_cleanup; - } - - /* Offset == 0 and more_fragments == 0? */ - if (((frag_hdr->_fragment_offset & IP6_FRAG_OFFSET_MASK) == 0) && - ((frag_hdr->_fragment_offset & IP6_FRAG_MORE_FLAG) == 0)) { - - /* This is a 1-fragment packet, usually a packet that we have - * already reassembled. Skip this header anc continue. */ - pbuf_header(p, -hlen); - } - else { -#if LWIP_IPV6_REASS - - /* reassemble the packet */ - p = ip6_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - goto ip6_input_cleanup; - } - - /* Returned p point to IPv6 header. - * Update all our variables and pointers and continue. */ - ip6hdr = (struct ip6_hdr *)p->payload; - nexth = IP6H_NEXTH(ip6hdr); - hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; - pbuf_header(p, -IP6_HLEN); - -#else /* LWIP_IPV6_REASS */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.opterr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; -#endif /* LWIP_IPV6_REASS */ - } - break; - } - default: - goto options_done; - break; - } - } -options_done: - - /* p points to IPv6 header again. */ - pbuf_header(p, ip_data.current_ip_header_tot_len); - - /* send to upper layers */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); - ip6_debug_print(p); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); - -#if LWIP_RAW - /* raw input did not eat the packet? */ - if (raw_input(p, inp) == 0) -#endif /* LWIP_RAW */ - { - switch (nexth) { - case IP6_NEXTH_NONE: - pbuf_free(p); - break; -#if LWIP_UDP - case IP6_NEXTH_UDP: -#if LWIP_UDPLITE - case IP6_NEXTH_UDPLITE: -#endif /* LWIP_UDPLITE */ - /* Point to payload. */ - pbuf_header(p, -ip_data.current_ip_header_tot_len); - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP6_NEXTH_TCP: - /* Point to payload. */ - pbuf_header(p, -ip_data.current_ip_header_tot_len); - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP6 - case IP6_NEXTH_ICMP6: - /* Point to payload. */ - pbuf_header(p, -ip_data.current_ip_header_tot_len); - icmp6_input(p, inp); - break; -#endif /* LWIP_ICMP */ - default: -#if LWIP_ICMP6 - /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ - if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && - (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { - icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen); - } -#endif /* LWIP_ICMP */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr))); - pbuf_free(p); - IP6_STATS_INC(ip6.proterr); - IP6_STATS_INC(ip6.drop); - break; - } - } - -ip6_input_cleanup: - ip_data.current_netif = NULL; - ip_data.current_ip6_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip6_addr_set_any(&ip_data.current_iphdr_src.ip6); - ip6_addr_set_any(&ip_data.current_iphdr_dest.ip6); - - return ERR_OK; -} - - -/** - * Sends an IPv6 packet on a network interface. This function constructs - * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is - * used as source (usually during network startup). If the source IPv6 address it - * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network - * interface is filled in as source address. If the destination IPv6 address is - * IP_HDRINCL, p is assumed to already include an IPv6 header and p->payload points - * to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IPv6/LINK headers - * returns errors returned by netif->output - */ -err_t -ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, - u8_t nexth, struct netif *netif) -{ - struct ip6_hdr *ip6hdr; - ip6_addr_t dest_addr; - - /* pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - /* Should the IPv6 header be generated or is it already included in p? */ - if (dest != IP_HDRINCL) { - /* generate IPv6 header */ - if (pbuf_header(p, IP6_HLEN)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - ip6hdr = (struct ip6_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", - (p->len >= sizeof(struct ip6_hdr))); - - IP6H_HOPLIM_SET(ip6hdr, hl); - IP6H_NEXTH_SET(ip6hdr, nexth); - - /* dest cannot be NULL here */ - ip6_addr_copy(ip6hdr->dest, *dest); - - IP6H_VTCFL_SET(ip6hdr, 6, tc, 0); - IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN); - - if (src == NULL) { - src = IP6_ADDR_ANY; - } - else if (ip6_addr_isany(src)) { - src = ip6_select_source_address(netif, dest); - if ((src == NULL) || ip6_addr_isany(src)) { - /* No appropriate source address was found for this packet. */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n")); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - } - /* src cannot be NULL here */ - ip6_addr_copy(ip6hdr->src, *src); - - } else { - /* IP header already included in p */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(dest_addr, ip6hdr->dest); - dest = &dest_addr; - } - - IP6_STATS_INC(ip6.xmit); - - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); - ip6_debug_print(p); - -#if ENABLE_LOOPBACK - /* TODO implement loopback for v6 - if (ip6_addr_cmp(dest, netif_ip6_addr(0))) { - return netif_loop_output(netif, p, dest); - }*/ -#endif /* ENABLE_LOOPBACK */ -#if LWIP_IPV6_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { - return ip6_frag(p, netif, dest); - } -#endif /* LWIP_IPV6_FRAG */ - - LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()")); - return netif->output_ip6(netif, p, dest); -} - -/** - * Simple interface to ip6_output_if. It finds the outgoing network - * interface and calls upon ip6_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth) -{ - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - - /* pbufs passed to IPv6 must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - if (dest != IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(src_addr, ip6hdr->src); - ip6_addr_copy(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - return ip6_output_if(p, src, dest, hl, tc, nexth, netif); -} - - -#if LWIP_NETIF_HWADDRHINT -/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip6_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param addr_hint address hint pointer set to netif->addr_hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) -{ - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - err_t err; - - /* pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ - LWIP_ASSERT("p->ref == 1", p->ref == 1); - - if (dest != IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(src_addr, ip6hdr->src); - ip6_addr_copy(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - NETIF_SET_HWADDRHINT(netif, addr_hint); - err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - return err; -} -#endif /* LWIP_NETIF_HWADDRHINT*/ - -#if LWIP_IPV6_MLD -/** - * Add a hop-by-hop options header with a router alert option and padding. - * - * Used by MLD when sending a Multicast listener report/done message. - * - * @param p the packet to which we will prepend the options header - * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6) - * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD) - * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise - */ -err_t -ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value) -{ - struct ip6_hbh_hdr * hbh_hdr; - - /* Move pointer to make room for hop-by-hop options header. */ - if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - hbh_hdr = (struct ip6_hbh_hdr *)p->payload; - - /* Set fields. */ - hbh_hdr->_nexth = nexth; - hbh_hdr->_hlen = 0; - hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION; - hbh_hdr->_ra_opt_dlen = 2; - hbh_hdr->_ra_opt_data = value; - hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION; - hbh_hdr->_padn_opt_dlen = 0; - - return ERR_OK; -} -#endif /* LWIP_IPV6_MLD */ - -#if IP6_DEBUG -/* Print an IPv6 header by using LWIP_DEBUGF - * @param p an IPv6 packet, p->payload pointing to the IPv6 header - */ -void -ip6_debug_print(struct pbuf *p) -{ - struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; - - LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", - IP6H_V(ip6hdr), - IP6H_TC(ip6hdr), - IP6H_FL(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", - IP6H_PLEN(ip6hdr), - IP6H_NEXTH(ip6hdr), - IP6H_HOPLIM(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->src)), - IP6_ADDR_BLOCK2(&(ip6hdr->src)), - IP6_ADDR_BLOCK3(&(ip6hdr->src)), - IP6_ADDR_BLOCK4(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->src)), - IP6_ADDR_BLOCK6(&(ip6hdr->src)), - IP6_ADDR_BLOCK7(&(ip6hdr->src)), - IP6_ADDR_BLOCK8(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->dest)), - IP6_ADDR_BLOCK2(&(ip6hdr->dest)), - IP6_ADDR_BLOCK3(&(ip6hdr->dest)), - IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->dest)), - IP6_ADDR_BLOCK6(&(ip6hdr->dest)), - IP6_ADDR_BLOCK7(&(ip6hdr->dest)), - IP6_ADDR_BLOCK8(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP6_DEBUG */ - -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/ip6_addr.c b/external/badvpn_dns/lwip/src/core/ipv6/ip6_addr.c deleted file mode 100644 index 65d2798..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/ip6_addr.c +++ /dev/null @@ -1,251 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * Functions for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" - -/* used by IP6_ADDR_ANY in ip6_addr.h */ -const ip6_addr_t ip6_addr_any = { { 0ul, 0ul, 0ul, 0ul } }; - -#ifndef isprint -#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) -#define isprint(c) in_range(c, 0x20, 0x7f) -#define isdigit(c) in_range(c, '0', '9') -#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) -#define islower(c) in_range(c, 'a', 'z') -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') -#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10) -#endif - -/** - * Check whether "cp" is a valid ascii representation - * of an IPv6 address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * - * @param cp IPv6 address in ascii represenation (e.g. "FF01::1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ip6addr_aton(const char *cp, ip6_addr_t *addr) -{ - u32_t addr_index, zero_blocks, current_block_index, current_block_value; - const char * s; - - /* Count the number of colons, to count the number of blocks in a "::" sequence - zero_blocks may be 1 even if there are no :: sequences */ - zero_blocks = 8; - for (s = cp; *s != 0; s++) { - if (*s == ':') - zero_blocks--; - else if (!isxdigit(*s)) - break; - } - - /* parse each block */ - addr_index = 0; - current_block_index = 0; - current_block_value = 0; - for (s = cp; *s != 0; s++) { - if (*s == ':') { - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } - } - current_block_index++; - current_block_value = 0; - if (current_block_index > 7) { - /* address too long! */ - return 0; - } if (s[1] == ':') { - s++; - /* "::" found, set zeros */ - while (zero_blocks-- > 0) { - if (current_block_index & 0x1) { - addr_index++; - } - else { - if (addr) { - addr->addr[addr_index] = 0; - } - } - current_block_index++; - } - } - } else if (isxdigit(*s)) { - /* add current digit */ - current_block_value = (current_block_value << 4) + - (isdigit(*s) ? *s - '0' : - 10 + (islower(*s) ? *s - 'a' : *s - 'A')); - } else { - /* unexpected digit, space? CRLF? */ - break; - } - } - - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } - } - - /* convert to network byte order. */ - if (addr) { - for (addr_index = 0; addr_index < 4; addr_index++) { - addr->addr[addr_index] = htonl(addr->addr[addr_index]); - } - } - - if (current_block_index != 7) { - return 0; - } - - return 1; -} - -/** - * Convert numeric IPv6 address into ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip6 address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * represenation of addr - */ -char * -ip6addr_ntoa(const ip6_addr_t *addr) -{ - static char str[40]; - return ip6addr_ntoa_r(addr, str, 40); -} - -/** - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip6 address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char * -ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen) -{ - u32_t current_block_index, current_block_value; - s32_t zero_flag, i; - - i = 0; - zero_flag = 0; /* used to indicate a zero chain for "::' */ - - for (current_block_index = 0; current_block_index < 8; current_block_index++) { - /* get the current 16-bit block */ - current_block_value = htonl(addr->addr[current_block_index >> 1]); - if ((current_block_index & 0x1) == 0) { - current_block_value = current_block_value >> 16; - } - current_block_value &= 0xffff; - - if (current_block_value == 0) { - /* generate empty block "::" */ - if (!zero_flag) { - if (current_block_index > 0) { - zero_flag = 1; - buf[i++] = ':'; - if (i >= buflen) return NULL; - } - } - } - else { - if (current_block_index > 0) { - buf[i++] = ':'; - if (i >= buflen) return NULL; - } - - if ((current_block_value & 0xf000) == 0) { - zero_flag = 1; - } - else { - buf[i++] = xchar(((current_block_value & 0xf000) >> 12)); - zero_flag = 0; - if (i >= buflen) return NULL; - } - - if (((current_block_value & 0xf00) == 0) && (zero_flag)) { - /* do nothing */ - } - else { - buf[i++] = xchar(((current_block_value & 0xf00) >> 8)); - zero_flag = 0; - if (i >= buflen) return NULL; - } - - if (((current_block_value & 0xf0) == 0) && (zero_flag)) { - /* do nothing */ - } - else { - buf[i++] = xchar(((current_block_value & 0xf0) >> 4)); - zero_flag = 0; - if (i >= buflen) return NULL; - } - - buf[i++] = xchar((current_block_value & 0xf)); - if (i >= buflen) return NULL; - - zero_flag = 0; - } - } - - buf[i] = 0; - - return buf; -} -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/ip6_frag.c b/external/badvpn_dns/lwip/src/core/ipv6/ip6_frag.c deleted file mode 100644 index a43fd61..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/ip6_frag.c +++ /dev/null @@ -1,697 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" -#include "lwip/ip6_frag.h" -#include "lwip/ip6.h" -#include "lwip/icmp6.h" -#include "lwip/nd6.h" - -#include "lwip/pbuf.h" -#include "lwip/memp.h" -#include "lwip/stats.h" - -#include <string.h> - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IPv6 header, since it replaces - * the Fragment Header in memory in incoming fragments to keep - * track of the various fragments. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* static variables */ -static struct ip6_reassdata *reassdatagrams; -static u16_t ip6_reass_pbufcount; - -/* Forward declarations. */ -static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr); -#if IP_REASS_FREE_OLDEST -static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed); -#endif /* IP_REASS_FREE_OLDEST */ - -void -ip6_reass_tmr(void) -{ - struct ip6_reassdata *r, *tmp; - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - r = r->next; - } else { - /* reassembly timed out */ - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip6_reass_free_complete_datagram(tmp); - } - } -} - -/** - * Free a datagram (struct ip6_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip6_reass_pbufcount), - * sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - */ -static void -ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) -{ - struct ip6_reassdata *prev; - u16_t pbufs_freed = 0; - u8_t clen; - struct pbuf *p; - struct ip6_reass_helper *iprh; - -#if LWIP_ICMP6 - iprh = (struct ip6_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, move back to the original header (we are now pointing to Fragment header). */ - if (pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr)) { - LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); - } - else { - icmp6_time_exceeded(p, ICMP6_TE_FRAG); - } - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(p); - } -#endif /* LWIP_ICMP6 */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip6_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(pcur); - } - - /* Then, unchain the struct ip6_reassdata from the list and free it. */ - if (ipr == reassdatagrams) { - reassdatagrams = ipr->next; - } else { - prev = reassdatagrams; - while (prev != NULL) { - if (prev->next == ipr) { - break; - } - prev = prev->next; - } - if (prev != NULL) { - prev->next = ipr->next; - } - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* Finally, update number of pbufs in reassembly queue */ - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed); - ip6_reass_pbufcount -= pbufs_freed; -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram ipr is not freed! - * - * @param ipr ip6_reassdata for the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - */ -static void -ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed) -{ - struct ip6_reassdata *r, *oldest; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the current datagram! */ - do { - r = oldest = reassdatagrams; - while (r != NULL) { - if (r != ipr) { - if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - } - } - r = r->next; - } - if (oldest != NULL) { - ip6_reass_free_complete_datagram(oldest); - } - } while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL)); -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Reassembles incoming IPv6 fragments into an IPv6 datagram. - * - * @param p points to the IPv6 Fragment Header - * @param len the length of the payload (after Fragment Header) - * @return NULL if reassembly is incomplete, pbuf pointing to - * IPv6 Header if reassembly is complete - */ -struct pbuf * -ip6_reass(struct pbuf *p) -{ - struct ip6_reassdata *ipr, *ipr_prev; - struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; - struct ip6_frag_hdr * frag_hdr; - u16_t offset, len; - u8_t clen, valid = 1; - struct pbuf *q; - - IP6_FRAG_STATS_INC(ip6_frag.recv); - - frag_hdr = (struct ip6_frag_hdr *) p->payload; - - clen = pbuf_clen(p); - - offset = ntohs(frag_hdr->_fragment_offset); - - /* Calculate fragment length from IPv6 payload length. - * Adjust for headers before Fragment Header. - * And finally adjust by Fragment Header length. */ - len = ntohs(ip6_current_header()->_plen); - len -= ((u8_t*)p->payload - (u8_t*)ip6_current_header()) - IP6_HLEN; - len -= IP6_FRAG_HLEN; - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if ((frag_hdr->_identification == ipr->identification) && - ip6_addr_cmp(ip6_current_src_addr(), &(ipr->iphdr->src)) && - ip6_addr_cmp(ip6_current_dest_addr(), &(ipr->iphdr->dest))) { - IP6_FRAG_STATS_INC(ip6_frag.cachehit); - break; - } - ipr_prev = ipr; - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - /* Make room and try again. */ - ip6_reass_remove_oldest_datagram(ipr, clen); - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr == NULL) -#endif /* IP_REASS_FREE_OLDEST */ - { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } - - memset(ipr, 0, sizeof(struct ip6_reassdata)); - ipr->timer = IP_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - - /* Use the current IPv6 header for src/dest address reference. - * Eventually, we will replace it when we get the first fragment - * (it might be this one, in any case, it is done later). */ - ipr->iphdr = (struct ip6_hdr *)ip6_current_header(); - - /* copy the fragmented packet id. */ - ipr->identification = frag_hdr->_identification; - - /* copy the nexth field */ - ipr->nexth = frag_hdr->_nexth; - } - - /* Check if we are allowed to enqueue more datagrams. */ - if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - ip6_reass_remove_oldest_datagram(ipr, clen); - if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) -#endif /* IP_REASS_FREE_OLDEST */ - { - /* @todo: send ICMPv6 time exceeded here? */ - /* drop this pbuf */ - IP6_FRAG_STATS_INC(ip6_frag.memerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } - - /* Overwrite Fragment Header with our own helper struct. */ - iprh = (struct ip6_reass_helper *)p->payload; - iprh->next_pbuf = NULL; - iprh->start = (offset & IP6_FRAG_OFFSET_MASK); - iprh->end = (offset & IP6_FRAG_OFFSET_MASK) + len; - - /* find the right place to insert this pbuf */ - /* Iterate through until we either get to the end of the list (append), - * or we find on with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip6_reass_helper*)q->payload; - if (iprh->start < iprh_tmp->start) { -#if IP_REASS_CHECK_OVERLAP - if (iprh->end > iprh_tmp->start) { - /* fragment overlaps with following, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - if (iprh_prev != NULL) { - if (iprh->start < iprh_prev->end) { - /* fragment overlaps with previous, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } -#endif /* IP_REASS_CHECK_OVERLAP */ - /* the new pbuf should be inserted before this */ - iprh->next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ - iprh_prev->next_pbuf = p; - } else { - /* fragment with the lowest offset */ - ipr->p = p; - } - break; - } else if(iprh->start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; -#if IP_REASS_CHECK_OVERLAP - } else if(iprh->start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no gaps. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = p; - if (iprh_prev->end != iprh->start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = p; - } - } - - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time */ - ip6_reass_pbufcount += clen; - - /* Remember IPv6 header if this is the first fragment. */ - if (iprh->start == 0) { - ipr->iphdr = (struct ip6_hdr *)ip6_current_header(); - } - - /* If this is the last fragment, calculate total packet length. */ - if ((offset & IP6_FRAG_MORE_FLAG) == 0) { - ipr->datagram_len = iprh->end; - } - - /* Additional validity tests: we have received first and last fragment. */ - iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload; - if (iprh_tmp->start != 0) { - valid = 0; - } - if (ipr->datagram_len == 0) { - valid = 0; - } - - /* Final validity test: no gaps between current and last fragment. */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while ((q != NULL) && valid) { - iprh = (struct ip6_reass_helper*)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - - if (valid) { - /* All fragments have been received */ - - /* chain together the pbufs contained within the ip6_reassdata list. */ - iprh = (struct ip6_reass_helper*) ipr->p->payload; - while(iprh != NULL) { - - if (iprh->next_pbuf != NULL) { - /* Save next helper struct (will be hidden in next step). */ - iprh_tmp = (struct ip6_reass_helper*) iprh->next_pbuf->payload; - - /* hide the fragment header for every succeding fragment */ - pbuf_header(iprh->next_pbuf, -IP6_FRAG_HLEN); - pbuf_cat(ipr->p, iprh->next_pbuf); - } - else { - iprh_tmp = NULL; - } - - iprh = iprh_tmp; - } - - /* Adjust datagram length by adding header lengths. */ - ipr->datagram_len += ((u8_t*)ipr->p->payload - (u8_t*)ipr->iphdr) - + IP6_FRAG_HLEN - - IP6_HLEN ; - - /* Set payload length in ip header. */ - ipr->iphdr->_plen = htons(ipr->datagram_len); - - /* Get the furst pbuf. */ - p = ipr->p; - - /* Restore Fragment Header in first pbuf. Mark as "single fragment" - * packet. Restore nexth. */ - frag_hdr = (struct ip6_frag_hdr *) p->payload; - frag_hdr->_nexth = ipr->nexth; - frag_hdr->reserved = 0; - frag_hdr->_fragment_offset = 0; - frag_hdr->_identification = 0; - - /* release the sources allocate for the fragment queue entry */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", ipr_prev != NULL); - ipr_prev->next = ipr->next; - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* adjust the number of pbufs currently queued for reassembly. */ - ip6_reass_pbufcount -= pbuf_clen(p); - - /* Move pbuf back to IPv6 header. */ - if (pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr)) { - LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); - pbuf_free(p); - return NULL; - } - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - return NULL; - -nullreturn: - pbuf_free(p); - return NULL; -} - -#endif /* LWIP_IPV6 ^^ LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG - -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref* -ip6_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ip6_frag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip6_frag_free_pbuf_custom_ref(pcr); -} - -/** - * Fragment an IPv6 datagram if too large for the netif or path MTU. - * - * Chop the datagram in MTU sized chunks and send them in order - * by pointing PBUF_REFs into p - * - * @param p ipv6 packet to send - * @param netif the netif on which to send - * @param dest destination ipv6 address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest) -{ - struct ip6_hdr *original_ip6hdr; - struct ip6_hdr *ip6hdr; - struct ip6_frag_hdr * frag_hdr; - struct pbuf *rambuf; - struct pbuf *newpbuf; - static u32_t identification; - u16_t nfb; - u16_t left, cop; - u16_t mtu; - u16_t fragment_offset = 0; - u16_t last; - u16_t poff = IP6_HLEN; - u16_t newpbuflen = 0; - u16_t left_to_copy; - - identification++; - - original_ip6hdr = (struct ip6_hdr *)p->payload; - - mtu = nd6_get_destination_mtu(dest, netif); - - /* TODO we assume there are no options in the unfragmentable part (IPv6 header). */ - left = p->tot_len - IP6_HLEN; - - nfb = (mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK; - - while (left) { - last = (left <= nfb); - - /* Fill this fragment */ - cop = last ? left : nfb; - - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM); - if (rambuf == NULL) { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (p->len >= (IP6_HLEN + IP6_FRAG_HLEN))); - SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); - ip6hdr = (struct ip6_hdr *)rambuf->payload; - frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); - - /* Can just adjust p directly for needed offset. */ - p->payload = (u8_t *)p->payload + poff; - p->len -= poff; - p->tot_len -= poff; - - left_to_copy = cop; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; - /* Is this pbuf already empty? */ - if (!newpbuflen) { - p = p->next; - continue; - } - pcr = ip6_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); - if (newpbuf == NULL) { - ip6_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy -= newpbuflen; - if (left_to_copy) { - p = p->next; - } - } - poff = newpbuflen; - - /* Set headers */ - frag_hdr->_nexth = original_ip6hdr->_nexth; - frag_hdr->reserved = 0; - frag_hdr->_fragment_offset = htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)); - frag_hdr->_identification = htonl(identification); - - IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); - IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN); - - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - IP6_FRAG_STATS_INC(ip6_frag.xmit); - netif->output_ip6(netif, rambuf, dest); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); - left -= cop; - fragment_offset += cop; - } - return ERR_OK; -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/mld6.c b/external/badvpn_dns/lwip/src/core/ipv6/mld6.c deleted file mode 100644 index 1cb2dd9..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/mld6.c +++ /dev/null @@ -1,580 +0,0 @@ -/** - * @file - * - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -/* Based on igmp.c implementation of igmp v2 protocol */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mld6.h" -#include "lwip/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/memp.h" -#include "lwip/stats.h" - -#include <string.h> - - -/* - * MLD constants - */ -#define MLD6_HL 1 -#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500) - -#define MLD6_GROUP_NON_MEMBER 0 -#define MLD6_GROUP_DELAYING_MEMBER 1 -#define MLD6_GROUP_IDLE_MEMBER 2 - - -/* The list of joined groups. */ -static struct mld_group* mld_group_list; - - -/* Forward declarations. */ -static struct mld_group * mld6_new_group(struct netif *ifp, ip6_addr_t *addr); -static err_t mld6_free_group(struct mld_group *group); -static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); -static void mld6_send(struct mld_group *group, u8_t type); - - -/** - * Stop MLD processing on interface - * - * @param netif network interface on which stop MLD processing - */ -err_t -mld6_stop(struct netif *netif) -{ - struct mld_group *group = mld_group_list; - struct mld_group *prev = NULL; - struct mld_group *next; - - /* look for groups joined on this interface further down the list */ - while (group != NULL) { - next = group->next; - /* is it a group joined on this interface? */ - if (group->netif == netif) { - /* is it the first group of the list? */ - if (group == mld_group_list) { - mld_group_list = next; - } - /* is there a "previous" group defined? */ - if (prev != NULL) { - prev->next = next; - } - /* disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, &(group->group_address), MLD6_DEL_MAC_FILTER); - } - /* free group */ - memp_free(MEMP_MLD6_GROUP, group); - } else { - /* change the "previous" */ - prev = group; - } - /* move to "next" */ - group = next; - } - return ERR_OK; -} - -/** - * Report MLD memberships for this interface - * - * @param netif network interface on which report MLD memberships - */ -void -mld6_report_groups(struct netif *netif) -{ - struct mld_group *group = mld_group_list; - - while (group != NULL) { - if (group->netif == netif) { - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - } - group = group->next; - } -} - -/** - * Search for a group that is joined on a netif - * - * @param ifp the network interface for which to look - * @param addr the group ipv6 address to search for - * @return a struct mld_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct mld_group * -mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr) -{ - struct mld_group *group = mld_group_list; - - while (group != NULL) { - if ((group->netif == ifp) && (ip6_addr_cmp(&(group->group_address), addr))) { - return group; - } - group = group->next; - } - - return NULL; -} - - -/** - * create a new group - * - * @param ifp the network interface for which to create - * @param addr the new group ipv6 - * @return a struct mld_group*, - * NULL on memory error. - */ -static struct mld_group * -mld6_new_group(struct netif *ifp, ip6_addr_t *addr) -{ - struct mld_group *group; - - group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP); - if (group != NULL) { - group->netif = ifp; - ip6_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - group->next = mld_group_list; - - mld_group_list = group; - } - - return group; -} - -/** - * Remove a group in the mld_group_list and free - * - * @param group the group to remove - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -mld6_free_group(struct mld_group *group) -{ - err_t err = ERR_OK; - - /* Is it the first group? */ - if (mld_group_list == group) { - mld_group_list = group->next; - } else { - /* look for group further down the list */ - struct mld_group *tmpGroup; - for (tmpGroup = mld_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { - if (tmpGroup->next == group) { - tmpGroup->next = group->next; - break; - } - } - /* Group not find group */ - if (tmpGroup == NULL) - err = ERR_ARG; - } - /* free group */ - memp_free(MEMP_MLD6_GROUP, group); - - return err; -} - - -/** - * Process an input MLD message. Called by icmp6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -mld6_input(struct pbuf *p, struct netif *inp) -{ - struct mld_header * mld_hdr; - struct mld_group* group; - - MLD6_STATS_INC(mld6.recv); - - /* Check that mld header fits in packet. */ - if (p->len < sizeof(struct mld_header)) { - /* TODO debug message */ - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - MLD6_STATS_INC(mld6.drop); - return; - } - - mld_hdr = (struct mld_header *)p->payload; - - switch (mld_hdr->type) { - case ICMP6_TYPE_MLQ: /* Multicast listener query. */ - { - /* Is it a general query? */ - if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && - ip6_addr_isany(&(mld_hdr->multicast_address))) { - MLD6_STATS_INC(mld6.rx_general); - /* Report all groups, except all nodes group, and if-local groups. */ - group = mld_group_list; - while (group != NULL) { - if ((group->netif == inp) && - (!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && - (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - group = group->next; - } - } - else { - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_group); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* Schedule a report. */ - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - } - break; /* ICMP6_TYPE_MLQ */ - } - case ICMP6_TYPE_MLR: /* Multicast listener report. */ - { - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_report); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* If we are waiting to report, cancel it. */ - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - group->timer = 0; /* stopped */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - } - break; /* ICMP6_TYPE_MLR */ - } - case ICMP6_TYPE_MLD: /* Multicast listener done. */ - { - /* Do nothing, router will query us. */ - break; /* ICMP6_TYPE_MLD */ - } - default: - MLD6_STATS_INC(mld6.proterr); - MLD6_STATS_INC(mld6.drop); - break; - } - - pbuf_free(p); -} - -/** - * Join a group on a network interface. - * - * @param srcaddr ipv6 address of the network interface which should - * join a new group. If IP6_ADDR_ANY, join on all netifs - * @param groupaddr the ipv6 address of the group to join - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct mld_group *group; - struct netif *netif; - u8_t match; - u8_t i; - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we join this interface ? */ - match = 0; - if (ip6_addr_isany(srcaddr)) { - match = 1; - } - else { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_cmp(srcaddr, netif_ip6_addr(netif, i))) { - match = 1; - break; - } - } - } - if (match) { - /* find group or create a new one if not found */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group == NULL) { - /* Joining a new group. Create a new group entry. */ - group = mld6_new_group(netif, groupaddr); - if (group == NULL) { - return ERR_MEM; - } - - /* Activate this address on the MAC layer. */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, groupaddr, MLD6_ADD_MAC_FILTER); - } - - /* Report our membership. */ - MLD6_STATS_INC(mld6.tx_report); - mld6_send(group, ICMP6_TYPE_MLR); - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - } - - /* Increment group use */ - group->use++; - err = ERR_OK; - } - - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * Leave a group on a network interface. - * - * @param srcaddr ipv6 address of the network interface which should - * leave the group. If IP6_ISANY, leave on all netifs - * @param groupaddr the ipv6 address of the group to leave - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct mld_group *group; - struct netif *netif; - u8_t match; - u8_t i; - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we leave this interface ? */ - match = 0; - if (ip6_addr_isany(srcaddr)) { - match = 1; - } - else { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_cmp(srcaddr, netif_ip6_addr(netif, i))) { - match = 1; - break; - } - } - } - if (match) { - /* find group */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group != NULL) { - /* Leave if there is no other use of the group */ - if (group->use <= 1) { - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - MLD6_STATS_INC(mld6.tx_leave); - mld6_send(group, ICMP6_TYPE_MLD); - } - - /* Disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, groupaddr, MLD6_DEL_MAC_FILTER); - } - - /* Free the group */ - mld6_free_group(group); - } else { - /* Decrement group use */ - group->use--; - } - /* Leave on this interface */ - err = ERR_OK; - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - - -/** - * Periodic timer for mld processing. Must be called every - * MLD6_TMR_INTERVAL milliseconds (100). - * - * When a delaying member expires, a membership report is sent. - */ -void -mld6_tmr(void) -{ - struct mld_group *group = mld_group_list; - - while (group != NULL) { - if (group->timer > 0) { - group->timer--; - if (group->timer == 0) { - /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - MLD6_STATS_INC(mld6.tx_report); - mld6_send(group, ICMP6_TYPE_MLR); - group->group_state = MLD6_GROUP_IDLE_MEMBER; - } - } - } - group = group->next; - } -} - -/** - * Schedule a delayed membership report for a group - * - * @param group the mld_group for which "delaying" membership report - * should be sent - * @param maxresp the max resp delay provided in the query - */ -static void -mld6_delayed_report(struct mld_group *group, u16_t maxresp) -{ - /* Convert maxresp from milliseconds to tmr ticks */ - maxresp = maxresp / MLD6_TMR_INTERVAL; - if (maxresp == 0) { - maxresp = 1; - } - -#ifdef LWIP_RAND - /* Randomize maxresp. (if LWIP_RAND is supported) */ - maxresp = (LWIP_RAND() % (maxresp - 1)) + 1; -#endif /* LWIP_RAND */ - - /* Apply timer value if no report has been scheduled already. */ - if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) || - ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && - ((group->timer == 0) || (maxresp < group->timer)))) { - group->timer = maxresp; - group->group_state = MLD6_GROUP_DELAYING_MEMBER; - } -} - -/** - * Send a MLD message (report or done). - * - * An IPv6 hop-by-hop options header with a router alert option - * is prepended. - * - * @param group the group to report or quit - * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done) - */ -static void -mld6_send(struct mld_group *group, u8_t type) -{ - struct mld_header * mld_hdr; - struct pbuf * p; - ip6_addr_t * src_addr; - - /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr), PBUF_RAM); - if ((p == NULL) || (p->len < (sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr)))) { - /* We couldn't allocate a suitable pbuf. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - MLD6_STATS_INC(mld6.memerr); - return; - } - - /* Move to make room for Hop-by-hop options header. */ - if (pbuf_header(p, -IP6_HBH_HLEN)) { - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - return; - } - - /* Select our source address. */ - if (!ip6_addr_isvalid(netif_ip6_addr_state(group->netif, 0))) { - /* This is a special case, when we are performing duplicate address detection. - * We must join the multicast group, but we don't have a valid address yet. */ - src_addr = IP6_ADDR_ANY; - } else { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(group->netif, 0); - } - - /* MLD message header pointer. */ - mld_hdr = (struct mld_header *)p->payload; - - /* Set fields. */ - mld_hdr->type = type; - mld_hdr->code = 0; - mld_hdr->chksum = 0; - mld_hdr->max_resp_delay = 0; - mld_hdr->reserved = 0; - ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address)); - - mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, - src_addr, &(group->group_address)); - - /* Add hop-by-hop headers options: router alert with MLD value. */ - ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD); - - /* Send the packet out. */ - MLD6_STATS_INC(mld6.xmit); - ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), - MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, group->netif); - pbuf_free(p); -} - - - -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/ipv6/nd6.c b/external/badvpn_dns/lwip/src/core/ipv6/nd6.c deleted file mode 100644 index 480638e..0000000 --- a/external/badvpn_dns/lwip/src/core/ipv6/nd6.c +++ /dev/null @@ -1,1787 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/nd6.h" -#include "lwip/pbuf.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" -#include "lwip/mld6.h" -#include "lwip/stats.h" - -#include <string.h> - - -/* Router tables. */ -struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; -struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; -struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES]; -struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS]; - -/* Default values, can be updated by a RA message. */ -u32_t reachable_time = LWIP_ND6_REACHABLE_TIME; -u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* TODO implement this value in timer */ - -/* Index for cache entries. */ -static u8_t nd6_cached_neighbor_index; -static u8_t nd6_cached_destination_index; - -/* Multicast address holder. */ -static ip6_addr_t multicast_address; - -/* Static buffer to parse RA packet options (size of a prefix option, biggest option) */ -static u8_t nd6_ra_buffer[sizeof(struct prefix_option)]; - -/* Forward declarations. */ -static s8_t nd6_find_neighbor_cache_entry(ip6_addr_t * ip6addr); -static s8_t nd6_new_neighbor_cache_entry(void); -static void nd6_free_neighbor_cache_entry(s8_t i); -static s8_t nd6_find_destination_cache_entry(ip6_addr_t * ip6addr); -static s8_t nd6_new_destination_cache_entry(void); -static s8_t nd6_is_prefix_in_netif(ip6_addr_t * ip6addr, struct netif * netif); -static s8_t nd6_get_router(ip6_addr_t * router_addr, struct netif * netif); -static s8_t nd6_new_router(ip6_addr_t * router_addr, struct netif * netif); -static s8_t nd6_get_onlink_prefix(ip6_addr_t * prefix, struct netif * netif); -static s8_t nd6_new_onlink_prefix(ip6_addr_t * prefix, struct netif * netif); - -#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 -#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 -static void nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags); -static void nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags); -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -static void nd6_send_rs(struct netif * netif); -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -#if LWIP_ND6_QUEUEING -static void nd6_free_q(struct nd6_q_entry *q); -#else /* LWIP_ND6_QUEUEING */ -#define nd6_free_q(q) pbuf_free(q) -#endif /* LWIP_ND6_QUEUEING */ -static void nd6_send_q(s8_t i); - - -/** - * Process an incoming neighbor discovery message - * - * @param p the nd packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -nd6_input(struct pbuf *p, struct netif *inp) -{ - u8_t msg_type; - s8_t i; - - ND6_STATS_INC(nd6.recv); - - msg_type = *((u8_t *)p->payload); - switch (msg_type) { - case ICMP6_TYPE_NA: /* Neighbor Advertisement. */ - { - struct na_header * na_hdr; - struct lladdr_option * lladdr_opt; - - /* Check that na header fits in packet. */ - if (p->len < (sizeof(struct na_header))) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - na_hdr = (struct na_header *)p->payload; - - /* Unsolicited NA?*/ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* This is an unsolicited NA. - * link-layer changed? - * part of DAD mechanism? */ - - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); - -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* If the target address matches this netif, it is a DAD response. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { - /* We are using a duplicate address. */ - netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID); - -#if LWIP_IPV6_MLD - /* Leave solicited node multicast group. */ - ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(inp, i)->addr[3]); - mld6_leavegroup(netif_ip6_addr(inp, i), &multicast_address); -#endif /* LWIP_IPV6_MLD */ - - - - -#if LWIP_IPV6_AUTOCONFIG - /* Check to see if this address was autoconfigured. */ - if (!ip6_addr_islinklocal(ip6_current_dest_addr())) { - i = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp); - if (i >= 0) { - /* Mark this prefix as duplicate, so that we don't use it - * to generate this address again. */ - prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE; - } - } -#endif /* LWIP_IPV6_AUTOCONFIG */ - - pbuf_free(p); - return; - } - } -#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ - - /* This is an unsolicited NA, most likely there was a LLADDR change. */ - i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr()); - if (i >= 0) { - if (na_hdr->flags & ND6_FLAG_OVERRIDE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - } - } - else { - /* This is a solicited NA. - * neighbor address resolution response? - * neighbor unreachability detection response? */ - - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); - - /* Find the cache entry corresponding to this na. */ - i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr()); - if (i < 0) { - /* We no longer care about this target address. drop it. */ - pbuf_free(p); - return; - } - - /* Update cache entry. */ - neighbor_cache[i].netif = inp; - neighbor_cache[i].counter.reachable_time = reachable_time; - if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || - (neighbor_cache[i].state == ND6_INCOMPLETE)) { - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - neighbor_cache[i].state = ND6_REACHABLE; - - /* Send queued packets, if any. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - } - - break; /* ICMP6_TYPE_NA */ - } - case ICMP6_TYPE_NS: /* Neighbor solicitation. */ - { - struct ns_header * ns_hdr; - struct lladdr_option * lladdr_opt; - u8_t accepted; - - /* Check that ns header fits in packet. */ - if (p->len < sizeof(struct ns_header)) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ns_hdr = (struct ns_header *)p->payload; - - /* Check if there is a link-layer address provided. Only point to it if in this buffer. */ - lladdr_opt = NULL; - if (p->len >= (sizeof(struct ns_header) + sizeof(struct lladdr_option))) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - } - - /* Check if the target address is configured on the receiving netif. */ - accepted = 0; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || - (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && - ip6_addr_isany(ip6_current_src_addr()))) && - ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { - accepted = 1; - break; - } - } - - /* NS not for us? */ - if (!accepted) { - pbuf_free(p); - return; - } - - /* Check for ANY address in src (DAD algorithm). */ - if (ip6_addr_isany(ip6_current_src_addr())) { - /* Sender is validating this address. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { - /* Send a NA back so that the sender does not use this address. */ - nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST); - if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) { - /* We shouldn't use this address either. */ - netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID); - } - } - } - } - else { - /* Sender is trying to resolve our address. */ - /* Verify that they included their own link-layer address. */ - if (lladdr_opt == NULL) { - /* Not a valid message. */ - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); - if ( i>= 0) { - /* We already have a record for the solicitor. */ - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - - /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; - } - } - else - { - /* Add their IPv6 address and link-layer address to neighbor cache. - * We will need it at least to send a unicast NA message, but most - * likely we will also be communicating with this node soon. */ - i = nd6_new_neighbor_cache_entry(); - if (i < 0) { - /* We couldn't assign a cache entry for this neighbor. - * we won't be able to reply. drop it. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; - } - - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(ns_hdr->target_address)); - - /* Send back a NA for us. Allocate the reply pbuf. */ - nd6_send_na(inp, ip6_current_dest_addr(), ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE); - } - - break; /* ICMP6_TYPE_NS */ - } - case ICMP6_TYPE_RA: /* Router Advertisement. */ - { - struct ra_header * ra_hdr; - u8_t * buffer; /* Used to copy options. */ - u16_t offset; - - /* Check that RA header fits in packet. */ - if (p->len < sizeof(struct ra_header)) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ra_hdr = (struct ra_header *)p->payload; - - /* If we are sending RS messages, stop. */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - inp->rs_count = 0; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - - /* Get the matching default router entry. */ - i = nd6_get_router(ip6_current_src_addr(), inp); - if (i < 0) { - /* Create a new router entry. */ - i = nd6_new_router(ip6_current_src_addr(), inp); - } - - if (i < 0) { - /* Could not create a new router entry. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Re-set invalidation timer. */ - default_router_list[i].invalidation_timer = ra_hdr->router_lifetime; - - /* Re-set default timer values. */ -#if LWIP_ND6_ALLOW_RA_UPDATES - if (ra_hdr->retrans_timer > 0) { - retrans_timer = ra_hdr->retrans_timer; - } - if (ra_hdr->reachable_time > 0) { - reachable_time = ra_hdr->reachable_time; - } -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - - /* TODO set default hop limit... */ - /* ra_hdr->current_hop_limit;*/ - - /* Update flags in local entry (incl. preference). */ - default_router_list[i].flags = ra_hdr->flags; - - /* Offset to options. */ - offset = sizeof(struct ra_header); - - /* Process each option. */ - while ((p->tot_len - offset) > 0) { - if (p->len == p->tot_len) { - /* no need to copy from contiguous pbuf */ - buffer = &((u8_t*)p->payload)[offset]; - } else { - buffer = nd6_ra_buffer; - pbuf_copy_partial(p, buffer, sizeof(struct prefix_option), offset); - } - switch (buffer[0]) { - case ND6_OPTION_TYPE_SOURCE_LLADDR: - { - struct lladdr_option * lladdr_opt; - lladdr_opt = (struct lladdr_option *)buffer; - if ((default_router_list[i].neighbor_entry != NULL) && - (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) { - SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len); - default_router_list[i].neighbor_entry->state = ND6_REACHABLE; - default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time; - } - break; - } - case ND6_OPTION_TYPE_MTU: - { - struct mtu_option * mtu_opt; - mtu_opt = (struct mtu_option *)buffer; - if (mtu_opt->mtu >= 1280) { -#if LWIP_ND6_ALLOW_RA_UPDATES - inp->mtu = mtu_opt->mtu; -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - } - break; - } - case ND6_OPTION_TYPE_PREFIX_INFO: - { - struct prefix_option * prefix_opt; - prefix_opt = (struct prefix_option *)buffer; - - if (prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) { - /* Add to on-link prefix list. */ - - /* Get a memory-aligned copy of the prefix. */ - ip6_addr_set(ip6_current_dest_addr(), &(prefix_opt->prefix)); - - /* find cache entry for this prefix. */ - i = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp); - if (i < 0) { - /* Create a new cache entry. */ - i = nd6_new_onlink_prefix(ip6_current_dest_addr(), inp); - } - if (i >= 0) { - prefix_list[i].invalidation_timer = prefix_opt->valid_lifetime; - -#if LWIP_IPV6_AUTOCONFIG - if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) { - /* Mark prefix as autonomous, so that address autoconfiguration can take place. - * Only OR flag, so that we don't over-write other flags (such as ADDRESS_DUPLICATE)*/ - prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_AUTONOMOUS; - } -#endif /* LWIP_IPV6_AUTOCONFIG */ - } - } - - break; - } - case ND6_OPTION_TYPE_ROUTE_INFO: - { - /* TODO implement preferred routes. - struct route_option * route_opt; - route_opt = (struct route_option *)buffer;*/ - - break; - } - default: - /* Unrecognized option, abort. */ - ND6_STATS_INC(nd6.proterr); - break; - } - offset += 8 * ((u16_t)buffer[1]); - } - - break; /* ICMP6_TYPE_RA */ - } - case ICMP6_TYPE_RD: /* Redirect */ - { - struct redirect_header * redir_hdr; - struct lladdr_option * lladdr_opt; - - /* Check that Redir header fits in packet. */ - if (p->len < sizeof(struct redirect_header)) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - redir_hdr = (struct redirect_header *)p->payload; - - lladdr_opt = NULL; - if (p->len >= (sizeof(struct redirect_header) + sizeof(struct lladdr_option))) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header)); - } - - /* Copy original destination address to current source address, to have an aligned copy. */ - ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->destination_address)); - - /* Find dest address in cache */ - i = nd6_find_destination_cache_entry(ip6_current_src_addr()); - if (i < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Set the new target address. */ - ip6_addr_set(&(destination_cache[i].next_hop_addr), &(redir_hdr->target_address)); - - /* If Link-layer address of other router is given, try to add to neighbor cache. */ - if (lladdr_opt != NULL) { - if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) { - /* Copy target address to current source address, to have an aligned copy. */ - ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->target_address)); - - i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); - if (i < 0) { - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; - } - } - if (i >= 0) { - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; - } - } - } - } - break; /* ICMP6_TYPE_RD */ - } - case ICMP6_TYPE_PTB: /* Packet too big */ - { - struct icmp6_hdr *icmp6hdr; /* Packet too big message */ - struct ip6_hdr * ip6hdr; /* IPv6 header of the packet which caused the error */ - - /* Check that ICMPv6 header + IPv6 header fit in payload */ - if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) { - /* drop short packets */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr)); - - /* Copy original destination address to current source address, to have an aligned copy. */ - ip6_addr_set(ip6_current_src_addr(), &(ip6hdr->dest)); - - /* Look for entry in destination cache. */ - i = nd6_find_destination_cache_entry(ip6_current_src_addr()); - if (i < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Change the Path MTU. */ - destination_cache[i].pmtu = icmp6hdr->data; - - break; /* ICMP6_TYPE_PTB */ - } - - default: - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - break; /* default */ - } - - pbuf_free(p); -} - - -/** - * Periodic timer for Neighbor discovery functions: - * - * - Update neighbor reachability states - * - Update destination cache entries age - * - Update invalidation timers of default routers and on-link prefixes - * - Perform duplicate address detection (DAD) for our addresses - * - Send router solicitations - */ -void -nd6_tmr(void) -{ - s8_t i, j; - struct netif * netif; - - /* Process neighbor entries. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - switch (neighbor_cache[i].state) { - case ND6_INCOMPLETE: - if (neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } - else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST); - } - break; - case ND6_REACHABLE: - /* Send queued packets, if any are left. Should have been sent already. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) { - /* Change to stale state. */ - neighbor_cache[i].state = ND6_STALE; - neighbor_cache[i].counter.stale_time = 0; - } - else { - neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL; - } - break; - case ND6_STALE: - neighbor_cache[i].counter.stale_time += ND6_TMR_INTERVAL; - break; - case ND6_DELAY: - if (neighbor_cache[i].counter.delay_time <= ND6_TMR_INTERVAL) { - /* Change to PROBE state. */ - neighbor_cache[i].state = ND6_PROBE; - neighbor_cache[i].counter.probes_sent = 0; - } - else { - neighbor_cache[i].counter.delay_time -= ND6_TMR_INTERVAL; - } - break; - case ND6_PROBE: - if (neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } - else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), 0); - } - break; - case ND6_NO_ENTRY: - default: - /* Do nothing. */ - break; - } - } - - /* Process destination entries. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - destination_cache[i].age++; - } - - /* Process router entries. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (default_router_list[i].neighbor_entry != NULL) { - /* Active entry. */ - if (default_router_list[i].invalidation_timer > 0) { - default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - } - if (default_router_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) { - /* Less than 1 second remainig. Clear this entry. */ - default_router_list[i].neighbor_entry->isrouter = 0; - default_router_list[i].neighbor_entry = NULL; - default_router_list[i].invalidation_timer = 0; - default_router_list[i].flags = 0; - } - } - } - - /* Process prefix entries. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if (prefix_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) { - prefix_list[i].invalidation_timer = 0; - } - if ((prefix_list[i].invalidation_timer > 0) && - (prefix_list[i].netif != NULL)) { - prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - -#if LWIP_IPV6_AUTOCONFIG - /* Initiate address autoconfiguration for this prefix, if conditions are met. */ - if (prefix_list[i].netif->ip6_autoconfig_enabled && - (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) && - !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) { - /* Try to get an address on this netif that is invalid. - * Skip 0 index (link-local address) */ - for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) { - if (netif_ip6_addr_state(prefix_list[i].netif, j) == IP6_ADDRESS_STATE_INVALID) { - /* Generate an address using this prefix and interface ID from link-local address. */ - prefix_list[i].netif->ip6_addr[j].addr[0] = prefix_list[i].prefix.addr[0]; - prefix_list[i].netif->ip6_addr[j].addr[1] = prefix_list[i].prefix.addr[1]; - prefix_list[i].netif->ip6_addr[j].addr[2] = prefix_list[i].netif->ip6_addr[0].addr[2]; - prefix_list[i].netif->ip6_addr[j].addr[3] = prefix_list[i].netif->ip6_addr[0].addr[3]; - - /* Mark it as tentative (DAD will be performed if configured). */ - netif_ip6_addr_set_state(prefix_list[i].netif, j, IP6_ADDR_TENTATIVE); - - /* Mark this prefix with ADDRESS_GENERATED, so that we don't try again. */ - prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED; - - /* Exit loop. */ - break; - } - } - } -#endif /* LWIP_IPV6_AUTOCONFIG */ - } - } - - - /* Process our own addresses, if DAD configured. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (ip6_addr_istentative(netif->ip6_addr_state[i])) { - if ((netif->ip6_addr_state[i] & 0x07) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { - /* No NA received in response. Mark address as valid. */ - netif->ip6_addr_state[i] = IP6_ADDR_PREFERRED; - /* TODO implement preferred and valid lifetimes. */ - } - else if (netif->flags & NETIF_FLAG_UP) { -#if LWIP_IPV6_MLD - if ((netif->ip6_addr_state[i] & 0x07) == 0) { - /* Join solicited node multicast group. */ - ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, i)->addr[3]); - mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address); - } -#endif /* LWIP_IPV6_MLD */ - /* Send a NS for this address. */ - nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST); - (netif->ip6_addr_state[i])++; - /* TODO send max 1 NS per tmr call? enable return*/ - /*return;*/ - } - } - } - } - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send router solicitation messages, if necessary. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - if ((netif->rs_count > 0) && (netif->flags & NETIF_FLAG_UP)) { - nd6_send_rs(netif); - netif->rs_count--; - } - } -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -} - -/** - * Send a neighbor solicitation message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) -{ - struct ns_header * ns_hdr; - struct lladdr_option * lladdr_opt; - struct pbuf * p; - ip6_addr_t * src_addr; - - if (ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(netif, 0); - } else { - src_addr = IP6_ADDR_ANY; - } - - /* Allocate a packet. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + sizeof(struct lladdr_option), PBUF_RAM); - if ((p == NULL) || (p->len < (sizeof(struct ns_header) + sizeof(struct lladdr_option)))) { - /* We couldn't allocate a suitable pbuf for the ns. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - ns_hdr = (struct ns_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - - ns_hdr->type = ICMP6_TYPE_NS; - ns_hdr->code = 0; - ns_hdr->chksum = 0; - ns_hdr->reserved = 0; - ip6_addr_set(&(ns_hdr->target_address), target_addr); - - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - target_addr = &multicast_address; - } - - ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - target_addr); - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, (src_addr == IP6_ADDR_ANY) ? NULL : src_addr, target_addr, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -/** - * Send a neighbor advertisement message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) -{ - struct na_header * na_hdr; - struct lladdr_option * lladdr_opt; - struct pbuf * p; - ip6_addr_t * src_addr; - ip6_addr_t * dest_addr; - - /* Use link-local address as source address. */ - /* src_addr = &(netif->ip6_addr[0]); */ - /* Use target address as source address. */ - src_addr = target_addr; - - /* Allocate a packet. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + sizeof(struct lladdr_option), PBUF_RAM); - if ((p == NULL) || (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option)))) { - /* We couldn't allocate a suitable pbuf for the ns. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - na_hdr = (struct na_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - na_hdr->type = ICMP6_TYPE_NA; - na_hdr->code = 0; - na_hdr->chksum = 0; - na_hdr->flags = flags & 0xf0; - na_hdr->reserved[0] = 0; - na_hdr->reserved[1] = 0; - na_hdr->reserved[2] = 0; - ip6_addr_set(&(na_hdr->target_address), target_addr); - - lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR; - lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - dest_addr = &multicast_address; - } - else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) { - ip6_addr_set_allnodes_linklocal(&multicast_address); - dest_addr = &multicast_address; - } - else { - dest_addr = ip6_current_src_addr(); - } - - na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - dest_addr); - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, src_addr, dest_addr, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -/** - * Send a router solicitation message - * - * @param netif the netif on which to send the message - */ -static void -nd6_send_rs(struct netif * netif) -{ - struct rs_header * rs_hdr; - struct lladdr_option * lladdr_opt; - struct pbuf * p; - ip6_addr_t * src_addr; - u16_t packet_len; - - /* Link-local source address, or unspecified address? */ - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { - src_addr = netif_ip6_addr(netif, 0); - } - else { - src_addr = IP6_ADDR_ANY; - } - - /* Generate the all routers target address. */ - ip6_addr_set_allrouters_linklocal(&multicast_address); - - /* Allocate a packet. */ - packet_len = sizeof(struct rs_header); - if (src_addr != IP6_ADDR_ANY) { - packet_len += sizeof(struct lladdr_option); - } - p = pbuf_alloc(PBUF_IP, packet_len, PBUF_RAM); - if ((p == NULL) || (p->len < packet_len)) { - /* We couldn't allocate a suitable pbuf for the ns. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - rs_hdr = (struct rs_header *)p->payload; - - rs_hdr->type = ICMP6_TYPE_RS; - rs_hdr->code = 0; - rs_hdr->chksum = 0; - rs_hdr->reserved = 0; - - if (src_addr != IP6_ADDR_ANY) { - /* Include our hw address. */ - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header)); - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - } - - rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - &multicast_address); - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, src_addr, &multicast_address, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -/** - * Search for a neighbor cache entry - * - * @param ip6addr the IPv6 address of the neighbor - * @return The neighbor cache entry index that matched, -1 if no - * entry is found - */ -static s8_t -nd6_find_neighbor_cache_entry(ip6_addr_t * ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) { - return i; - } - } - return -1; -} - -/** - * Create a new neighbor cache entry. - * - * If no unused entry is found, will try to recycle an old entry - * according to ad-hoc "age" heuristic. - * - * @return The neighbor cache entry index that was created, -1 if no - * entry could be created - */ -static s8_t -nd6_new_neighbor_cache_entry(void) -{ - s8_t i; - s8_t j; - u32_t time; - - - /* First, try to find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (neighbor_cache[i].state == ND6_NO_ENTRY) { - return i; - } - } - - /* We need to recycle an entry. in general, do not recycle if it is a router. */ - - /* Next, try to find a Stale entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_STALE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Probe entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_PROBE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Delayed entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_DELAY) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find the oldest reachable entry. */ - time = 0xfffffffful; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_REACHABLE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.reachable_time < time) { - j = i; - time = neighbor_cache[i].counter.reachable_time; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry without queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ( - (neighbor_cache[i].q == NULL) && - (neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry with queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* No more entries to try. */ - return -1; -} - -/** - * Will free any resources associated with a neighbor cache - * entry, and will mark it as unused. - * - * @param i the neighbor cache entry index to free - */ -static void -nd6_free_neighbor_cache_entry(s8_t i) -{ - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - - /* Free any queued packets. */ - if (neighbor_cache[i].q != NULL) { - nd6_free_q(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } - - neighbor_cache[i].state = ND6_NO_ENTRY; - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = NULL; - neighbor_cache[i].counter.reachable_time = 0; - ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address)); -} - -/** - * Search for a destination cache entry - * - * @param ip6addr the IPv6 address of the destination - * @return The destination cache entry index that matched, -1 if no - * entry is found - */ -static s8_t -nd6_find_destination_cache_entry(ip6_addr_t * ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) { - return i; - } - } - return -1; -} - -/** - * Create a new destination cache entry. If no unused entry is found, - * will recycle oldest entry. - * - * @return The destination cache entry index that was created, -1 if no - * entry was created - */ -static s8_t -nd6_new_destination_cache_entry(void) -{ - s8_t i, j; - u32_t age; - - /* Find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_isany(&(destination_cache[i].destination_addr))) { - return i; - } - } - - /* Find oldest entry. */ - age = 0; - j = LWIP_ND6_NUM_DESTINATIONS - 1; - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (destination_cache[i].age > age) { - j = i; - } - } - - return j; -} - -/** - * Determine whether an address matches an on-link prefix. - * - * @param ip6addr the IPv6 address to match - * @return 1 if the address is on-link, 0 otherwise - */ -static s8_t -nd6_is_prefix_in_netif(ip6_addr_t * ip6addr, struct netif * netif) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if ((prefix_list[i].netif == netif) && - (prefix_list[i].invalidation_timer > 0) && - ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { - return 1; - } - } - /* Check to see if address prefix matches a (manually?) configured address. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { - return 1; - } - } - return 0; -} - -/** - * Select a default router for a destination. - * - * @param ip6addr the destination address - * @param netif the netif for the outgoing packet, if known - * @return the default router entry index, or -1 if no suitable - * router is found - */ -s8_t -nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif) -{ - s8_t i; - /* last_router is used for round-robin router selection (as recommended - * in RFC). This is more robust in case one router is not reachable, - * we are not stuck trying to resolve it. */ - static s8_t last_router; - (void)ip6addr; /* TODO match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */ - - /* TODO: implement default router preference */ - - /* Look for reachable routers. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (++last_router >= LWIP_ND6_NUM_ROUTERS) { - last_router = 0; - } - if ((default_router_list[i].neighbor_entry != NULL) && - (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) && - (default_router_list[i].invalidation_timer > 0) && - (default_router_list[i].neighbor_entry->state == ND6_REACHABLE)) { - return i; - } - } - - /* Look for router in other reachability states, but still valid according to timer. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (++last_router >= LWIP_ND6_NUM_ROUTERS) { - last_router = 0; - } - if ((default_router_list[i].neighbor_entry != NULL) && - (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) && - (default_router_list[i].invalidation_timer > 0)) { - return i; - } - } - - /* Look for any router for which we have any information at all. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (++last_router >= LWIP_ND6_NUM_ROUTERS) { - last_router = 0; - } - if (default_router_list[i].neighbor_entry != NULL && - (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1)) { - return i; - } - } - - /* no suitable router found. */ - return -1; -} - -/** - * Find an entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is found, if known - * @return the index of the router entry, or -1 if not found - */ -static s8_t -nd6_get_router(ip6_addr_t * router_addr, struct netif * netif) -{ - s8_t i; - - /* Look for router. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if ((default_router_list[i].neighbor_entry != NULL) && - ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) && - ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) { - return i; - } - } - - /* router not found. */ - return -1; -} - -/** - * Create a new entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is connected, if known - * @return the index on the router table, or -1 if could not be created - */ -static s8_t -nd6_new_router(ip6_addr_t * router_addr, struct netif * netif) -{ - s8_t router_index; - s8_t neighbor_index; - - /* Do we have a neighbor entry for this router? */ - neighbor_index = nd6_find_neighbor_cache_entry(router_addr); - if (neighbor_index < 0) { - /* Create a neighbor entry for this router. */ - neighbor_index = nd6_new_neighbor_cache_entry(); - if (neighbor_index < 0) { - /* Could not create neighbor entry for this router. */ - return -1; - } - ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr); - neighbor_cache[neighbor_index].netif = netif; - neighbor_cache[neighbor_index].q = NULL; - neighbor_cache[neighbor_index].state = ND6_INCOMPLETE; - neighbor_cache[neighbor_index].counter.probes_sent = 0; - } - - /* Mark neighbor as router. */ - neighbor_cache[neighbor_index].isrouter = 1; - - /* Look for empty entry. */ - for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) { - if (default_router_list[router_index].neighbor_entry == NULL) { - default_router_list[router_index].neighbor_entry = &(neighbor_cache[neighbor_index]); - return router_index; - } - } - - /* Could not create a router entry. */ - - /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */ - neighbor_cache[neighbor_index].isrouter = 0; - - /* router not found. */ - return -1; -} - -/** - * Find the cached entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not found - */ -static s8_t -nd6_get_onlink_prefix(ip6_addr_t * prefix, struct netif * netif) -{ - s8_t i; - - /* Look for prefix in list. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && - (prefix_list[i].netif == netif)) { - return i; - } - } - - /* Entry not available. */ - return -1; -} - -/** - * Creates a new entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not created - */ -static s8_t -nd6_new_onlink_prefix(ip6_addr_t * prefix, struct netif * netif) -{ - s8_t i; - - /* Create new entry. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((prefix_list[i].netif == NULL) || - (prefix_list[i].invalidation_timer == 0)) { - /* Found empty prefix entry. */ - prefix_list[i].netif = netif; - ip6_addr_set(&(prefix_list[i].prefix), prefix); -#if LWIP_IPV6_AUTOCONFIG - prefix_list[i].flags = 0; -#endif - return i; - } - } - - /* Entry not available. */ - return -1; -} - -/** - * Determine the next hop for a destination. Will determine if the - * destination is on-link, else a suitable on-link router is selected. - * - * The last entry index is cached for fast entry search. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the neighbor cache entry for the next hop, ERR_RTE if no - * suitable next hop was found, ERR_MEM if no cache entry - * could be created - */ -s8_t -nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) -{ - s8_t i; - -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - u8_t addr_hint = *(netif->addr_hint); - if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { - nd6_cached_destination_index = addr_hint; - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look for ip6addr in destination cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - /* the cached entry index is the right one! */ - /* do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - /* Search destination cache. */ - i = nd6_find_destination_cache_entry(ip6addr); - if (i >= 0) { - /* found destination entry. make it our new cached index. */ - nd6_cached_destination_index = i; - } - else { - /* Not found. Create a new destination entry. */ - i = nd6_new_destination_cache_entry(); - if (i >= 0) { - /* got new destination entry. make it our new cached index. */ - nd6_cached_destination_index = i; - } else { - /* Could not create a destination cache entry. */ - return ERR_MEM; - } - - /* Copy dest address to destination cache. */ - ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); - - /* Now find the next hop. is it a neighbor? */ - if (ip6_addr_islinklocal(ip6addr) || - nd6_is_prefix_in_netif(ip6addr, netif)) { - /* Destination in local link. */ - destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); - } - else { - /* We need to select a router. */ - i = nd6_select_router(ip6addr, netif); - if (i < 0) { - /* No router found. */ - ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); - return ERR_RTE; - } - destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; /* Start with netif mtu, correct through ICMPv6 if necessary */ - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); - } - } - } - -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - *(netif->addr_hint) = nd6_cached_destination_index; - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look in neighbor cache for the next-hop address. */ - if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr), - &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - /* Cache hit. */ - /* Do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr)); - if (i >= 0) { - /* Found a matching record, make it new cached entry. */ - nd6_cached_neighbor_index = i; - } - else { - /* Neighbor not in cache. Make a new entry. */ - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - /* got new neighbor entry. make it our new cached index. */ - nd6_cached_neighbor_index = i; - } else { - /* Could not create a neighbor cache entry. */ - return ERR_MEM; - } - - /* Initialize fields. */ - ip6_addr_copy(neighbor_cache[i].next_hop_address, - destination_cache[nd6_cached_destination_index].next_hop_addr); - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = netif; - neighbor_cache[i].state = ND6_INCOMPLETE; - neighbor_cache[i].counter.probes_sent = 0; - } - } - - /* Reset this destination's age. */ - destination_cache[nd6_cached_destination_index].age = 0; - - return nd6_cached_neighbor_index; -} - -/** - * Queue a packet for a neighbor. - * - * @param neighbor_index the index in the neighbor cache table - * @param q packet to be queued - * @return ERR_OK if succeeded, ERR_MEM if out of memory - */ -err_t -nd6_queue_packet(s8_t neighbor_index, struct pbuf * q) -{ - err_t result = ERR_MEM; - struct pbuf *p; - int copy_needed = 0; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *new_entry, *r; -#endif /* LWIP_ND6_QUEUEING */ - - if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { - return ERR_ARG; - } - - /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but - * to copy the whole queue into a new PBUF_RAM (see bug #11400) - * PBUF_ROMs can be left as they are, since ROM must not get changed. */ - p = q; - while (p) { - if(p->type != PBUF_ROM) { - copy_needed = 1; - break; - } - p = p->next; - } - if(copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); - while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ -#if LWIP_ND6_QUEUEING - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); -#else /* LWIP_ND6_QUEUEING */ - pbuf_free(neighbor_cache[neighbor_index].q); - neighbor_cache[neighbor_index].q = NULL; -#endif /* LWIP_ND6_QUEUEING */ - p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); - } - if(p != NULL) { - if (pbuf_copy(p, q) != ERR_OK) { - pbuf_free(p); - p = NULL; - } - } - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet was copied/ref'd? */ - if (p != NULL) { - /* queue packet ... */ -#if LWIP_ND6_QUEUEING - /* allocate a new nd6 queue entry */ - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - } - if (new_entry != NULL) { - new_entry->next = NULL; - new_entry->p = p; - if(neighbor_cache[neighbor_index].q != NULL) { - /* queue was already existent, append the new entry to the end */ - r = neighbor_cache[neighbor_index].q; - while (r->next != NULL) { - r = r->next; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - neighbor_cache[neighbor_index].q = new_entry; - } - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; - } else { - /* the pool MEMP_ND6_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p)); - /* { result == ERR_MEM } through initialization */ - } -#else /* LWIP_ND6_QUEUEING */ - /* Queue a single packet. If an older packet is already queued, free it as per RFC. */ - if (neighbor_cache[neighbor_index].q != NULL) { - pbuf_free(neighbor_cache[neighbor_index].q); - } - neighbor_cache[neighbor_index].q = p; - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; -#endif /* LWIP_ND6_QUEUEING */ - } else { - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q)); - /* { result == ERR_MEM } through initialization */ - } - - return result; -} - -#if LWIP_ND6_QUEUEING -/** - * Free a complete queue of nd6 q entries - * - * @param q a queue of nd6_q_entry to free - */ -static void -nd6_free_q(struct nd6_q_entry *q) -{ - struct nd6_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("q->p != NULL", q->p != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ND6_QUEUE, r); - } -} -#endif /* LWIP_ND6_QUEUEING */ - -/** - * Send queued packets for a neighbor - * - * @param i the neighbor to send packets to - */ -static void -nd6_send_q(s8_t i) -{ - struct ip6_hdr *ip6hdr; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *q; -#endif /* LWIP_ND6_QUEUEING */ - - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - -#if LWIP_ND6_QUEUEING - while (neighbor_cache[i].q != NULL) { - /* remember first in queue */ - q = neighbor_cache[i].q; - /* pop first item off the queue */ - neighbor_cache[i].q = q->next; - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(q->p->payload); - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest)); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, ip6_current_dest_addr()); - /* free the queued IP packet */ - pbuf_free(q->p); - /* now queue entry can be freed */ - memp_free(MEMP_ND6_QUEUE, q); - } -#else /* LWIP_ND6_QUEUEING */ - if (neighbor_cache[i].q != NULL) { - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload); - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest)); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, ip6_current_dest_addr()); - /* free the queued IP packet */ - pbuf_free(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } -#endif /* LWIP_ND6_QUEUEING */ -} - - -/** - * Get the Path MTU for a destination. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the Path MTU, if known, or the netif default MTU - */ -u16_t -nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif) -{ - s8_t i; - - i = nd6_find_destination_cache_entry(ip6addr); - if (i >= 0) { - if (destination_cache[i].pmtu > 0) { - return destination_cache[i].pmtu; - } - } - - if (netif != NULL) { - return netif->mtu; - } - - return 1280; /* Minimum MTU */ -} - - -#if LWIP_ND6_TCP_REACHABILITY_HINTS -/** - * Provide the Neighbor discovery process with a hint that a - * destination is reachable. Called by tcp_receive when ACKs are - * received or sent (as per RFC). This is useful to avoid sending - * NS messages every 30 seconds. - * - * @param ip6addr the destination address which is know to be reachable - * by an upper layer protocol (TCP) - */ -void -nd6_reachability_hint(ip6_addr_t * ip6addr) -{ - s8_t i; - - /* Find destination in cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - i = nd6_cached_destination_index; - ND6_STATS_INC(nd6.cachehit); - } - else { - i = nd6_find_destination_cache_entry(ip6addr); - } - if (i < 0) { - return; - } - - /* Find next hop neighbor in cache. */ - if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - i = nd6_cached_neighbor_index; - ND6_STATS_INC(nd6.cachehit); - } - else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr)); - } - if (i < 0) { - return; - } - - /* Set reachability state. */ - neighbor_cache[i].state = ND6_REACHABLE; - neighbor_cache[i].counter.reachable_time = reachable_time; -} -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/mem.c b/external/badvpn_dns/lwip/src/core/mem.c deleted file mode 100644 index 1659a2c..0000000 --- a/external/badvpn_dns/lwip/src/core/mem.c +++ /dev/null @@ -1,659 +0,0 @@ -/** - * @file - * Dynamic memory manager - * - * This is a lightweight replacement for the standard C library malloc(). - * - * If you want to use the standard C library malloc() instead, define - * MEM_LIBC_MALLOC to 1 in your lwipopts.h - * - * To let mem_malloc() use pools (prevents fragmentation and is much faster than - * a heap but might waste some memory), define MEM_USE_POOLS to 1, define - * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list - * of pools like this (more pools can be added between _START and _END): - * - * Define three pools with sizes 256, 512, and 1512 bytes - * LWIP_MALLOC_MEMPOOL_START - * LWIP_MALLOC_MEMPOOL(20, 256) - * LWIP_MALLOC_MEMPOOL(10, 512) - * LWIP_MALLOC_MEMPOOL(5, 1512) - * LWIP_MALLOC_MEMPOOL_END - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/sys.h" -#include "lwip/stats.h" -#include "lwip/err.h" - -#include <string.h> - -#if MEM_USE_POOLS -/* lwIP head implemented with different sized pools */ - -/** - * Allocate memory: determine the smallest pool that is big enough - * to contain an element of 'size' and get an element from that pool. - * - * @param size the size in bytes of the memory needed - * @return a pointer to the allocated memory or NULL if the pool is empty - */ -void * -mem_malloc(mem_size_t size) -{ - void *ret; - struct memp_malloc_helper *element; - memp_t poolnr; - mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - - for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { -#if MEM_USE_POOLS_TRY_BIGGER_POOL -again: -#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ - /* is this pool big enough to hold an element of the required size - plus a struct memp_malloc_helper that saves the pool this element came from? */ - if (required_size <= memp_sizes[poolnr]) { - break; - } - } - if (poolnr > MEMP_POOL_LAST) { - LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); - return NULL; - } - element = (struct memp_malloc_helper*)memp_malloc(poolnr); - if (element == NULL) { - /* No need to DEBUGF or ASSERT: This error is already - taken care of in memp.c */ -#if MEM_USE_POOLS_TRY_BIGGER_POOL - /** Try a bigger pool if this one is empty! */ - if (poolnr < MEMP_POOL_LAST) { - poolnr++; - goto again; - } -#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ - return NULL; - } - - /* save the pool number this element came from */ - element->poolnr = poolnr; - /* and return a pointer to the memory directly after the struct memp_malloc_helper */ - ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - - return ret; -} - -/** - * Free memory previously allocated by mem_malloc. Loads the pool number - * and calls memp_free with that pool number to put the element back into - * its pool - * - * @param rmem the memory element to free - */ -void -mem_free(void *rmem) -{ - struct memp_malloc_helper *hmem; - - LWIP_ASSERT("rmem != NULL", (rmem != NULL)); - LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); - - /* get the original struct memp_malloc_helper */ - hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); - - LWIP_ASSERT("hmem != NULL", (hmem != NULL)); - LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); - LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); - - /* and put it in the pool we saved earlier */ - memp_free(hmem->poolnr, hmem); -} - -#else /* MEM_USE_POOLS */ -/* lwIP replacement for your libc malloc() */ - -/** - * The heap is made up as a list of structs of this type. - * This does not have to be aligned since for getting its size, - * we only use the macro SIZEOF_STRUCT_MEM, which automatically alignes. - */ -struct mem { - /** index (-> ram[next]) of the next struct */ - mem_size_t next; - /** index (-> ram[prev]) of the previous struct */ - mem_size_t prev; - /** 1: this area is used; 0: this area is unused */ - u8_t used; -}; - -/** All allocated blocks will be MIN_SIZE bytes big, at least! - * MIN_SIZE can be overridden to suit your needs. Smaller values save space, - * larger values could prevent too small blocks to fragment the RAM too much. */ -#ifndef MIN_SIZE -#define MIN_SIZE 12 -#endif /* MIN_SIZE */ -/* some alignment macros: we define them here for better source code layout */ -#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) -#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) -#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) - -/** If you want to relocate the heap to external memory, simply define - * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. - * If so, make sure the memory at that location is big enough (see below on - * how that space is calculated). */ -#ifndef LWIP_RAM_HEAP_POINTER -/** the heap. we need one struct mem at the end and some room for alignment */ -u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]; -#define LWIP_RAM_HEAP_POINTER ram_heap -#endif /* LWIP_RAM_HEAP_POINTER */ - -/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ -static u8_t *ram; -/** the last entry, always unused! */ -static struct mem *ram_end; -/** pointer to the lowest free block, this is used for faster search */ -static struct mem *lfree; - -/** concurrent access protection */ -#if !NO_SYS -static sys_mutex_t mem_mutex; -#endif - -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - -static volatile u8_t mem_free_count; - -/* Allow mem_free from other (e.g. interrupt) context */ -#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) -#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) -#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) -#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) - -#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - -/* Protect the heap only by using a semaphore */ -#define LWIP_MEM_FREE_DECL_PROTECT() -#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) -#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) -/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ -#define LWIP_MEM_ALLOC_DECL_PROTECT() -#define LWIP_MEM_ALLOC_PROTECT() -#define LWIP_MEM_ALLOC_UNPROTECT() - -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - -/** - * "Plug holes" by combining adjacent empty struct mems. - * After this function is through, there should not exist - * one empty struct mem pointing to another empty struct mem. - * - * @param mem this points to a struct mem which just has been freed - * @internal this function is only called by mem_free() and mem_trim() - * - * This assumes access to the heap is protected by the calling function - * already. - */ -static void -plug_holes(struct mem *mem) -{ - struct mem *nmem; - struct mem *pmem; - - LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); - LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); - LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); - - /* plug hole forward */ - LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); - - nmem = (struct mem *)(void *)&ram[mem->next]; - if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { - /* if mem->next is unused and not end of ram, combine mem and mem->next */ - if (lfree == nmem) { - lfree = mem; - } - mem->next = nmem->next; - ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); - } - - /* plug hole backward */ - pmem = (struct mem *)(void *)&ram[mem->prev]; - if (pmem != mem && pmem->used == 0) { - /* if mem->prev is unused, combine mem and mem->prev */ - if (lfree == mem) { - lfree = pmem; - } - pmem->next = mem->next; - ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); - } -} - -/** - * Zero the heap and initialize start, end and lowest-free - */ -void -mem_init(void) -{ - struct mem *mem; - - LWIP_ASSERT("Sanity check alignment", - (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); - - /* align the heap */ - ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); - /* initialize the start of the heap */ - mem = (struct mem *)(void *)ram; - mem->next = MEM_SIZE_ALIGNED; - mem->prev = 0; - mem->used = 0; - /* initialize the end of the heap */ - ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; - ram_end->used = 1; - ram_end->next = MEM_SIZE_ALIGNED; - ram_end->prev = MEM_SIZE_ALIGNED; - - /* initialize the lowest-free pointer to the start of the heap */ - lfree = (struct mem *)(void *)ram; - - MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); - - if(sys_mutex_new(&mem_mutex) != ERR_OK) { - LWIP_ASSERT("failed to create mem_mutex", 0); - } -} - -/** - * Put a struct mem back on the heap - * - * @param rmem is the data portion of a struct mem as returned by a previous - * call to mem_malloc() - */ -void -mem_free(void *rmem) -{ - struct mem *mem; - LWIP_MEM_FREE_DECL_PROTECT(); - - if (rmem == NULL) { - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); - return; - } - LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); - - LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && - (u8_t *)rmem < (u8_t *)ram_end); - - if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { - SYS_ARCH_DECL_PROTECT(lev); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); - /* protect mem stats from concurrent access */ - SYS_ARCH_PROTECT(lev); - MEM_STATS_INC(illegal); - SYS_ARCH_UNPROTECT(lev); - return; - } - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - /* Get the corresponding struct mem ... */ - mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); - /* ... which has to be in a used state ... */ - LWIP_ASSERT("mem_free: mem->used", mem->used); - /* ... and is now unused. */ - mem->used = 0; - - if (mem < lfree) { - /* the newly freed struct is now the lowest */ - lfree = mem; - } - - MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); - - /* finally, see if prev or next are free also */ - plug_holes(mem); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); -} - -/** - * Shrink memory returned by mem_malloc(). - * - * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked - * @param newsize required size after shrinking (needs to be smaller than or - * equal to the previous size) - * @return for compatibility reasons: is always == rmem, at the moment - * or NULL if newsize is > old size, in which case rmem is NOT touched - * or freed! - */ -void * -mem_trim(void *rmem, mem_size_t newsize) -{ - mem_size_t size; - mem_size_t ptr, ptr2; - struct mem *mem, *mem2; - /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ - LWIP_MEM_FREE_DECL_PROTECT(); - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - newsize = LWIP_MEM_ALIGN_SIZE(newsize); - - if(newsize < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - newsize = MIN_SIZE_ALIGNED; - } - - if (newsize > MEM_SIZE_ALIGNED) { - return NULL; - } - - LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && - (u8_t *)rmem < (u8_t *)ram_end); - - if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { - SYS_ARCH_DECL_PROTECT(lev); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); - /* protect mem stats from concurrent access */ - SYS_ARCH_PROTECT(lev); - MEM_STATS_INC(illegal); - SYS_ARCH_UNPROTECT(lev); - return rmem; - } - /* Get the corresponding struct mem ... */ - mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); - /* ... and its offset pointer */ - ptr = (mem_size_t)((u8_t *)mem - ram); - - size = mem->next - ptr - SIZEOF_STRUCT_MEM; - LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); - if (newsize > size) { - /* not supported */ - return NULL; - } - if (newsize == size) { - /* No change in size, simply return */ - return rmem; - } - - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - - mem2 = (struct mem *)(void *)&ram[mem->next]; - if(mem2->used == 0) { - /* The next struct is unused, we can simply move it at little */ - mem_size_t next; - /* remember the old next pointer */ - next = mem2->next; - /* create new struct mem which is moved directly after the shrinked mem */ - ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; - if (lfree == mem2) { - lfree = (struct mem *)(void *)&ram[ptr2]; - } - mem2 = (struct mem *)(void *)&ram[ptr2]; - mem2->used = 0; - /* restore the next pointer */ - mem2->next = next; - /* link it back to mem */ - mem2->prev = ptr; - /* link mem to it */ - mem->next = ptr2; - /* last thing to restore linked list: as we have moved mem2, - * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not - * the end of the heap */ - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* no need to plug holes, we've already done that */ - } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { - /* Next struct is used but there's room for another struct mem with - * at least MIN_SIZE_ALIGNED of data. - * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem - * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory */ - ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; - mem2 = (struct mem *)(void *)&ram[ptr2]; - if (mem2 < lfree) { - lfree = mem2; - } - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - mem->next = ptr2; - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* the original mem->next is used, so no need to plug holes! */ - } - /* else { - next struct mem is used but size between mem and mem2 is not big enough - to create another struct mem - -> don't do anyhting. - -> the remaining space stays unused since it is too small - } */ -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); - return rmem; -} - -/** - * Adam's mem_malloc() plus solution for bug #17922 - * Allocate a block of memory with a minimum of 'size' bytes. - * - * @param size is the minimum size of the requested block in bytes. - * @return pointer to allocated memory or NULL if no free memory was found. - * - * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). - */ -void * -mem_malloc(mem_size_t size) -{ - mem_size_t ptr, ptr2; - struct mem *mem, *mem2; -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - u8_t local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_ALLOC_DECL_PROTECT(); - - if (size == 0) { - return NULL; - } - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - size = LWIP_MEM_ALIGN_SIZE(size); - - if(size < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - size = MIN_SIZE_ALIGNED; - } - - if (size > MEM_SIZE_ALIGNED) { - return NULL; - } - - /* protect the heap from concurrent access */ - sys_mutex_lock(&mem_mutex); - LWIP_MEM_ALLOC_PROTECT(); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* run as long as a mem_free disturbed mem_malloc or mem_trim */ - do { - local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - /* Scan through the heap searching for a free block that is big enough, - * beginning with the lowest free block. - */ - for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; - ptr = ((struct mem *)(void *)&ram[ptr])->next) { - mem = (struct mem *)(void *)&ram[ptr]; -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* allow mem_free or mem_trim to run */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem. */ - local_mem_free_count = 1; - break; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - if ((!mem->used) && - (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { - /* mem is not used and at least perfect fit is possible: - * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ - - if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { - /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing - * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') - * -> split large block, create empty remainder, - * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if - * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, - * struct mem would fit in but no data between mem2 and mem2->next - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory - */ - ptr2 = ptr + SIZEOF_STRUCT_MEM + size; - /* create mem2 struct */ - mem2 = (struct mem *)(void *)&ram[ptr2]; - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - /* and insert it between mem and mem->next */ - mem->next = ptr2; - mem->used = 1; - - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); - } else { - /* (a mem2 struct does no fit into the user data space of mem and mem->next will always - * be used at this point: if not we have 2 unused structs in a row, plug_holes should have - * take care of this). - * -> near fit or excact fit: do not split, no mem2 creation - * also can't move mem->next directly behind mem, since mem->next - * will always be used at this point! - */ - mem->used = 1; - MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT -mem_malloc_adjust_lfree: -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - if (mem == lfree) { - struct mem *cur = lfree; - /* Find next free block after mem and update lowest free pointer */ - while (cur->used && cur != ram_end) { -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* prevent high interrupt latency... */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem or lfree. */ - goto mem_malloc_adjust_lfree; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - cur = (struct mem *)(void *)&ram[cur->next]; - } - lfree = cur; - LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); - } - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", - (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); - LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", - ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); - LWIP_ASSERT("mem_malloc: sanity check alignment", - (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); - - return (u8_t *)mem + SIZEOF_STRUCT_MEM; - } - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* if we got interrupted by a mem_free, try again */ - } while(local_mem_free_count != 0); -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); - MEM_STATS_INC(err); - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - return NULL; -} - -#endif /* MEM_USE_POOLS */ -/** - * Contiguously allocates enough space for count objects that are size bytes - * of memory each and returns a pointer to the allocated memory. - * - * The allocated memory is filled with bytes of value zero. - * - * @param count number of objects to allocate - * @param size size of the objects to allocate - * @return pointer to allocated memory / NULL pointer if there is an error - */ -void *mem_calloc(mem_size_t count, mem_size_t size) -{ - void *p; - - /* allocate 'count' objects of size 'size' */ - p = mem_malloc(count * size); - if (p) { - /* zero the memory */ - memset(p, 0, count * size); - } - return p; -} - -#endif /* !MEM_LIBC_MALLOC */ diff --git a/external/badvpn_dns/lwip/src/core/memp.c b/external/badvpn_dns/lwip/src/core/memp.c deleted file mode 100644 index 1323463..0000000 --- a/external/badvpn_dns/lwip/src/core/memp.c +++ /dev/null @@ -1,485 +0,0 @@ -/** - * @file - * Dynamic pool memory manager - * - * lwIP has dedicated pools for many structures (netconn, protocol control blocks, - * packet buffers, ...). All these pools are managed here. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/udp.h" -#include "lwip/raw.h" -#include "lwip/tcp_impl.h" -#include "lwip/igmp.h" -#include "lwip/api.h" -#include "lwip/api_msg.h" -#include "lwip/tcpip.h" -#include "lwip/sys.h" -#include "lwip/timers.h" -#include "lwip/stats.h" -#include "netif/etharp.h" -#include "lwip/ip_frag.h" -#include "lwip/snmp_structs.h" -#include "lwip/snmp_msg.h" -#include "lwip/dns.h" -#include "netif/ppp_oe.h" -#include "lwip/nd6.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" - -#include <string.h> - -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ - -struct memp { - struct memp *next; -#if MEMP_OVERFLOW_CHECK - const char *file; - int line; -#endif /* MEMP_OVERFLOW_CHECK */ -}; - -#if MEMP_OVERFLOW_CHECK -/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning - * and at the end of each element, initialize them as 0xcd and check - * them later. */ -/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, - * every single element in each pool is checked! - * This is VERY SLOW but also very helpful. */ -/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in - * lwipopts.h to change the amount reserved for checking. */ -#ifndef MEMP_SANITY_REGION_BEFORE -#define MEMP_SANITY_REGION_BEFORE 16 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#if MEMP_SANITY_REGION_BEFORE > 0 -#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) -#else -#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#ifndef MEMP_SANITY_REGION_AFTER -#define MEMP_SANITY_REGION_AFTER 16 -#endif /* MEMP_SANITY_REGION_AFTER*/ -#if MEMP_SANITY_REGION_AFTER > 0 -#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) -#else -#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_AFTER*/ - -/* MEMP_SIZE: save space for struct memp and for sanity check */ -#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) - -#else /* MEMP_OVERFLOW_CHECK */ - -/* No sanity checks - * We don't need to preserve the struct memp while not allocated, so we - * can save a little space and set MEMP_SIZE to 0. - */ -#define MEMP_SIZE 0 -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_OVERFLOW_CHECK */ - -/** This array holds the first free element of each pool. - * Elements form a linked list. */ -static struct memp *memp_tab[MEMP_MAX]; - -#else /* MEMP_MEM_MALLOC */ - -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_MEM_MALLOC */ - -/** This array holds the element sizes of each pool. */ -#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC -static -#endif -const u16_t memp_sizes[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), -#include "lwip/memp_std.h" -}; - -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ - -/** This array holds the number of elements in each pool. */ -static const u16_t memp_num[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) (num), -#include "lwip/memp_std.h" -}; - -/** This array holds a textual description of each pool. */ -#ifdef LWIP_DEBUG -static const char *memp_desc[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) (desc), -#include "lwip/memp_std.h" -}; -#endif /* LWIP_DEBUG */ - -#if MEMP_SEPARATE_POOLS - -/** This creates each memory pool. These are named memp_memory_XXX_base (where - * XXX is the name of the pool defined in memp_std.h). - * To relocate a pool, declare it as extern in cc.h. Example for GCC: - * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[]; - */ -#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \ - [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; -#include "lwip/memp_std.h" - -/** This array holds the base of each memory pool. */ -static u8_t *const memp_bases[] = { -#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base, -#include "lwip/memp_std.h" -}; - -#else /* MEMP_SEPARATE_POOLS */ - -/** This is the actual memory used by the pools (all pools in one big block). */ -static u8_t memp_memory[MEM_ALIGNMENT - 1 -#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) -#include "lwip/memp_std.h" -]; - -#endif /* MEMP_SEPARATE_POOLS */ - -#if MEMP_SANITY_CHECK -/** - * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". - */ -static int -memp_sanity(void) -{ - s16_t i; - struct memp *t, *h; - - for (i = 0; i < MEMP_MAX; i++) { - t = memp_tab[i]; - if(t != NULL) { - for (h = t->next; (t != NULL) && (h != NULL); t = t->next, - h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) { - if (t == h) { - return 0; - } - } - } - } - return 1; -} -#endif /* MEMP_SANITY_CHECK*/ -#if MEMP_OVERFLOW_CHECK -#if defined(LWIP_DEBUG) && MEMP_STATS -static const char * memp_overflow_names[] = { -#define LWIP_MEMPOOL(name,num,size,desc) "/"desc, -#include "lwip/memp_std.h" - }; -#endif - -/** - * Check if a memp element was victim of an overflow - * (e.g. the restricted area after it has been altered) - * - * @param p the memp element to check - * @param memp_type the pool p comes from - */ -static void -memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type) -{ - u16_t k; - u8_t *m; -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type]; - for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp overflow in pool "; - char digit[] = "0"; - if(memp_type >= 10) { - digit[0] = '0' + (memp_type/10); - strcat(errstr, digit); - } - digit[0] = '0' + (memp_type%10); - strcat(errstr, digit); -#if defined(LWIP_DEBUG) && MEMP_STATS - strcat(errstr, memp_overflow_names[memp_type]); -#endif - LWIP_ASSERT(errstr, 0); - } - } -#endif -} - -/** - * Check if a memp element was victim of an underflow - * (e.g. the restricted area before it has been altered) - * - * @param p the memp element to check - * @param memp_type the pool p comes from - */ -static void -memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type) -{ - u16_t k; - u8_t *m; -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp underflow in pool "; - char digit[] = "0"; - if(memp_type >= 10) { - digit[0] = '0' + (memp_type/10); - strcat(errstr, digit); - } - digit[0] = '0' + (memp_type%10); - strcat(errstr, digit); -#if defined(LWIP_DEBUG) && MEMP_STATS - strcat(errstr, memp_overflow_names[memp_type]); -#endif - LWIP_ASSERT(errstr, 0); - } - } -#endif -} - -/** - * Do an overflow check for all elements in every pool. - * - * @see memp_overflow_check_element for a description of the check - */ -static void -memp_overflow_check_all(void) -{ - u16_t i, j; - struct memp *p; - -#if !MEMP_SEPARATE_POOLS - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); -#endif /* !MEMP_SEPARATE_POOLS */ - for (i = 0; i < MEMP_MAX; ++i) { -#if MEMP_SEPARATE_POOLS - p = (struct memp *)(memp_bases[i]); -#endif /* MEMP_SEPARATE_POOLS */ - for (j = 0; j < memp_num[i]; ++j) { - memp_overflow_check_element_overflow(p, i); - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } -#if !MEMP_SEPARATE_POOLS - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); -#endif /* !MEMP_SEPARATE_POOLS */ - for (i = 0; i < MEMP_MAX; ++i) { -#if MEMP_SEPARATE_POOLS - p = (struct memp *)(memp_bases[i]); -#endif /* MEMP_SEPARATE_POOLS */ - for (j = 0; j < memp_num[i]; ++j) { - memp_overflow_check_element_underflow(p, i); - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } -} - -/** - * Initialize the restricted areas of all memp elements in every pool. - */ -static void -memp_overflow_init(void) -{ - u16_t i, j; - struct memp *p; - u8_t *m; - -#if !MEMP_SEPARATE_POOLS - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); -#endif /* !MEMP_SEPARATE_POOLS */ - for (i = 0; i < MEMP_MAX; ++i) { -#if MEMP_SEPARATE_POOLS - p = (struct memp *)(memp_bases[i]); -#endif /* MEMP_SEPARATE_POOLS */ - for (j = 0; j < memp_num[i]; ++j) { -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); -#endif -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; - memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); -#endif - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } -} -#endif /* MEMP_OVERFLOW_CHECK */ - -/** - * Initialize this module. - * - * Carves out memp_memory into linked lists for each pool-type. - */ -void -memp_init(void) -{ - struct memp *memp; - u16_t i, j; - - for (i = 0; i < MEMP_MAX; ++i) { - MEMP_STATS_AVAIL(used, i, 0); - MEMP_STATS_AVAIL(max, i, 0); - MEMP_STATS_AVAIL(err, i, 0); - MEMP_STATS_AVAIL(avail, i, memp_num[i]); - } - -#if !MEMP_SEPARATE_POOLS - memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); -#endif /* !MEMP_SEPARATE_POOLS */ - /* for every pool: */ - for (i = 0; i < MEMP_MAX; ++i) { - memp_tab[i] = NULL; -#if MEMP_SEPARATE_POOLS - memp = (struct memp*)memp_bases[i]; -#endif /* MEMP_SEPARATE_POOLS */ - /* create a linked list of memp elements */ - for (j = 0; j < memp_num[i]; ++j) { - memp->next = memp_tab[i]; - memp_tab[i] = memp; - memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] -#if MEMP_OVERFLOW_CHECK - + MEMP_SANITY_REGION_AFTER_ALIGNED -#endif - ); - } - } -#if MEMP_OVERFLOW_CHECK - memp_overflow_init(); - /* check everything a first time to see if it worked */ - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK */ -} - -/** - * Get an element from a specific pool. - * - * @param type the pool to get an element from - * - * the debug version has two more parameters: - * @param file file name calling this function - * @param line number of line where this function is called - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc(memp_t type) -#else -memp_malloc_fn(memp_t type, const char* file, const int line) -#endif -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); - - SYS_ARCH_PROTECT(old_level); -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - - memp = memp_tab[type]; - - if (memp != NULL) { - memp_tab[type] = memp->next; -#if MEMP_OVERFLOW_CHECK - memp->next = NULL; - memp->file = file; - memp->line = line; -#endif /* MEMP_OVERFLOW_CHECK */ - MEMP_STATS_INC_USED(used, type); - LWIP_ASSERT("memp_malloc: memp properly aligned", - ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); - memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); - } else { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); - MEMP_STATS_INC(err, type); - } - - SYS_ARCH_UNPROTECT(old_level); - - return memp; -} - -/** - * Put an element back into its pool. - * - * @param type the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free(memp_t type, void *mem) -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - if (mem == NULL) { - return; - } - LWIP_ASSERT("memp_free: mem properly aligned", - ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); - - memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); - - SYS_ARCH_PROTECT(old_level); -#if MEMP_OVERFLOW_CHECK -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#else - memp_overflow_check_element_overflow(memp, type); - memp_overflow_check_element_underflow(memp, type); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -#endif /* MEMP_OVERFLOW_CHECK */ - - MEMP_STATS_DEC(used, type); - - memp->next = memp_tab[type]; - memp_tab[type] = memp; - -#if MEMP_SANITY_CHECK - LWIP_ASSERT("memp sanity", memp_sanity()); -#endif /* MEMP_SANITY_CHECK */ - - SYS_ARCH_UNPROTECT(old_level); -} - -#endif /* MEMP_MEM_MALLOC */ diff --git a/external/badvpn_dns/lwip/src/core/netif.c b/external/badvpn_dns/lwip/src/core/netif.c deleted file mode 100644 index 4df1a90..0000000 --- a/external/badvpn_dns/lwip/src/core/netif.c +++ /dev/null @@ -1,918 +0,0 @@ -/** - * @file - * lwIP network interface abstraction - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/tcp_impl.h" -#include "lwip/snmp.h" -#include "lwip/igmp.h" -#include "netif/etharp.h" -#include "lwip/stats.h" -#if ENABLE_LOOPBACK -#include "lwip/sys.h" -#if LWIP_NETIF_LOOPBACK_MULTITHREADING -#include "lwip/tcpip.h" -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_AUTOIP -#include "lwip/autoip.h" -#endif /* LWIP_AUTOIP */ -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif /* LWIP_DHCP */ -#if LWIP_IPV6_DHCP6 -#include "lwip/dhcp6.h" -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_IPV6_MLD -#include "lwip/mld6.h" -#endif /* LWIP_IPV6_MLD */ - -#if LWIP_NETIF_STATUS_CALLBACK -#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) -#else -#define NETIF_STATUS_CALLBACK(n) -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_LINK_CALLBACK -#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) -#else -#define NETIF_LINK_CALLBACK(n) -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -struct netif *netif_list; -struct netif *netif_default; - -static u8_t netif_num; - -#if LWIP_IPV6 -static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ - -#if LWIP_HAVE_LOOPIF -static struct netif loop_netif; - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -static err_t -netif_loopif_init(struct netif *netif) -{ - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; - netif->output = netif_loop_output; - return ERR_OK; -} -#endif /* LWIP_HAVE_LOOPIF */ - -void -netif_init(void) -{ -#if LWIP_HAVE_LOOPIF - ip_addr_t loop_ipaddr, loop_netmask, loop_gw; - IP4_ADDR(&loop_gw, 127,0,0,1); - IP4_ADDR(&loop_ipaddr, 127,0,0,1); - IP4_ADDR(&loop_netmask, 255,0,0,0); - -#if NO_SYS - netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input); -#else /* NO_SYS */ - netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); -#endif /* NO_SYS */ - netif_set_up(&loop_netif); - -#endif /* LWIP_HAVE_LOOPIF */ -} - -/** - * Add a network interface to the list of lwIP netifs. - * - * @param netif a pre-allocated netif structure - * @param ipaddr IP address for the new netif - * @param netmask network mask for the new netif - * @param gw default gateway IP address for the new netif - * @param state opaque data passed to the new netif - * @param init callback function that initializes the interface - * @param input callback function that is called to pass - * ingress packets up in the protocol layer stack. - * - * @return netif, or NULL if failed. - */ -struct netif * -netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) -{ -#if LWIP_IPV6 - u32_t i; -#endif - - LWIP_ASSERT("No init function given", init != NULL); - - /* reset new interface configuration state */ - ip_addr_set_zero(&netif->ip_addr); - ip_addr_set_zero(&netif->netmask); - ip_addr_set_zero(&netif->gw); -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - ip6_addr_set_zero(&netif->ip6_addr[i]); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); - } - netif->output_ip6 = netif_null_output_ip6; -#endif /* LWIP_IPV6 */ - netif->flags = 0; -#if LWIP_DHCP - /* netif not under DHCP control by default */ - netif->dhcp = NULL; -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - /* netif not under AutoIP control by default */ - netif->autoip = NULL; -#endif /* LWIP_AUTOIP */ -#if LWIP_IPV6_AUTOCONFIG - /* IPv6 address autoconfiguration not enabled by default */ - netif->ip6_autoconfig_enabled = 0; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if LWIP_IPV6_DHCP6 - /* netif not under DHCPv6 control by default */ - netif->dhcp6 = NULL; -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_NETIF_STATUS_CALLBACK - netif->status_callback = NULL; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - netif->link_callback = NULL; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_IGMP - netif->igmp_mac_filter = NULL; -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - netif->mld_mac_filter = NULL; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if ENABLE_LOOPBACK - netif->loop_first = NULL; - netif->loop_last = NULL; -#endif /* ENABLE_LOOPBACK */ - - /* remember netif specific state information data */ - netif->state = state; - #ifdef PSIPHON - /* tun2socks as a library, with a multi-run lifetime, - may invoke this multiple times */ - netif->num = netif_num; -#else - netif->num = netif_num++; -#endif /* PSIPHON */ - netif->input = input; - NETIF_SET_HWADDRHINT(netif, NULL); -#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS - netif->loop_cnt_current = 0; -#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ - - netif_set_addr(netif, ipaddr, netmask, gw); - - /* call user specified initialization function for netif */ - if (init(netif) != ERR_OK) { - return NULL; - } - - /* add this netif to the list */ - netif->next = netif_list; - netif_list = netif; - snmp_inc_iflist(); - -#if LWIP_IGMP - /* start IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_start(netif); - } -#endif /* LWIP_IGMP */ - - LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", - netif->name[0], netif->name[1])); - ip_addr_debug_print(NETIF_DEBUG, ipaddr); - LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); - ip_addr_debug_print(NETIF_DEBUG, netmask); - LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); - ip_addr_debug_print(NETIF_DEBUG, gw); - LWIP_DEBUGF(NETIF_DEBUG, ("\n")); - return netif; -} - -/** - * Change IP address configuration for a network interface (including netmask - * and default gateway). - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * @param netmask the new netmask - * @param gw the new default gateway - */ -void -netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw) -{ - netif_set_ipaddr(netif, ipaddr); - netif_set_netmask(netif, netmask); - netif_set_gw(netif, gw); -} - -/** - * Remove a network interface from the list of lwIP netifs. - * - * @param netif the network interface to remove - */ -void -netif_remove(struct netif *netif) -{ - if (netif == NULL) { - return; - } - -#if LWIP_IGMP - /* stop IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_stop(netif); - } -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /* stop MLD processing */ - mld6_stop(netif); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - if (netif_is_up(netif)) { - /* set netif down before removing (call callback function) */ - netif_set_down(netif); - } - - snmp_delete_ipaddridx_tree(netif); - - /* is it the first netif? */ - if (netif_list == netif) { - netif_list = netif->next; - } else { - /* look for netif further down the list */ - struct netif * tmpNetif; - for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { - if (tmpNetif->next == netif) { - tmpNetif->next = netif->next; - break; - } - } - if (tmpNetif == NULL) - return; /* we didn't find any netif today */ - } - snmp_dec_iflist(); - /* this netif is default? */ - if (netif_default == netif) { - /* reset default netif */ - netif_set_default(NULL); - } -#if LWIP_NETIF_REMOVE_CALLBACK - if (netif->remove_callback) { - netif->remove_callback(netif); - } -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); -} - -/** - * Find a network interface by searching for its name - * - * @param name the name of the netif (like netif->name) plus concatenated number - * in ascii representation (e.g. 'en0') - */ -struct netif * -netif_find(char *name) -{ - struct netif *netif; - u8_t num; - - if (name == NULL) { - return NULL; - } - - num = name[2] - '0'; - - for(netif = netif_list; netif != NULL; netif = netif->next) { - if (num == netif->num && - name[0] == netif->name[0] && - name[1] == netif->name[1]) { - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); - return netif; - } - } - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); - return NULL; -} - -int netif_is_named (struct netif *netif, const char name[3]) -{ - u8_t num = name[2] - '0'; - - return (!memcmp(netif->name, name, 2) && netif->num == num); -} - -/** - * Change the IP address of a network interface - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * - * @note call netif_set_addr() if you also want to change netmask and - * default gateway - */ -void -netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) -{ - /* TODO: Handling of obsolete pcbs */ - /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ -#if LWIP_TCP - struct tcp_pcb *pcb; - struct tcp_pcb_listen *lpcb; - - /* address is actually being changed? */ - if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { - /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); - pcb = tcp_active_pcbs; - while (pcb != NULL) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(ipX_2_ip(&pcb->local_ip), &(netif->ip_addr)) -#if LWIP_AUTOIP - /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && !ip_addr_islinklocal(ipX_2_ip(&pcb->local_ip)) -#endif /* LWIP_AUTOIP */ - ) { - /* this connection must be aborted */ - struct tcp_pcb *next = pcb->next; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); - tcp_abort(pcb); - pcb = next; - } else { - pcb = pcb->next; - } - } - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - /* PCB bound to current local interface address? */ - if ((!(ip_addr_isany(ipX_2_ip(&lpcb->local_ip)))) && - (ip_addr_cmp(ipX_2_ip(&lpcb->local_ip), &(netif->ip_addr)))) { - /* The PCB is listening to the old ipaddr and - * is set to listen to the new one instead */ - ip_addr_set(ipX_2_ip(&lpcb->local_ip), ipaddr); - } - } - } -#endif - snmp_delete_ipaddridx_tree(netif); - snmp_delete_iprteidx_tree(0,netif); - /* set new IP address to netif */ - ip_addr_set(&(netif->ip_addr), ipaddr); - snmp_insert_ipaddridx_tree(netif); - snmp_insert_iprteidx_tree(0,netif); - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->ip_addr), - ip4_addr2_16(&netif->ip_addr), - ip4_addr3_16(&netif->ip_addr), - ip4_addr4_16(&netif->ip_addr))); -} - -/** - * Change the default gateway for a network interface - * - * @param netif the network interface to change - * @param gw the new default gateway - * - * @note call netif_set_addr() if you also want to change ip address and netmask - */ -void -netif_set_gw(struct netif *netif, ip_addr_t *gw) -{ - ip_addr_set(&(netif->gw), gw); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->gw), - ip4_addr2_16(&netif->gw), - ip4_addr3_16(&netif->gw), - ip4_addr4_16(&netif->gw))); -} - -void netif_set_pretend_tcp (struct netif *netif, u8_t pretend) -{ - if (pretend) { - netif->flags |= NETIF_FLAG_PRETEND_TCP; - } else { - netif->flags &= ~NETIF_FLAG_PRETEND_TCP; - } -} - -/** - * Change the netmask of a network interface - * - * @param netif the network interface to change - * @param netmask the new netmask - * - * @note call netif_set_addr() if you also want to change ip address and - * default gateway - */ -void -netif_set_netmask(struct netif *netif, ip_addr_t *netmask) -{ - snmp_delete_iprteidx_tree(0, netif); - /* set new netmask to netif */ - ip_addr_set(&(netif->netmask), netmask); - snmp_insert_iprteidx_tree(0, netif); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->netmask), - ip4_addr2_16(&netif->netmask), - ip4_addr3_16(&netif->netmask), - ip4_addr4_16(&netif->netmask))); -} - -/** - * Set a network interface as the default network interface - * (used to output all packets for which no specific route is found) - * - * @param netif the default network interface - */ -void -netif_set_default(struct netif *netif) -{ - if (netif == NULL) { - /* remove default route */ - snmp_delete_iprteidx_tree(1, netif); - } else { - /* install default route */ - snmp_insert_iprteidx_tree(1, netif); - } - netif_default = netif; - LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", - netif ? netif->name[0] : ''', netif ? netif->name[1] : ''')); -} - -/** - * Bring an interface up, available for processing - * traffic. - * - * @note: Enabling DHCP on a down interface will make it come - * up once configured. - * - * @see dhcp_start() - */ -void netif_set_up(struct netif *netif) -{ - if (!(netif->flags & NETIF_FLAG_UP)) { - netif->flags |= NETIF_FLAG_UP; - -#if LWIP_SNMP - snmp_get_sysuptime(&netif->ts); -#endif /* LWIP_SNMP */ - - NETIF_STATUS_CALLBACK(netif); - - if (netif->flags & NETIF_FLAG_LINK_UP) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & (NETIF_FLAG_ETHARP)) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups( netif); - } -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /* send mld memberships */ - mld6_report_groups( netif); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send Router Solicitation messages. */ - netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - - } - } -} - -/** - * Bring an interface down, disabling any traffic processing. - * - * @note: Enabling DHCP on a down interface will make it come - * up once configured. - * - * @see dhcp_start() - */ -void netif_set_down(struct netif *netif) -{ - if (netif->flags & NETIF_FLAG_UP) { - netif->flags &= ~NETIF_FLAG_UP; -#if LWIP_SNMP - snmp_get_sysuptime(&netif->ts); -#endif - -#if LWIP_ARP - if (netif->flags & NETIF_FLAG_ETHARP) { - etharp_cleanup_netif(netif); - } -#endif /* LWIP_ARP */ - NETIF_STATUS_CALLBACK(netif); - } -} - -#if LWIP_NETIF_STATUS_CALLBACK -/** - * Set callback to be called when interface is brought up/down - */ -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) -{ - if (netif) { - netif->status_callback = status_callback; - } -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_REMOVE_CALLBACK -/** - * Set callback to be called when the interface has been removed - */ -void -netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) -{ - if (netif) { - netif->remove_callback = remove_callback; - } -} -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -/** - * Called by a driver when its link goes up - */ -void netif_set_link_up(struct netif *netif ) -{ - if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - netif->flags |= NETIF_FLAG_LINK_UP; - -#if LWIP_DHCP - if (netif->dhcp) { - dhcp_network_changed(netif); - } -#endif /* LWIP_DHCP */ - -#if LWIP_AUTOIP - if (netif->autoip) { - autoip_network_changed(netif); - } -#endif /* LWIP_AUTOIP */ - - if (netif->flags & NETIF_FLAG_UP) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & NETIF_FLAG_ETHARP) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups( netif); - } -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /* send mld memberships */ - mld6_report_groups( netif); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - } - NETIF_LINK_CALLBACK(netif); - } -} - -/** - * Called by a driver when its link goes down - */ -void netif_set_link_down(struct netif *netif ) -{ - if (netif->flags & NETIF_FLAG_LINK_UP) { - netif->flags &= ~NETIF_FLAG_LINK_UP; - NETIF_LINK_CALLBACK(netif); - } -} - -#if LWIP_NETIF_LINK_CALLBACK -/** - * Set callback to be called when link is brought up/down - */ -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) -{ - if (netif) { - netif->link_callback = link_callback; - } -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if ENABLE_LOOPBACK -/** - * Send an IP packet to be received on the same netif (loopif-like). - * The pbuf is simply copied and handed back to netif->input. - * In multithreaded mode, this is done directly since netif->input must put - * the packet on a queue. - * In callback mode, the packet is put on an internal queue and is fed to - * netif->input by netif_poll(). - * - * @param netif the lwip network interface structure - * @param p the (IP) packet to 'send' - * @param ipaddr the ip address to send the packet to (not used) - * @return ERR_OK if the packet has been sent - * ERR_MEM if the pbuf used to copy the packet couldn't be allocated - */ -err_t -netif_loop_output(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr) -{ - struct pbuf *r; - err_t err; - struct pbuf *last; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = 0; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if LWIP_SNMP -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* LWIP_SNMP */ - SYS_ARCH_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(ipaddr); - - /* Allocate a new pbuf */ - r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (r == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return ERR_MEM; - } -#if LWIP_LOOPBACK_MAX_PBUFS - clen = pbuf_clen(r); - /* check for overflow or too many pbuf on queue */ - if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || - ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return ERR_MEM; - } - netif->loop_cnt_current += clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* Copy the whole pbuf queue p into the single pbuf r */ - if ((err = pbuf_copy(r, p)) != ERR_OK) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return err; - } - - /* Put the packet on a linked list which gets emptied through calling - netif_poll(). */ - - /* let last point to the last pbuf in chain r */ - for (last = r; last->next != NULL; last = last->next); - - SYS_ARCH_PROTECT(lev); - if(netif->loop_first != NULL) { - LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); - netif->loop_last->next = r; - netif->loop_last = last; - } else { - netif->loop_first = r; - netif->loop_last = last; - } - SYS_ARCH_UNPROTECT(lev); - - LINK_STATS_INC(link.xmit); - snmp_add_ifoutoctets(stats_if, p->tot_len); - snmp_inc_ifoutucastpkts(stats_if); - -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - /* For multithreading environment, schedule a call to netif_poll */ - tcpip_callback((tcpip_callback_fn)netif_poll, netif); -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - - return ERR_OK; -} - -/** - * Call netif_poll() in the main loop of your application. This is to prevent - * reentering non-reentrant functions like tcp_input(). Packets passed to - * netif_loop_output() are put on a list that is passed to netif->input() by - * netif_poll(). - */ -void -netif_poll(struct netif *netif) -{ - struct pbuf *in; - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if LWIP_SNMP -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* LWIP_SNMP */ - SYS_ARCH_DECL_PROTECT(lev); - - do { - /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ - SYS_ARCH_PROTECT(lev); - in = netif->loop_first; - if (in != NULL) { - struct pbuf *in_end = in; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = pbuf_clen(in); - /* adjust the number of pbufs on queue */ - LWIP_ASSERT("netif->loop_cnt_current underflow", - ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); - netif->loop_cnt_current -= clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - while (in_end->len != in_end->tot_len) { - LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); - in_end = in_end->next; - } - /* 'in_end' now points to the last pbuf from 'in' */ - if (in_end == netif->loop_last) { - /* this was the last pbuf in the list */ - netif->loop_first = netif->loop_last = NULL; - } else { - /* pop the pbuf off the list */ - netif->loop_first = in_end->next; - LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); - } - /* De-queue the pbuf from its successors on the 'loop_' list. */ - in_end->next = NULL; - } - SYS_ARCH_UNPROTECT(lev); - - if (in != NULL) { - LINK_STATS_INC(link.recv); - snmp_add_ifinoctets(stats_if, in->tot_len); - snmp_inc_ifinucastpkts(stats_if); - /* loopback packets are always IP packets! */ - if (ip_input(in, netif) != ERR_OK) { - pbuf_free(in); - } - /* Don't reference the packet any more! */ - in = NULL; - } - /* go on while there is a packet on the list */ - } while (netif->loop_first != NULL); -} - -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -/** - * Calls netif_poll() for every netif on the netif_list. - */ -void -netif_poll_all(void) -{ - struct netif *netif = netif_list; - /* loop through netifs */ - while (netif != NULL) { - netif_poll(netif); - /* proceed to next network interface */ - netif = netif->next; - } -} -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_IPV6 -s8_t -netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_cmp(netif_ip6_addr(netif, i), ip6addr)) { - return i; - } - } - return -1; -} - -void -netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit) -{ - u8_t i, addr_index; - - /* Link-local prefix. */ - netif->ip6_addr[0].addr[0] = PP_HTONL(0xfe800000ul); - netif->ip6_addr[0].addr[1] = 0; - - /* Generate interface ID. */ - if (from_mac_48bit) { - /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ - netif->ip6_addr[0].addr[2] = htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | - ((u32_t)(netif->hwaddr[1]) << 16) | - ((u32_t)(netif->hwaddr[2]) << 8) | - (0xff)); - netif->ip6_addr[0].addr[3] = htonl((0xfeul << 24) | - ((u32_t)(netif->hwaddr[3]) << 16) | - ((u32_t)(netif->hwaddr[4]) << 8) | - (netif->hwaddr[5])); - } - else { - /* Use hwaddr directly as interface ID. */ - netif->ip6_addr[0].addr[2] = 0; - netif->ip6_addr[0].addr[3] = 0; - - addr_index = 3; - for (i = 0; i < 8; i++) { - if (i == 4) { - addr_index--; - } - netif->ip6_addr[0].addr[addr_index] |= ((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03)); - } - } - - /* Set address state. */ -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* Will perform duplicate address detection (DAD). */ - netif->ip6_addr_state[0] = IP6_ADDR_TENTATIVE; -#else - /* Consider address valid. */ - netif->ip6_addr_state[0] = IP6_ADDR_PREFERRED; -#endif /* LWIP_IPV6_AUTOCONFIG */ -} - -static err_t -netif_null_output_ip6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr) -{ - (void)netif; - (void)p; - (void)ipaddr; - - return ERR_IF; -} -#endif /* LWIP_IPV6 */ diff --git a/external/badvpn_dns/lwip/src/core/pbuf.c b/external/badvpn_dns/lwip/src/core/pbuf.c deleted file mode 100644 index 1e5e53b..0000000 --- a/external/badvpn_dns/lwip/src/core/pbuf.c +++ /dev/null @@ -1,1179 +0,0 @@ -/** - * @file - * Packet buffer management - * - * Packets are built from the pbuf data structure. It supports dynamic - * memory allocation for packet contents or can reference externally - * managed packet contents both in RAM and ROM. Quick allocation for - * incoming packets is provided through pools with fixed sized pbufs. - * - * A packet may span over multiple pbufs, chained as a singly linked - * list. This is called a "pbuf chain". - * - * Multiple packets may be queued, also using this singly linked list. - * This is called a "packet queue". - * - * So, a packet queue consists of one or more pbuf chains, each of - * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE - * NOT SUPPORTED!!! Use helper structs to queue multiple packets. - * - * The differences between a pbuf chain and a packet queue are very - * precise but subtle. - * - * The last pbuf of a packet has a ->tot_len field that equals the - * ->len field. It can be found by traversing the list. If the last - * pbuf of a packet has a ->next field other than NULL, more packets - * are on the queue. - * - * Therefore, looping through a pbuf of a single packet, has an - * loop end condition (tot_len == p->len), NOT (next == NULL). - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/stats.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#include "arch/perf.h" -#if LWIP_TCP && TCP_QUEUE_OOSEQ -#include "lwip/tcp_impl.h" -#endif -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include <string.h> - -#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) -/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically - aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ -#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) - -#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_IS_EMPTY() -#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -#if !NO_SYS -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL -#include "lwip/tcpip.h" -#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ - if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ - SYS_ARCH_PROTECT(old_level); \ - pbuf_free_ooseq_pending = 0; \ - SYS_ARCH_UNPROTECT(old_level); \ - } } while(0) -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -#endif /* !NO_SYS */ - -volatile u8_t pbuf_free_ooseq_pending; -#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() - -/** - * Attempt to reclaim some memory from queued out-of-sequence TCP segments - * if we run out of pool pbufs. It's better to give priority to new packets - * if we're running out. - * - * This must be done in the correct thread context therefore this function - * can only be used with NO_SYS=0 and through tcpip_callback. - */ -#if !NO_SYS -static -#endif /* !NO_SYS */ -void -pbuf_free_ooseq(void) -{ - struct tcp_pcb* pcb; - SYS_ARCH_DECL_PROTECT(old_level); - - SYS_ARCH_PROTECT(old_level); - pbuf_free_ooseq_pending = 0; - SYS_ARCH_UNPROTECT(old_level); - - for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { - if (NULL != pcb->ooseq) { - /** Free the ooseq pbufs of one PCB only */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; - return; - } - } -} - -#if !NO_SYS -/** - * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq(). - */ -static void -pbuf_free_ooseq_callback(void *arg) -{ - LWIP_UNUSED_ARG(arg); - pbuf_free_ooseq(); -} -#endif /* !NO_SYS */ - -/** Queue a call to pbuf_free_ooseq if not already queued. */ -static void -pbuf_pool_is_empty(void) -{ -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - pbuf_free_ooseq_pending = 1; - SYS_ARCH_UNPROTECT(old_level); -#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ - u8_t queued; - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - queued = pbuf_free_ooseq_pending; - pbuf_free_ooseq_pending = 1; - SYS_ARCH_UNPROTECT(old_level); - - if(!queued) { - /* queue a call to pbuf_free_ooseq if not already queued */ - PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); - } -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -} -#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -/** - * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). - * - * The actual memory allocated for the pbuf is determined by the - * layer at which the pbuf is allocated and the requested size - * (from the size parameter). - * - * @param layer flag to define header size - * @param length size of the pbuf's payload - * @param type this parameter decides how and where the pbuf - * should be allocated as follows: - * - * - PBUF_RAM: buffer memory for pbuf is allocated as one large - * chunk. This includes protocol headers as well. - * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for - * protocol headers. Additional headers must be prepended - * by allocating another pbuf and chain in to the front of - * the ROM pbuf. It is assumed that the memory used is really - * similar to ROM in that it is immutable and will not be - * changed. Memory which is dynamic should generally not - * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. - * - PBUF_REF: no buffer memory is allocated for the pbuf, even for - * protocol headers. It is assumed that the pbuf is only - * being used in a single thread. If the pbuf gets queued, - * then pbuf_take should be called to copy the buffer. - * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from - * the pbuf pool that is allocated during pbuf_init(). - * - * @return the allocated pbuf. If multiple pbufs where allocated, this - * is the first pbuf of a pbuf chain. - */ -struct pbuf * -pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) -{ - struct pbuf *p, *q, *r; - u16_t offset; - s32_t rem_len; /* remaining length */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); - - /* determine header offset */ - switch (layer) { - case PBUF_TRANSPORT: - /* add room for transport (often TCP) layer header */ - offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; - break; - case PBUF_IP: - /* add room for IP layer header */ - offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; - break; - case PBUF_LINK: - /* add room for link layer header */ - offset = PBUF_LINK_HLEN; - break; - case PBUF_RAW: - offset = 0; - break; - default: - LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); - return NULL; - } - - switch (type) { - case PBUF_POOL: - /* allocate head of pbuf chain into p */ - p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); - if (p == NULL) { - PBUF_POOL_IS_EMPTY(); - return NULL; - } - p->type = type; - p->next = NULL; - - /* make the payload pointer point 'offset' bytes into pbuf data memory */ - p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); - LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", - ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); - /* the total length of the pbuf chain is the requested size */ - p->tot_len = length; - /* set the length of the first pbuf in the chain */ - p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); - LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", - ((u8_t*)p->payload + p->len <= - (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); - LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", - (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); - /* set reference count (needed here in case we fail) */ - p->ref = 1; - - /* now allocate the tail of the pbuf chain */ - - /* remember first pbuf for linkage in next iteration */ - r = p; - /* remaining length to be allocated */ - rem_len = length - p->len; - /* any remaining pbufs to be allocated? */ - while (rem_len > 0) { - q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); - if (q == NULL) { - PBUF_POOL_IS_EMPTY(); - /* free chain so far allocated */ - pbuf_free(p); - /* bail out unsuccesfully */ - return NULL; - } - q->type = type; - q->flags = 0; - q->next = NULL; - /* make previous pbuf point to this pbuf */ - r->next = q; - /* set total length of this pbuf and next in chain */ - LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); - q->tot_len = (u16_t)rem_len; - /* this pbuf length is pool size, unless smaller sized tail */ - q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); - q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); - LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", - ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); - LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", - ((u8_t*)p->payload + p->len <= - (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); - q->ref = 1; - /* calculate remaining length to be allocated */ - rem_len -= q->len; - /* remember this pbuf for linkage in next iteration */ - r = q; - } - /* end of chain */ - /*r->next = NULL;*/ - - break; - case PBUF_RAM: - /* If pbuf is to be allocated in RAM, allocate memory for it. */ - p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); - if (p == NULL) { - return NULL; - } - /* Set up internal structure of the pbuf. */ - p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); - p->len = p->tot_len = length; - p->next = NULL; - p->type = type; - - LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", - ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); - break; - /* pbuf references existing (non-volatile static constant) ROM payload? */ - case PBUF_ROM: - /* pbuf references existing (externally allocated) RAM payload? */ - case PBUF_REF: - /* only allocate memory for the pbuf structure */ - p = (struct pbuf *)memp_malloc(MEMP_PBUF); - if (p == NULL) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", - (type == PBUF_ROM) ? "ROM" : "REF")); - return NULL; - } - /* caller must set this field properly, afterwards */ - p->payload = NULL; - p->len = p->tot_len = length; - p->next = NULL; - p->type = type; - break; - default: - LWIP_ASSERT("pbuf_alloc: erroneous type", 0); - return NULL; - } - /* set reference count */ - p->ref = 1; - /* set flags */ - p->flags = 0; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); - return p; -} - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** Initialize a custom pbuf (already allocated). - * - * @param layer flag to define header size - * @param length size of the pbuf's payload - * @param type type of the pbuf (only used to treat the pbuf accordingly, as - * this function allocates no memory) - * @param p pointer to the custom pbuf to initialize (already allocated) - * @param payload_mem pointer to the buffer that is used for payload and headers, - * must be at least big enough to hold 'length' plus the header size, - * may be NULL if set later. - * ATTENTION: The caller is responsible for correct alignment of this buffer!! - * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least - * big enough to hold 'length' plus the header size - */ -struct pbuf* -pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, - void *payload_mem, u16_t payload_mem_len) -{ - u16_t offset; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); - - /* determine header offset */ - switch (l) { - case PBUF_TRANSPORT: - /* add room for transport (often TCP) layer header */ - offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; - break; - case PBUF_IP: - /* add room for IP layer header */ - offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; - break; - case PBUF_LINK: - /* add room for link layer header */ - offset = PBUF_LINK_HLEN; - break; - case PBUF_RAW: - offset = 0; - break; - default: - LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); - return NULL; - } - - if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); - return NULL; - } - - p->pbuf.next = NULL; - if (payload_mem != NULL) { - p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); - } else { - p->pbuf.payload = NULL; - } - p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; - p->pbuf.len = p->pbuf.tot_len = length; - p->pbuf.type = type; - p->pbuf.ref = 1; - return &p->pbuf; -} -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -/** - * Shrink a pbuf chain to a desired length. - * - * @param p pbuf to shrink. - * @param new_len desired new length of pbuf chain - * - * Depending on the desired length, the first few pbufs in a chain might - * be skipped and left unchanged. The new last pbuf in the chain will be - * resized, and any remaining pbufs will be freed. - * - * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. - * @note May not be called on a packet queue. - * - * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). - */ -void -pbuf_realloc(struct pbuf *p, u16_t new_len) -{ - struct pbuf *q; - u16_t rem_len; /* remaining length */ - s32_t grow; - - LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); - LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || - p->type == PBUF_ROM || - p->type == PBUF_RAM || - p->type == PBUF_REF); - - /* desired length larger than current length? */ - if (new_len >= p->tot_len) { - /* enlarging not yet supported */ - return; - } - - /* the pbuf chain grows by (new_len - p->tot_len) bytes - * (which may be negative in case of shrinking) */ - grow = new_len - p->tot_len; - - /* first, step over any pbufs that should remain in the chain */ - rem_len = new_len; - q = p; - /* should this pbuf be kept? */ - while (rem_len > q->len) { - /* decrease remaining length by pbuf length */ - rem_len -= q->len; - /* decrease total length indicator */ - LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); - q->tot_len += (u16_t)grow; - /* proceed to next pbuf in chain */ - q = q->next; - LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); - } - /* we have now reached the new last pbuf (in q) */ - /* rem_len == desired length for pbuf q */ - - /* shrink allocated memory for PBUF_RAM */ - /* (other types merely adjust their length fields */ - if ((q->type == PBUF_RAM) && (rem_len != q->len)) { - /* reallocate and adjust the length of the pbuf that will be split */ - q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); - LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); - } - /* adjust length fields for new last pbuf */ - q->len = rem_len; - q->tot_len = q->len; - - /* any remaining pbufs in chain? */ - if (q->next != NULL) { - /* free remaining pbufs in chain */ - pbuf_free(q->next); - } - /* q is last packet in chain */ - q->next = NULL; - -} - -/** - * Adjusts the payload pointer to hide or reveal headers in the payload. - * - * Adjusts the ->payload pointer so that space for a header - * (dis)appears in the pbuf payload. - * - * The ->payload, ->tot_len and ->len fields are adjusted. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size which - * increases the size of the pbuf. New space is on the front. - * (Using a negative value decreases the header size.) - * If hdr_size_inc is 0, this function does nothing and returns succesful. - * - * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so - * the call will fail. A check is made that the increase in header size does - * not move the payload pointer in front of the start of the buffer. - * @return non-zero on failure, zero on success. - * - */ -u8_t -pbuf_header(struct pbuf *p, s16_t header_size_increment) -{ - u16_t type; - void *payload; - u16_t increment_magnitude; - - LWIP_ASSERT("p != NULL", p != NULL); - if ((header_size_increment == 0) || (p == NULL)) { - return 0; - } - - if (header_size_increment < 0){ - increment_magnitude = -header_size_increment; - /* Check that we aren't going to move off the end of the pbuf */ - LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); - } else { - increment_magnitude = header_size_increment; -#if 0 - /* Can't assert these as some callers speculatively call - pbuf_header() to see if it's OK. Will return 1 below instead. */ - /* Check that we've got the correct type of pbuf to work with */ - LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", - p->type == PBUF_RAM || p->type == PBUF_POOL); - /* Check that we aren't going to move off the beginning of the pbuf */ - LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", - (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); -#endif - } - - type = p->type; - /* remember current payload pointer */ - payload = p->payload; - - /* pbuf types containing payloads? */ - if (type == PBUF_RAM || type == PBUF_POOL) { - /* set new payload pointer */ - p->payload = (u8_t *)p->payload - header_size_increment; - /* boundary check fails? */ - if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", - (void *)p->payload, (void *)(p + 1))); - /* restore old payload pointer */ - p->payload = payload; - /* bail out unsuccesfully */ - return 1; - } - /* pbuf types refering to external payloads? */ - } else if (type == PBUF_REF || type == PBUF_ROM) { - /* hide a header in the payload? */ - if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { - /* increase payload pointer */ - p->payload = (u8_t *)p->payload - header_size_increment; - } else { - /* cannot expand payload to front (yet!) - * bail out unsuccesfully */ - return 1; - } - } else { - /* Unknown type */ - LWIP_ASSERT("bad pbuf type", 0); - return 1; - } - /* modify pbuf length fields */ - p->len += header_size_increment; - p->tot_len += header_size_increment; - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", - (void *)payload, (void *)p->payload, header_size_increment)); - - return 0; -} - -/** - * Dereference a pbuf chain or queue and deallocate any no-longer-used - * pbufs at the head of this chain or queue. - * - * Decrements the pbuf reference count. If it reaches zero, the pbuf is - * deallocated. - * - * For a pbuf chain, this is repeated for each pbuf in the chain, - * up to the first pbuf which has a non-zero reference count after - * decrementing. So, when all reference counts are one, the whole - * chain is free'd. - * - * @param p The pbuf (chain) to be dereferenced. - * - * @return the number of pbufs that were de-allocated - * from the head of the chain. - * - * @note MUST NOT be called on a packet queue (Not verified to work yet). - * @note the reference counter of a pbuf equals the number of pointers - * that refer to the pbuf (or into the pbuf). - * - * @internal examples: - * - * Assuming existing chains a->b->c with the following reference - * counts, calling pbuf_free(a) results in: - * - * 1->2->3 becomes ...1->3 - * 3->3->3 becomes 2->3->3 - * 1->1->2 becomes ......1 - * 2->1->1 becomes 1->1->1 - * 1->1->1 becomes ....... - * - */ -u8_t -pbuf_free(struct pbuf *p) -{ - u16_t type; - struct pbuf *q; - u8_t count; - - if (p == NULL) { - LWIP_ASSERT("p != NULL", p != NULL); - /* if assertions are disabled, proceed with debug output */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_free(p == NULL) was called.\n")); - return 0; - } - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); - - PERF_START; - - LWIP_ASSERT("pbuf_free: sane type", - p->type == PBUF_RAM || p->type == PBUF_ROM || - p->type == PBUF_REF || p->type == PBUF_POOL); - - count = 0; - /* de-allocate all consecutive pbufs from the head of the chain that - * obtain a zero reference count after decrementing*/ - while (p != NULL) { - u16_t ref; - SYS_ARCH_DECL_PROTECT(old_level); - /* Since decrementing ref cannot be guaranteed to be a single machine operation - * we must protect it. We put the new ref into a local variable to prevent - * further protection. */ - SYS_ARCH_PROTECT(old_level); - /* all pbufs in a chain are referenced at least once */ - LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); - /* decrease reference count (number of pointers to pbuf) */ - ref = --(p->ref); - SYS_ARCH_UNPROTECT(old_level); - /* this pbuf is no longer referenced to? */ - if (ref == 0) { - /* remember next pbuf in chain for next iteration */ - q = p->next; - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); - type = p->type; -#if LWIP_SUPPORT_CUSTOM_PBUF - /* is this a custom pbuf? */ - if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { - struct pbuf_custom *pc = (struct pbuf_custom*)p; - LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); - pc->custom_free_function(p); - } else -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - { - /* is this a pbuf from the pool? */ - if (type == PBUF_POOL) { - memp_free(MEMP_PBUF_POOL, p); - /* is this a ROM or RAM referencing pbuf? */ - } else if (type == PBUF_ROM || type == PBUF_REF) { - memp_free(MEMP_PBUF, p); - /* type == PBUF_RAM */ - } else { - mem_free(p); - } - } - count++; - /* proceed to next pbuf */ - p = q; - /* p->ref > 0, this pbuf is still referenced to */ - /* (and so the remaining pbufs in chain as well) */ - } else { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); - /* stop walking through the chain */ - p = NULL; - } - } - PERF_STOP("pbuf_free"); - /* return number of de-allocated pbufs */ - return count; -} - -/** - * Count number of pbufs in a chain - * - * @param p first pbuf of chain - * @return the number of pbufs in a chain - */ - -u8_t -pbuf_clen(struct pbuf *p) -{ - u8_t len; - - len = 0; - while (p != NULL) { - ++len; - p = p->next; - } - return len; -} - -/** - * Increment the reference count of the pbuf. - * - * @param p pbuf to increase reference counter of - * - */ -void -pbuf_ref(struct pbuf *p) -{ - SYS_ARCH_DECL_PROTECT(old_level); - /* pbuf given? */ - if (p != NULL) { - SYS_ARCH_PROTECT(old_level); - ++(p->ref); - SYS_ARCH_UNPROTECT(old_level); - } -} - -/** - * Concatenate two pbufs (each may be a pbuf chain) and take over - * the caller's reference of the tail pbuf. - * - * @note The caller MAY NOT reference the tail pbuf afterwards. - * Use pbuf_chain() for that purpose. - * - * @see pbuf_chain() - */ - -void -pbuf_cat(struct pbuf *h, struct pbuf *t) -{ - struct pbuf *p; - - LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", - ((h != NULL) && (t != NULL)), return;); - - /* proceed to last pbuf of chain */ - for (p = h; p->next != NULL; p = p->next) { - /* add total length of second chain to all totals of first chain */ - p->tot_len += t->tot_len; - } - /* { p is last pbuf of first h chain, p->next == NULL } */ - LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); - LWIP_ASSERT("p->next == NULL", p->next == NULL); - /* add total length of second chain to last pbuf total of first chain */ - p->tot_len += t->tot_len; - /* chain last pbuf of head (p) with first of tail (t) */ - p->next = t; - /* p->next now references t, but the caller will drop its reference to t, - * so netto there is no change to the reference count of t. - */ -} - -/** - * Chain two pbufs (or pbuf chains) together. - * - * The caller MUST call pbuf_free(t) once it has stopped - * using it. Use pbuf_cat() instead if you no longer use t. - * - * @param h head pbuf (chain) - * @param t tail pbuf (chain) - * @note The pbufs MUST belong to the same packet. - * @note MAY NOT be called on a packet queue. - * - * The ->tot_len fields of all pbufs of the head chain are adjusted. - * The ->next field of the last pbuf of the head chain is adjusted. - * The ->ref field of the first pbuf of the tail chain is adjusted. - * - */ -void -pbuf_chain(struct pbuf *h, struct pbuf *t) -{ - pbuf_cat(h, t); - /* t is now referenced by h */ - pbuf_ref(t); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); -} - -/** - * Dechains the first pbuf from its succeeding pbufs in the chain. - * - * Makes p->tot_len field equal to p->len. - * @param p pbuf to dechain - * @return remainder of the pbuf chain, or NULL if it was de-allocated. - * @note May not be called on a packet queue. - */ -struct pbuf * -pbuf_dechain(struct pbuf *p) -{ - struct pbuf *q; - u8_t tail_gone = 1; - /* tail */ - q = p->next; - /* pbuf has successor in chain? */ - if (q != NULL) { - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); - /* enforce invariant if assertion is disabled */ - q->tot_len = p->tot_len - p->len; - /* decouple pbuf from remainder */ - p->next = NULL; - /* total length of pbuf p is its own length only */ - p->tot_len = p->len; - /* q is no longer referenced by p, free it */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); - tail_gone = pbuf_free(q); - if (tail_gone > 0) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, - ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); - } - /* return remaining tail or NULL if deallocated */ - } - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); - return ((tail_gone > 0) ? NULL : q); -} - -/** - * - * Create PBUF_RAM copies of pbufs. - * - * Used to queue packets on behalf of the lwIP stack, such as - * ARP based queueing. - * - * @note You MUST explicitly use p = pbuf_take(p); - * - * @note Only one packet is copied, no packet queue! - * - * @param p_to pbuf destination of the copy - * @param p_from pbuf source of the copy - * - * @return ERR_OK if pbuf was copied - * ERR_ARG if one of the pbufs is NULL or p_to is not big - * enough to hold p_from - */ -err_t -pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) -{ - u16_t offset_to=0, offset_from=0, len; - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", - (void*)p_to, (void*)p_from)); - - /* is the target big enough to hold the source? */ - LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && - (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); - - /* iterate through pbuf chain */ - do - { - /* copy one part of the original chain */ - if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { - /* complete current p_from fits into current p_to */ - len = p_from->len - offset_from; - } else { - /* current p_from does not fit into current p_to */ - len = p_to->len - offset_to; - } - MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); - offset_to += len; - offset_from += len; - LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); - LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); - if (offset_from >= p_from->len) { - /* on to next p_from (if any) */ - offset_from = 0; - p_from = p_from->next; - } - if (offset_to == p_to->len) { - /* on to next p_to (if any) */ - offset_to = 0; - p_to = p_to->next; - LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); - } - - if((p_from != NULL) && (p_from->len == p_from->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", - (p_from->next == NULL), return ERR_VAL;); - } - if((p_to != NULL) && (p_to->len == p_to->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", - (p_to->next == NULL), return ERR_VAL;); - } - } while (p_from); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); - return ERR_OK; -} - -/** - * Copy (part of) the contents of a packet buffer - * to an application supplied buffer. - * - * @param buf the pbuf from which to copy data - * @param dataptr the application supplied buffer - * @param len length of data to copy (dataptr must be big enough). No more - * than buf->tot_len will be copied, irrespective of len - * @param offset offset into the packet buffer from where to begin copying len bytes - * @return the number of bytes copied, or 0 on failure - */ -u16_t -pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) -{ - struct pbuf *p; - u16_t left; - u16_t buf_copy_len; - u16_t copied_total = 0; - - LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); - LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); - - left = 0; - - if((buf == NULL) || (dataptr == NULL)) { - return 0; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for(p = buf; len != 0 && p != NULL; p = p->next) { - if ((offset != 0) && (offset >= p->len)) { - /* don't copy from this buffer -> on to the next */ - offset -= p->len; - } else { - /* copy from this buffer. maybe only partially. */ - buf_copy_len = p->len - offset; - if (buf_copy_len > len) - buf_copy_len = len; - /* copy the necessary parts of the buffer */ - MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); - copied_total += buf_copy_len; - left += buf_copy_len; - len -= buf_copy_len; - offset = 0; - } - } - return copied_total; -} - -/** - * Copy application supplied data into a pbuf. - * This function can only be used to copy the equivalent of buf->tot_len data. - * - * @param buf pbuf to fill with data - * @param dataptr application supplied data buffer - * @param len length of the application supplied data buffer - * - * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough - */ -err_t -pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) -{ - struct pbuf *p; - u16_t buf_copy_len; - u16_t total_copy_len = len; - u16_t copied_total = 0; - - LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;); - LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;); - - if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { - return ERR_ARG; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for(p = buf; total_copy_len != 0; p = p->next) { - LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); - buf_copy_len = total_copy_len; - if (buf_copy_len > p->len) { - /* this pbuf cannot hold all remaining data */ - buf_copy_len = p->len; - } - /* copy the necessary parts of the buffer */ - MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len); - total_copy_len -= buf_copy_len; - copied_total += buf_copy_len; - } - LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); - return ERR_OK; -} - -/** - * Creates a single pbuf out of a queue of pbufs. - * - * @remark: Either the source pbuf 'p' is freed by this function or the original - * pbuf 'p' is returned, therefore the caller has to check the result! - * - * @param p the source pbuf - * @param layer pbuf_layer of the new pbuf - * - * @return a new, single pbuf (p->next is NULL) - * or the old pbuf if allocation fails - */ -struct pbuf* -pbuf_coalesce(struct pbuf *p, pbuf_layer layer) -{ - struct pbuf *q; - err_t err; - if (p->next == NULL) { - return p; - } - q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); - if (q == NULL) { - /* @todo: what do we do now? */ - return p; - } - err = pbuf_copy(q, p); - LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); - pbuf_free(p); - return q; -} - -#if LWIP_CHECKSUM_ON_COPY -/** - * Copies data into a single pbuf (*not* into a pbuf queue!) and updates - * the checksum while copying - * - * @param p the pbuf to copy data into - * @param start_offset offset of p->payload where to copy the data to - * @param dataptr data to copy into the pbuf - * @param len length of data to copy into the pbuf - * @param chksum pointer to the checksum which is updated - * @return ERR_OK if successful, another error if the data does not fit - * within the (first) pbuf (no pbuf queues!) - */ -err_t -pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum) -{ - u32_t acc; - u16_t copy_chksum; - char *dst_ptr; - LWIP_ASSERT("p != NULL", p != NULL); - LWIP_ASSERT("dataptr != NULL", dataptr != NULL); - LWIP_ASSERT("chksum != NULL", chksum != NULL); - LWIP_ASSERT("len != 0", len != 0); - - if ((start_offset >= p->len) || (start_offset + len > p->len)) { - return ERR_ARG; - } - - dst_ptr = ((char*)p->payload) + start_offset; - copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); - if ((start_offset & 1) != 0) { - copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); - } - acc = *chksum; - acc += copy_chksum; - *chksum = FOLD_U32T(acc); - return ERR_OK; -} -#endif /* LWIP_CHECKSUM_ON_COPY */ - - /** Get one byte from the specified position in a pbuf - * WARNING: returns zero for offset >= p->tot_len - * - * @param p pbuf to parse - * @param offset offset into p of the byte to return - * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len - */ -u8_t -pbuf_get_at(struct pbuf* p, u16_t offset) -{ - u16_t copy_from = offset; - struct pbuf* q = p; - - /* get the correct pbuf */ - while ((q != NULL) && (q->len <= copy_from)) { - copy_from -= q->len; - q = q->next; - } - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->len > copy_from)) { - return ((u8_t*)q->payload)[copy_from]; - } - return 0; -} - -/** Compare pbuf contents at specified offset with memory s2, both of length n - * - * @param p pbuf to compare - * @param offset offset into p at wich to start comparing - * @param s2 buffer to compare - * @param n length of buffer to compare - * @return zero if equal, nonzero otherwise - * (0xffff if p is too short, diffoffset+1 otherwise) - */ -u16_t -pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n) -{ - u16_t start = offset; - struct pbuf* q = p; - - /* get the correct pbuf */ - while ((q != NULL) && (q->len <= start)) { - start -= q->len; - q = q->next; - } - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->len > start)) { - u16_t i; - for(i = 0; i < n; i++) { - u8_t a = pbuf_get_at(q, start + i); - u8_t b = ((u8_t*)s2)[i]; - if (a != b) { - return i+1; - } - } - return 0; - } - return 0xffff; -} - -/** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset - * start_offset. - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param mem search for the contents of this buffer - * @param mem_len length of 'mem' - * @param start_offset offset into p at which to start searching - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset) -{ - u16_t i; - u16_t max = p->tot_len - mem_len; - if (p->tot_len >= mem_len + start_offset) { - for(i = start_offset; i <= max; ) { - u16_t plus = pbuf_memcmp(p, i, mem, mem_len); - if (plus == 0) { - return i; - } else { - i += plus; - } - } - } - return 0xFFFF; -} - -/** Find occurrence of substr with length substr_len in pbuf p, start at offset - * start_offset - * WARNING: in contrast to strstr(), this one does not stop at the first \0 in - * the pbuf/source string! - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param substr string to search for in p, maximum length is 0xFFFE - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_strstr(struct pbuf* p, const char* substr) -{ - size_t substr_len; - if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { - return 0xFFFF; - } - substr_len = strlen(substr); - if (substr_len >= 0xFFFF) { - return 0xFFFF; - } - return pbuf_memfind(p, substr, (u16_t)substr_len, 0); -} diff --git a/external/badvpn_dns/lwip/src/core/raw.c b/external/badvpn_dns/lwip/src/core/raw.c deleted file mode 100644 index 68b23c6..0000000 --- a/external/badvpn_dns/lwip/src/core/raw.c +++ /dev/null @@ -1,422 +0,0 @@ -/** - * @file - * Implementation of raw protocol PCBs for low-level handling of - * different types of protocols besides (or overriding) those - * already available in lwIP. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/raw.h" -#include "lwip/stats.h" -#include "arch/perf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#include <string.h> - -/** The list of RAW PCBs */ -static struct raw_pcb *raw_pcbs; - -/** - * Determine if in incoming IP packet is covered by a RAW PCB - * and if so, pass it to a user-provided receive callback function. - * - * Given an incoming IP datagram (as a chain of pbufs) this function - * finds a corresponding RAW PCB and calls the corresponding receive - * callback function. - * - * @param p pbuf to be demultiplexed to a RAW PCB. - * @param inp network interface on which the datagram was received. - * @return - 1 if the packet has been eaten by a RAW PCB receive - * callback function. The caller MAY NOT not reference the - * packet any longer, and MAY NOT call pbuf_free(). - * @return - 0 if packet is not eaten (pbuf is still referenced by the - * caller). - * - */ -u8_t -raw_input(struct pbuf *p, struct netif *inp) -{ - struct raw_pcb *pcb, *prev; - struct ip_hdr *iphdr; - s16_t proto; - u8_t eaten = 0; -#if LWIP_IPV6 - struct ip6_hdr *ip6hdr; -#endif /* LWIP_IPV6 */ - - - LWIP_UNUSED_ARG(inp); - - iphdr = (struct ip_hdr *)p->payload; -#if LWIP_IPV6 - if (IPH_V(iphdr) == 6) { - ip6hdr = (struct ip6_hdr *)p->payload; - proto = IP6H_NEXTH(ip6hdr); - } - else -#endif /* LWIP_IPV6 */ - { - proto = IPH_PROTO(iphdr); - } - - prev = NULL; - pcb = raw_pcbs; - /* loop through all raw pcbs until the packet is eaten by one */ - /* this allows multiple pcbs to match against the packet by design */ - while ((eaten == 0) && (pcb != NULL)) { - if ((pcb->protocol == proto) && IP_PCB_IPVER_INPUT_MATCH(pcb) && - (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip) || - ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) { -#if IP_SOF_BROADCAST_RECV - /* broadcast filter? */ - if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) -#if LWIP_IPV6 - && !PCB_ISIPV6(pcb) -#endif /* LWIP_IPV6 */ - ) -#endif /* IP_SOF_BROADCAST_RECV */ - { - /* receive callback function available? */ - if (pcb->recv.ip4 != NULL) { -#ifndef LWIP_NOASSERT - void* old_payload = p->payload; -#endif - /* the receive callback function did not eat the packet? */ - eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr()); - if (eaten != 0) { - /* receive function ate the packet */ - p = NULL; - eaten = 1; - if (prev != NULL) { - /* move the pcb to the front of raw_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - } else { - /* sanity-check that the receive callback did not alter the pbuf */ - LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet", - p->payload == old_payload); - } - } - /* no receive callback function was set for this raw PCB */ - } - /* drop the packet */ - } - prev = pcb; - pcb = pcb->next; - } - return eaten; -} - -/** - * Bind a RAW PCB. - * - * @param pcb RAW PCB to be bound with a local address ipaddr. - * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to - * bind to all local interfaces. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occured. - * - ERR_USE. The specified IP address is already bound to by - * another RAW PCB. - * - * @see raw_disconnect() - */ -err_t -raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) -{ - ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->local_ip, ipaddr); - return ERR_OK; -} - -/** - * Connect an RAW PCB. This function is required by upper layers - * of lwip. Using the raw api you could use raw_sendto() instead - * - * This will associate the RAW PCB with the remote address. - * - * @param pcb RAW PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * - * @return lwIP error code - * - * @see raw_disconnect() and raw_sendto() - */ -err_t -raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr) -{ - ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->remote_ip, ipaddr); - return ERR_OK; -} - - -/** - * Set the callback function for received packets that match the - * raw PCB's protocol and binding. - * - * The callback function MUST either - * - eat the packet by calling pbuf_free() and returning non-zero. The - * packet will not be passed to other raw PCBs or other protocol layers. - * - not free the packet, and return zero. The packet will be matched - * against further PCBs and/or forwarded to another protocol layers. - * - * @return non-zero if the packet was free()d, zero if the packet remains - * available for others. - */ -void -raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) -{ - /* remember recv() callback and user data */ - pcb->recv.ip4 = recv; - pcb->recv_arg = recv_arg; -} - -/** - * Send the raw IP packet to the given address. Note that actually you cannot - * modify the IP headers (this is inconsistent with the receive callback where - * you actually get the IP headers), you can only specify the IP payload here. - * It requires some more changes in lwIP. (there will be a raw_send() function - * then.) - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * @param ipaddr the destination address of the IP packet - * - */ -err_t -raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) -{ - err_t err; - struct netif *netif; - ipX_addr_t *src_ip; - struct pbuf *q; /* q will be sent down the stack */ - s16_t header_size; - ipX_addr_t *dst_ip = ip_2_ipX(ipaddr); - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); - - header_size = ( -#if LWIP_IPV6 - PCB_ISIPV6(pcb) ? IP6_HLEN : -#endif /* LWIP_IPV6 */ - IP_HLEN); - - /* not enough space to add an IP header to first pbuf in given p chain? */ - if (pbuf_header(p, header_size)) { - /* allocate header in new pbuf */ - q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p */ - pbuf_chain(q, p); - } - /* { first pbuf q points to header pbuf } */ - LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* first pbuf q equals given pbuf */ - q = p; - if(pbuf_header(q, -header_size)) { - LWIP_ASSERT("Can't restore header we just removed!", 0); - return ERR_MEM; - } - } - - netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip); - if (netif == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip); - /* free any temporary header pbuf allocated by pbuf_header() */ - if (q != p) { - pbuf_free(q); - } - return ERR_RTE; - } - -#if IP_SOF_BROADCAST -#if LWIP_IPV6 - /* @todo: why does IPv6 not filter broadcast with SOF_BROADCAST enabled? */ - if (!PCB_ISIPV6(pcb)) -#endif /* LWIP_IPV6 */ - { - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - /* free any temporary header pbuf allocated by pbuf_header() */ - if (q != p) { - pbuf_free(q); - } - return ERR_VAL; - } - } -#endif /* IP_SOF_BROADCAST */ - - if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { - /* use outgoing network interface IP address as source address */ - src_ip = ipX_netif_get_local_ipX(PCB_ISIPV6(pcb), netif, dst_ip); -#if LWIP_IPV6 - if (src_ip == NULL) { - if (q != p) { - pbuf_free(q); - } - return ERR_RTE; - } -#endif /* LWIP_IPV6 */ - } else { - /* use RAW PCB local IP address as source address */ - src_ip = &pcb->local_ip; - } - - NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); - err = ipX_output_if(PCB_ISIPV6(pcb), q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - /* did we chain a header earlier? */ - if (q != p) { - /* free the header */ - pbuf_free(q); - } - return err; -} - -/** - * Send the raw IP packet to the address given by raw_connect() - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * - */ -err_t -raw_send(struct raw_pcb *pcb, struct pbuf *p) -{ - return raw_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip)); -} - -/** - * Remove an RAW PCB. - * - * @param pcb RAW PCB to be removed. The PCB is removed from the list of - * RAW PCB's and the data structure is freed from memory. - * - * @see raw_new() - */ -void -raw_remove(struct raw_pcb *pcb) -{ - struct raw_pcb *pcb2; - /* pcb to be removed is first in list? */ - if (raw_pcbs == pcb) { - /* make list start at 2nd pcb */ - raw_pcbs = raw_pcbs->next; - /* pcb not 1st in list */ - } else { - for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in raw_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - } - } - } - memp_free(MEMP_RAW_PCB, pcb); -} - -/** - * Create a RAW PCB. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new(u8_t proto) -{ - struct raw_pcb *pcb; - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); - - pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); - /* could allocate RAW PCB? */ - if (pcb != NULL) { - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct raw_pcb)); - pcb->protocol = proto; - pcb->ttl = RAW_TTL; - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - return pcb; -} - -#if LWIP_IPV6 -/** - * Create a RAW PCB for IPv6. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param proto the protocol number (next header) of the IPv6 packet payload - * (e.g. IP6_NEXTH_ICMP6) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new_ip6(u8_t proto) -{ - struct raw_pcb *pcb; - pcb = raw_new(proto); - ip_set_v6(pcb, 1); - return pcb; -} -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_RAW */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/asn1_dec.c b/external/badvpn_dns/lwip/src/core/snmp/asn1_dec.c deleted file mode 100644 index 1d56582..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/asn1_dec.c +++ /dev/null @@ -1,657 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) decoding - * - * @todo not optimised (yet), favor correctness over speed, favor speed over size - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_asn1.h" - -/** - * Retrieves type field from incoming pbuf chain. - * - * @param p points to a pbuf holding an ASN1 coded type field - * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field - * @param type return ASN1 type - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - *type = *msg_ptr; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes length field from incoming pbuf chain into host length. - * - * @param p points to a pbuf holding an ASN1 coded length - * @param ofs points to the offset within the pbuf chain of the ASN1 coded length - * @param octets_used returns number of octets used by the length code - * @param length return host order length, upto 64k - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (*msg_ptr < 0x80) - { - /* primitive definite length format */ - *octets_used = 1; - *length = *msg_ptr; - return ERR_OK; - } - else if (*msg_ptr == 0x80) - { - /* constructed indefinite length format, termination with two zero octets */ - u8_t zeros; - u8_t i; - - *length = 0; - zeros = 0; - while (zeros != 2) - { - i = 2; - while (i > 0) - { - i--; - (*length) += 1; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (*msg_ptr == 0) - { - zeros++; - if (zeros == 2) - { - /* stop while (i > 0) */ - i = 0; - } - } - else - { - zeros = 0; - } - } - } - *octets_used = 1; - return ERR_OK; - } - else if (*msg_ptr == 0x81) - { - /* constructed definite length format, one octet */ - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - *length = *msg_ptr; - *octets_used = 2; - return ERR_OK; - } - else if (*msg_ptr == 0x82) - { - u8_t i; - - /* constructed definite length format, two octets */ - i = 2; - while (i > 0) - { - i--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (i == 0) - { - /* least significant length octet */ - *length |= *msg_ptr; - } - else - { - /* most significant length octet */ - *length = (*msg_ptr) << 8; - } - } - *octets_used = 3; - return ERR_OK; - } - else - { - /* constructed definite length format 3..127 octets, this is too big (>64k) */ - /** @todo: do we need to accept inefficient codings with many leading zero's? */ - *octets_used = 1 + ((*msg_ptr) & 0x7f); - return ERR_ARG; - } - } - p = p->next; - } - - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes positive integer (counter, gauge, timeticks) into u32_t. - * - * @param p points to a pbuf holding an ASN1 coded integer - * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -err_t -snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if ((len > 0) && (len < 6)) - { - /* start from zero */ - *value = 0; - if (*msg_ptr & 0x80) - { - /* negative, expecting zero sign bit! */ - return ERR_ARG; - } - else - { - /* positive */ - if ((len > 1) && (*msg_ptr == 0)) - { - /* skip leading "sign byte" octet 0x00 */ - len--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - } - /* OR octets with value */ - while (len > 1) - { - len--; - *value |= *msg_ptr; - *value <<= 8; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - *value |= *msg_ptr; - return ERR_OK; - } - else - { - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes integer into s32_t. - * - * @param p points to a pbuf holding an ASN1 coded integer - * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed! - */ -err_t -snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value) -{ - u16_t plen, base; - u8_t *msg_ptr; -#if BYTE_ORDER == LITTLE_ENDIAN - u8_t *lsb_ptr = (u8_t*)value; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; -#endif - u8_t sign; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if ((len > 0) && (len < 5)) - { - if (*msg_ptr & 0x80) - { - /* negative, start from -1 */ - *value = -1; - sign = 1; - } - else - { - /* positive, start from 0 */ - *value = 0; - sign = 0; - } - /* OR/AND octets with value */ - while (len > 1) - { - len--; - if (sign) - { - *lsb_ptr &= *msg_ptr; - *value <<= 8; - *lsb_ptr |= 255; - } - else - { - *lsb_ptr |= *msg_ptr; - *value <<= 8; - } - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (sign) - { - *lsb_ptr &= *msg_ptr; - } - else - { - *lsb_ptr |= *msg_ptr; - } - return ERR_OK; - } - else - { - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes object identifier from incoming message into array of s32_t. - * - * @param p points to a pbuf holding an ASN1 coded object identifier - * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier - * @param len length of the coded object identifier - * @param oid return object identifier struct - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid) -{ - u16_t plen, base; - u8_t *msg_ptr; - s32_t *oid_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - oid->len = 0; - oid_ptr = &oid->id[0]; - if (len > 0) - { - /* first compressed octet */ - if (*msg_ptr == 0x2B) - { - /* (most) common case 1.3 (iso.org) */ - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = 3; - oid_ptr++; - } - else if (*msg_ptr < 40) - { - *oid_ptr = 0; - oid_ptr++; - *oid_ptr = *msg_ptr; - oid_ptr++; - } - else if (*msg_ptr < 80) - { - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = (*msg_ptr) - 40; - oid_ptr++; - } - else - { - *oid_ptr = 2; - oid_ptr++; - *oid_ptr = (*msg_ptr) - 80; - oid_ptr++; - } - oid->len = 2; - } - else - { - /* accepting zero length identifiers e.g. for - getnext operation. uncommon but valid */ - return ERR_OK; - } - len--; - if (len > 0) - { - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) - { - /* sub-identifier uses multiple octets */ - if (*msg_ptr & 0x80) - { - s32_t sub_id = 0; - - while ((*msg_ptr & 0x80) && (len > 1)) - { - len--; - sub_id = (sub_id << 7) + (*msg_ptr & ~0x80); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (!(*msg_ptr & 0x80) && (len > 0)) - { - /* last octet sub-identifier */ - len--; - sub_id = (sub_id << 7) + *msg_ptr; - *oid_ptr = sub_id; - } - } - else - { - /* !(*msg_ptr & 0x80) sub-identifier uses single octet */ - len--; - *oid_ptr = *msg_ptr; - } - if (len > 0) - { - /* remaining oid bytes available ... */ - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - oid_ptr++; - oid->len++; - } - if (len == 0) - { - /* len == 0, end of oid */ - return ERR_OK; - } - else - { - /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ - return ERR_ARG; - } - - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) - * from incoming message into array. - * - * @param p points to a pbuf holding an ASN1 coded raw data - * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data - * @param len length of the coded raw data (zero is valid, e.g. empty string!) - * @param raw_len length of the raw return value - * @param raw return raw bytes - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw) -{ - u16_t plen, base; - u8_t *msg_ptr; - - if (len > 0) - { - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if (raw_len >= len) - { - while (len > 1) - { - /* copy len - 1 octets */ - len--; - *raw = *msg_ptr; - raw++; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* copy last octet */ - *raw = *msg_ptr; - return ERR_OK; - } - else - { - /* raw_len < len, not enough dst space */ - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; - } - else - { - /* len == 0, empty string */ - return ERR_OK; - } -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/asn1_enc.c b/external/badvpn_dns/lwip/src/core/snmp/asn1_enc.c deleted file mode 100644 index 64dfc5f..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/asn1_enc.c +++ /dev/null @@ -1,611 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) encoding - * - * @todo not optimised (yet), favor correctness over speed, favor speed over size - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_asn1.h" - -/** - * Returns octet count for length. - * - * @param length - * @param octets_needed points to the return value - */ -void -snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) -{ - if (length < 0x80U) - { - *octets_needed = 1; - } - else if (length < 0x100U) - { - *octets_needed = 2; - } - else - { - *octets_needed = 3; - } -} - -/** - * Returns octet count for an u32_t. - * - * @param value - * @param octets_needed points to the return value - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -void -snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) -{ - if (value < 0x80UL) - { - *octets_needed = 1; - } - else if (value < 0x8000UL) - { - *octets_needed = 2; - } - else if (value < 0x800000UL) - { - *octets_needed = 3; - } - else if (value < 0x80000000UL) - { - *octets_needed = 4; - } - else - { - *octets_needed = 5; - } -} - -/** - * Returns octet count for an s32_t. - * - * @param value - * @param octets_needed points to the return value - * - * @note ASN coded integers are _always_ signed. - */ -void -snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) -{ - if (value < 0) - { - value = ~value; - } - if (value < 0x80L) - { - *octets_needed = 1; - } - else if (value < 0x8000L) - { - *octets_needed = 2; - } - else if (value < 0x800000L) - { - *octets_needed = 3; - } - else - { - *octets_needed = 4; - } -} - -/** - * Returns octet count for an object identifier. - * - * @param ident_len object identifier array length - * @param ident points to object identifier array - * @param octets_needed points to the return value - */ -void -snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed) -{ - s32_t sub_id; - u8_t cnt; - - cnt = 0; - if (ident_len > 1) - { - /* compressed prefix in one octet */ - cnt++; - ident_len -= 2; - ident += 2; - } - while(ident_len > 0) - { - ident_len--; - sub_id = *ident; - - sub_id >>= 7; - cnt++; - while(sub_id > 0) - { - sub_id >>= 7; - cnt++; - } - ident++; - } - *octets_needed = cnt; -} - -/** - * Encodes ASN type field into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @param type input ASN1 type - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - *msg_ptr = type; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes host order length field into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode length into - * @param ofs points to the offset within the pbuf chain - * @param length is the host order length to be encoded - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (length < 0x80) - { - *msg_ptr = (u8_t)length; - return ERR_OK; - } - else if (length < 0x100) - { - *msg_ptr = 0x81; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - *msg_ptr = (u8_t)length; - return ERR_OK; - } - else - { - u8_t i; - - /* length >= 0x100 && length <= 0xFFFF */ - *msg_ptr = 0x82; - i = 2; - while (i > 0) - { - i--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (i == 0) - { - /* least significant length octet */ - *msg_ptr = (u8_t)length; - } - else - { - /* most significant length octet */ - *msg_ptr = (u8_t)(length >> 8); - } - } - return ERR_OK; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) - * @param value is the host order u32_t value to be encoded - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_u32t_cnt() - */ -err_t -snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (octets_needed == 5) - { - /* not enough bits in 'value' add leading 0x00 */ - octets_needed--; - *msg_ptr = 0x00; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - while (octets_needed > 1) - { - octets_needed--; - *msg_ptr = (u8_t)(value >> (octets_needed << 3)); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* (only) one least significant octet */ - *msg_ptr = (u8_t)value; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes s32_t integer into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) - * @param value is the host order s32_t value to be encoded - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_s32t_cnt() - */ -err_t -snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - while (octets_needed > 1) - { - octets_needed--; - *msg_ptr = (u8_t)(value >> (octets_needed << 3)); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* (only) one least significant octet */ - *msg_ptr = (u8_t)value; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes object identifier into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode oid into - * @param ofs points to the offset within the pbuf chain - * @param ident_len object identifier array length - * @param ident points to object identifier array - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (ident_len > 1) - { - if ((ident[0] == 1) && (ident[1] == 3)) - { - /* compressed (most common) prefix .iso.org */ - *msg_ptr = 0x2b; - } - else - { - /* calculate prefix */ - *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]); - } - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - ident_len -= 2; - ident += 2; - } - else - { -/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ - /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ - return ERR_ARG; - } - while (ident_len > 0) - { - s32_t sub_id; - u8_t shift, tail; - - ident_len--; - sub_id = *ident; - tail = 0; - shift = 28; - while(shift > 0) - { - u8_t code; - - code = (u8_t)(sub_id >> shift); - if ((code != 0) || (tail != 0)) - { - tail = 1; - *msg_ptr = code | 0x80; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - shift -= 7; - } - *msg_ptr = (u8_t)sub_id & 0x7F; - if (ident_len > 0) - { - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* proceed to next sub-identifier */ - ident++; - } - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode raw data into - * @param ofs points to the offset within the pbuf chain - * @param raw_len raw data length - * @param raw points raw data - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - while (raw_len > 1) - { - /* copy raw_len - 1 octets */ - raw_len--; - *msg_ptr = *raw; - raw++; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (raw_len > 0) - { - /* copy last or single octet */ - *msg_ptr = *raw; - } - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/mib2.c b/external/badvpn_dns/lwip/src/core/snmp/mib2.c deleted file mode 100644 index dcd3b62..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/mib2.c +++ /dev/null @@ -1,4146 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) objects and functions. - * - * @note the object identifiers for this MIB-2 and private MIB tree - * must be kept in sorted ascending order. This to ensure correct getnext operation. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" -#include "lwip/netif.h" -#include "lwip/ip.h" -#include "lwip/ip_frag.h" -#include "lwip/mem.h" -#include "lwip/tcp_impl.h" -#include "lwip/udp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_structs.h" -#include "lwip/sys.h" -#include "netif/etharp.h" - -/** - * IANA assigned enterprise ID for lwIP is 26381 - * @see http://www.iana.org/assignments/enterprise-numbers - * - * @note this enterprise ID is assigned to the lwIP project, - * all object identifiers living under this ID are assigned - * by the lwIP maintainers (contact Christiaan Simons)! - * @note don't change this define, use snmp_set_sysobjid() - * - * If you need to create your own private MIB you'll need - * to apply for your own enterprise ID with IANA: - * http://www.iana.org/numbers.html - */ -#define SNMP_ENTERPRISE_ID 26381 -#define SNMP_SYSOBJID_LEN 7 -#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID} - -#ifndef SNMP_SYSSERVICES -#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) -#endif - -#ifndef SNMP_GET_SYSUPTIME -#define SNMP_GET_SYSUPTIME(sysuptime) (sysuptime = (sys_now() / 10)) -#endif - -static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void system_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t system_set_test(struct obj_def *od, u16_t len, void *value); -static void system_set_value(struct obj_def *od, u16_t len, void *value); -static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void interfaces_get_value(struct obj_def *od, u16_t len, void *value); -static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ifentry_get_value(struct obj_def *od, u16_t len, void *value); -#if !SNMP_SAFE_REQUESTS -static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value); -static void ifentry_set_value (struct obj_def *od, u16_t len, void *value); -#endif /* SNMP_SAFE_REQUESTS */ -static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void atentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value); -static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value); -static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void icmp_get_value(struct obj_def *od, u16_t len, void *value); -#if LWIP_TCP -static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void tcp_get_value(struct obj_def *od, u16_t len, void *value); -#ifdef THIS_SEEMS_UNUSED -static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value); -#endif -#endif -static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void udp_get_value(struct obj_def *od, u16_t len, void *value); -static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void udpentry_get_value(struct obj_def *od, u16_t len, void *value); -static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void snmp_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value); -static void snmp_set_value(struct obj_def *od, u16_t len, void *value); - - -/* snmp .1.3.6.1.2.1.11 */ -const mib_scalar_node snmp_scalar = { - &snmp_get_object_def, - &snmp_get_value, - &snmp_set_test, - &snmp_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t snmp_ids[28] = { - 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30 -}; -struct mib_node* const snmp_nodes[28] = { - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar -}; -const struct mib_array_node snmp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 28, - snmp_ids, - snmp_nodes -}; - -/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ -/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ -/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ - -/* udp .1.3.6.1.2.1.7 */ -/** index root node for udpTable */ -struct mib_list_rootnode udp_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t udpentry_ids[2] = { 1, 2 }; -struct mib_node* const udpentry_nodes[2] = { - (struct mib_node*)&udp_root, (struct mib_node*)&udp_root, -}; -const struct mib_array_node udpentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - udpentry_ids, - udpentry_nodes -}; - -s32_t udptable_id = 1; -struct mib_node* udptable_node = (struct mib_node*)&udpentry; -struct mib_ram_array_node udptable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &udptable_id, - &udptable_node -}; - -const mib_scalar_node udp_scalar = { - &udp_get_object_def, - &udp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const udp_nodes[5] = { - (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, - (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, - (struct mib_node*)&udptable -}; -const struct mib_array_node udp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - udp_ids, - udp_nodes -}; - -/* tcp .1.3.6.1.2.1.6 */ -#if LWIP_TCP -/* only if the TCP protocol is available may implement this group */ -/** index root node for tcpConnTable */ -struct mib_list_rootnode tcpconntree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const tcpconnentry_nodes[5] = { - (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, - (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, - (struct mib_node*)&tcpconntree_root -}; -const struct mib_array_node tcpconnentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - tcpconnentry_ids, - tcpconnentry_nodes -}; - -s32_t tcpconntable_id = 1; -struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry; -struct mib_ram_array_node tcpconntable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, -/** @todo update maxlength when inserting / deleting from table - 0 when table is empty, 1 when more than one entry */ - 0, - &tcpconntable_id, - &tcpconntable_node -}; - -const mib_scalar_node tcp_scalar = { - &tcp_get_object_def, - &tcp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -struct mib_node* const tcp_nodes[15] = { - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar -}; -const struct mib_array_node tcp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 15, - tcp_ids, - tcp_nodes -}; -#endif - -/* icmp .1.3.6.1.2.1.5 */ -const mib_scalar_node icmp_scalar = { - &icmp_get_object_def, - &icmp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; -struct mib_node* const icmp_nodes[26] = { - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar -}; -const struct mib_array_node icmp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 26, - icmp_ids, - icmp_nodes -}; - -/** index root node for ipNetToMediaTable */ -struct mib_list_rootnode ipntomtree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 }; -struct mib_node* const ipntomentry_nodes[4] = { - (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root, - (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root -}; -const struct mib_array_node ipntomentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 4, - ipntomentry_ids, - ipntomentry_nodes -}; - -s32_t ipntomtable_id = 1; -struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry; -struct mib_ram_array_node ipntomtable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &ipntomtable_id, - &ipntomtable_node -}; - -/** index root node for ipRouteTable */ -struct mib_list_rootnode iprtetree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; -struct mib_node* const iprteentry_nodes[13] = { - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root -}; -const struct mib_array_node iprteentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 13, - iprteentry_ids, - iprteentry_nodes -}; - -s32_t iprtetable_id = 1; -struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry; -struct mib_ram_array_node iprtetable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &iprtetable_id, - &iprtetable_node -}; - -/** index root node for ipAddrTable */ -struct mib_list_rootnode ipaddrtree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const ipaddrentry_nodes[5] = { - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root -}; -const struct mib_array_node ipaddrentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - ipaddrentry_ids, - ipaddrentry_nodes -}; - -s32_t ipaddrtable_id = 1; -struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry; -struct mib_ram_array_node ipaddrtable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &ipaddrtable_id, - &ipaddrtable_node -}; - -/* ip .1.3.6.1.2.1.4 */ -const mib_scalar_node ip_scalar = { - &ip_get_object_def, - &ip_get_value, - &ip_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; -struct mib_node* const ip_nodes[23] = { - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable, - (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable, - (struct mib_node*)&ip_scalar -}; -const struct mib_array_node mib2_ip = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 23, - ip_ids, - ip_nodes -}; - -/** index root node for atTable */ -struct mib_list_rootnode arptree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t atentry_ids[3] = { 1, 2, 3 }; -struct mib_node* const atentry_nodes[3] = { - (struct mib_node*)&arptree_root, - (struct mib_node*)&arptree_root, - (struct mib_node*)&arptree_root -}; -const struct mib_array_node atentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 3, - atentry_ids, - atentry_nodes -}; - -const s32_t attable_id = 1; -struct mib_node* const attable_node = (struct mib_node*)&atentry; -const struct mib_array_node attable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - &attable_id, - &attable_node -}; - -/* at .1.3.6.1.2.1.3 */ -s32_t at_id = 1; -struct mib_node* mib2_at_node = (struct mib_node*)&attable; -struct mib_ram_array_node at = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &at_id, - &mib2_at_node -}; - -/** index root node for ifTable */ -struct mib_list_rootnode iflist_root = { - &ifentry_get_object_def, - &ifentry_get_value, -#if SNMP_SAFE_REQUESTS - &noleafs_set_test, - &noleafs_set_value, -#else /* SNMP_SAFE_REQUESTS */ - &ifentry_set_test, - &ifentry_set_value, -#endif /* SNMP_SAFE_REQUESTS */ - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; -struct mib_node* const ifentry_nodes[22] = { - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root -}; -const struct mib_array_node ifentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 22, - ifentry_ids, - ifentry_nodes -}; - -s32_t iftable_id = 1; -struct mib_node* iftable_node = (struct mib_node*)&ifentry; -struct mib_ram_array_node iftable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &iftable_id, - &iftable_node -}; - -/* interfaces .1.3.6.1.2.1.2 */ -const mib_scalar_node interfaces_scalar = { - &interfaces_get_object_def, - &interfaces_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t interfaces_ids[2] = { 1, 2 }; -struct mib_node* const interfaces_nodes[2] = { - (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable -}; -const struct mib_array_node interfaces = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - interfaces_ids, - interfaces_nodes -}; - - -/* 0 1 2 3 4 5 6 */ -/* system .1.3.6.1.2.1.1 */ -const mib_scalar_node sys_tem_scalar = { - &system_get_object_def, - &system_get_value, - &system_set_test, - &system_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 }; -struct mib_node* const sys_tem_nodes[7] = { - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar -}; -/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */ -const struct mib_array_node sys_tem = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 7, - sys_tem_ids, - sys_tem_nodes -}; - -/* mib-2 .1.3.6.1.2.1 */ -#if LWIP_TCP -#define MIB2_GROUPS 8 -#else -#define MIB2_GROUPS 7 -#endif -const s32_t mib2_ids[MIB2_GROUPS] = -{ - 1, - 2, - 3, - 4, - 5, -#if LWIP_TCP - 6, -#endif - 7, - 11 -}; -struct mib_node* const mib2_nodes[MIB2_GROUPS] = { - (struct mib_node*)&sys_tem, - (struct mib_node*)&interfaces, - (struct mib_node*)&at, - (struct mib_node*)&mib2_ip, - (struct mib_node*)&icmp, -#if LWIP_TCP - (struct mib_node*)&tcp, -#endif - (struct mib_node*)&udp, - (struct mib_node*)&snmp -}; - -const struct mib_array_node mib2 = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - MIB2_GROUPS, - mib2_ids, - mib2_nodes -}; - -/* mgmt .1.3.6.1.2 */ -const s32_t mgmt_ids[1] = { 1 }; -struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 }; -const struct mib_array_node mgmt = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - mgmt_ids, - mgmt_nodes -}; - -/* internet .1.3.6.1 */ -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -s32_t internet_ids[2] = { 2, 4 }; -struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private }; -const struct mib_array_node internet = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - internet_ids, - internet_nodes -}; -#else -const s32_t internet_ids[1] = { 2 }; -struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt }; -const struct mib_array_node internet = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - internet_ids, - internet_nodes -}; -#endif - -/** mib-2.system.sysObjectID */ -static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID}; -/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */ -static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}}; -/** mib-2.system.sysServices */ -static const s32_t sysservices = SNMP_SYSSERVICES; - -/** mib-2.system.sysDescr */ -static const u8_t sysdescr_len_default = 4; -static const u8_t sysdescr_default[] = "lwIP"; -static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default; -static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0]; -/** mib-2.system.sysContact */ -static const u8_t syscontact_len_default = 0; -static const u8_t syscontact_default[] = ""; -static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default; -static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0]; -/** mib-2.system.sysName */ -static const u8_t sysname_len_default = 8; -static const u8_t sysname_default[] = "FQDN-unk"; -static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default; -static u8_t* sysname_ptr = (u8_t*)&sysname_default[0]; -/** mib-2.system.sysLocation */ -static const u8_t syslocation_len_default = 0; -static const u8_t syslocation_default[] = ""; -static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default; -static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0]; -/** mib-2.snmp.snmpEnableAuthenTraps */ -static const u8_t snmpenableauthentraps_default = 2; /* disabled */ -static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; - -/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */ -static const struct snmp_obj_id ifspecific = {2, {0, 0}}; -/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ -static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; - - - -/* mib-2.system counter(s) */ -static u32_t sysuptime = 0; - -/* mib-2.ip counter(s) */ -static u32_t ipinreceives = 0, - ipinhdrerrors = 0, - ipinaddrerrors = 0, - ipforwdatagrams = 0, - ipinunknownprotos = 0, - ipindiscards = 0, - ipindelivers = 0, - ipoutrequests = 0, - ipoutdiscards = 0, - ipoutnoroutes = 0, - ipreasmreqds = 0, - ipreasmoks = 0, - ipreasmfails = 0, - ipfragoks = 0, - ipfragfails = 0, - ipfragcreates = 0, - iproutingdiscards = 0; -/* mib-2.icmp counter(s) */ -static u32_t icmpinmsgs = 0, - icmpinerrors = 0, - icmpindestunreachs = 0, - icmpintimeexcds = 0, - icmpinparmprobs = 0, - icmpinsrcquenchs = 0, - icmpinredirects = 0, - icmpinechos = 0, - icmpinechoreps = 0, - icmpintimestamps = 0, - icmpintimestampreps = 0, - icmpinaddrmasks = 0, - icmpinaddrmaskreps = 0, - icmpoutmsgs = 0, - icmpouterrors = 0, - icmpoutdestunreachs = 0, - icmpouttimeexcds = 0, - icmpoutparmprobs = 0, - icmpoutsrcquenchs = 0, - icmpoutredirects = 0, - icmpoutechos = 0, - icmpoutechoreps = 0, - icmpouttimestamps = 0, - icmpouttimestampreps = 0, - icmpoutaddrmasks = 0, - icmpoutaddrmaskreps = 0; -/* mib-2.tcp counter(s) */ -static u32_t tcpactiveopens = 0, - tcppassiveopens = 0, - tcpattemptfails = 0, - tcpestabresets = 0, - tcpinsegs = 0, - tcpoutsegs = 0, - tcpretranssegs = 0, - tcpinerrs = 0, - tcpoutrsts = 0; -/* mib-2.udp counter(s) */ -static u32_t udpindatagrams = 0, - udpnoports = 0, - udpinerrors = 0, - udpoutdatagrams = 0; -/* mib-2.snmp counter(s) */ -static u32_t snmpinpkts = 0, - snmpoutpkts = 0, - snmpinbadversions = 0, - snmpinbadcommunitynames = 0, - snmpinbadcommunityuses = 0, - snmpinasnparseerrs = 0, - snmpintoobigs = 0, - snmpinnosuchnames = 0, - snmpinbadvalues = 0, - snmpinreadonlys = 0, - snmpingenerrs = 0, - snmpintotalreqvars = 0, - snmpintotalsetvars = 0, - snmpingetrequests = 0, - snmpingetnexts = 0, - snmpinsetrequests = 0, - snmpingetresponses = 0, - snmpintraps = 0, - snmpouttoobigs = 0, - snmpoutnosuchnames = 0, - snmpoutbadvalues = 0, - snmpoutgenerrs = 0, - snmpoutgetrequests = 0, - snmpoutgetnexts = 0, - snmpoutsetrequests = 0, - snmpoutgetresponses = 0, - snmpouttraps = 0; - - - -/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */ -/** - * Copy octet string. - * - * @param dst points to destination - * @param src points to source - * @param n number of octets to copy. - */ -static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n) -{ - u16_t i = n; - while (i > 0) { - i--; - *dst++ = *src++; - } -} - -/** - * Copy object identifier (s32_t) array. - * - * @param dst points to destination - * @param src points to source - * @param n number of sub identifiers to copy. - */ -void objectidncpy(s32_t *dst, s32_t *src, u8_t n) -{ - u8_t i = n; - while(i > 0) { - i--; - *dst++ = *src++; - } -} - -/** - * Initializes sysDescr pointers. - * - * @param str if non-NULL then copy str pointer - * @param len points to string length, excluding zero terminator - */ -void snmp_set_sysdesr(u8_t *str, u8_t *len) -{ - if (str != NULL) - { - sysdescr_ptr = str; - sysdescr_len_ptr = len; - } -} - -void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid) -{ - *oid = &sysobjid; -} - -/** - * Initializes sysObjectID value. - * - * @param oid points to stuct snmp_obj_id to copy - */ -void snmp_set_sysobjid(struct snmp_obj_id *oid) -{ - sysobjid = *oid; -} - -/** - * Must be called at regular 10 msec interval from a timer interrupt - * or signal handler depending on your runtime environment. - */ -void snmp_inc_sysuptime(void) -{ - sysuptime++; -} - -void snmp_add_sysuptime(u32_t value) -{ - sysuptime+=value; -} - -void snmp_get_sysuptime(u32_t *value) -{ - SNMP_GET_SYSUPTIME(sysuptime); - *value = sysuptime; -} - -/** - * Initializes sysContact pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - syscontact_ptr = ocstr; - syscontact_len_ptr = ocstrlen; - } -} - -/** - * Initializes sysName pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - sysname_ptr = ocstr; - sysname_len_ptr = ocstrlen; - } -} - -/** - * Initializes sysLocation pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - syslocation_ptr = ocstr; - syslocation_len_ptr = ocstrlen; - } -} - - -void snmp_add_ifinoctets(struct netif *ni, u32_t value) -{ - ni->ifinoctets += value; -} - -void snmp_inc_ifinucastpkts(struct netif *ni) -{ - (ni->ifinucastpkts)++; -} - -void snmp_inc_ifinnucastpkts(struct netif *ni) -{ - (ni->ifinnucastpkts)++; -} - -void snmp_inc_ifindiscards(struct netif *ni) -{ - (ni->ifindiscards)++; -} - -void snmp_add_ifoutoctets(struct netif *ni, u32_t value) -{ - ni->ifoutoctets += value; -} - -void snmp_inc_ifoutucastpkts(struct netif *ni) -{ - (ni->ifoutucastpkts)++; -} - -void snmp_inc_ifoutnucastpkts(struct netif *ni) -{ - (ni->ifoutnucastpkts)++; -} - -void snmp_inc_ifoutdiscards(struct netif *ni) -{ - (ni->ifoutdiscards)++; -} - -void snmp_inc_iflist(void) -{ - struct mib_list_node *if_node = NULL; - - snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node); - /* enable getnext traversal on filled table */ - iftable.maxlength = 1; -} - -void snmp_dec_iflist(void) -{ - snmp_mib_node_delete(&iflist_root, iflist_root.tail); - /* disable getnext traversal on empty table */ - if(iflist_root.count == 0) iftable.maxlength = 0; -} - -/** - * Inserts ARP table indexes (.xIfIndex.xNetAddress) - * into arp table index trees (both atTable and ipNetToMediaTable). - */ -void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip) -{ - struct mib_list_rootnode *at_rn; - struct mib_list_node *at_node; - s32_t arpidx[5]; - u8_t level, tree; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_netiftoifindex(ni, &arpidx[0]); - snmp_iptooid(ip, &arpidx[1]); - - for (tree = 0; tree < 2; tree++) - { - if (tree == 0) - { - at_rn = &arptree_root; - } - else - { - at_rn = &ipntomtree_root; - } - for (level = 0; level < 5; level++) - { - at_node = NULL; - snmp_mib_node_insert(at_rn, arpidx[level], &at_node); - if ((level != 4) && (at_node != NULL)) - { - if (at_node->nptr == NULL) - { - at_rn = snmp_mib_lrn_alloc(); - at_node->nptr = (struct mib_node*)at_rn; - if (at_rn != NULL) - { - if (level == 3) - { - if (tree == 0) - { - at_rn->get_object_def = atentry_get_object_def; - at_rn->get_value = atentry_get_value; - } - else - { - at_rn->get_object_def = ip_ntomentry_get_object_def; - at_rn->get_value = ip_ntomentry_get_value; - } - at_rn->set_test = noleafs_set_test; - at_rn->set_value = noleafs_set_value; - } - } - else - { - /* at_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full")); - break; - } - } - else - { - at_rn = (struct mib_list_rootnode*)at_node->nptr; - } - } - } - } - /* enable getnext traversal on filled tables */ - at.maxlength = 1; - ipntomtable.maxlength = 1; -} - -/** - * Removes ARP table indexes (.xIfIndex.xNetAddress) - * from arp table index trees. - */ -void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip) -{ - struct mib_list_rootnode *at_rn, *next, *del_rn[5]; - struct mib_list_node *at_n, *del_n[5]; - s32_t arpidx[5]; - u8_t fc, tree, level, del_cnt; - - snmp_netiftoifindex(ni, &arpidx[0]); - snmp_iptooid(ip, &arpidx[1]); - - for (tree = 0; tree < 2; tree++) - { - /* mark nodes for deletion */ - if (tree == 0) - { - at_rn = &arptree_root; - } - else - { - at_rn = &ipntomtree_root; - } - level = 0; - del_cnt = 0; - while ((level < 5) && (at_rn != NULL)) - { - fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n); - if (fc == 0) - { - /* arpidx[level] does not exist */ - del_cnt = 0; - at_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = at_rn; - del_n[del_cnt] = at_n; - del_cnt++; - at_rn = (struct mib_list_rootnode*)(at_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - at_rn = (struct mib_list_rootnode*)(at_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - at_rn = del_rn[del_cnt]; - at_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(at_rn, at_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty tables */ - if(arptree_root.count == 0) at.maxlength = 0; - if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0; -} - -void snmp_inc_ipinreceives(void) -{ - ipinreceives++; -} - -void snmp_inc_ipinhdrerrors(void) -{ - ipinhdrerrors++; -} - -void snmp_inc_ipinaddrerrors(void) -{ - ipinaddrerrors++; -} - -void snmp_inc_ipforwdatagrams(void) -{ - ipforwdatagrams++; -} - -void snmp_inc_ipinunknownprotos(void) -{ - ipinunknownprotos++; -} - -void snmp_inc_ipindiscards(void) -{ - ipindiscards++; -} - -void snmp_inc_ipindelivers(void) -{ - ipindelivers++; -} - -void snmp_inc_ipoutrequests(void) -{ - ipoutrequests++; -} - -void snmp_inc_ipoutdiscards(void) -{ - ipoutdiscards++; -} - -void snmp_inc_ipoutnoroutes(void) -{ - ipoutnoroutes++; -} - -void snmp_inc_ipreasmreqds(void) -{ - ipreasmreqds++; -} - -void snmp_inc_ipreasmoks(void) -{ - ipreasmoks++; -} - -void snmp_inc_ipreasmfails(void) -{ - ipreasmfails++; -} - -void snmp_inc_ipfragoks(void) -{ - ipfragoks++; -} - -void snmp_inc_ipfragfails(void) -{ - ipfragfails++; -} - -void snmp_inc_ipfragcreates(void) -{ - ipfragcreates++; -} - -void snmp_inc_iproutingdiscards(void) -{ - iproutingdiscards++; -} - -/** - * Inserts ipAddrTable indexes (.ipAdEntAddr) - * into index tree. - */ -void snmp_insert_ipaddridx_tree(struct netif *ni) -{ - struct mib_list_rootnode *ipa_rn; - struct mib_list_node *ipa_node; - s32_t ipaddridx[4]; - u8_t level; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); - - level = 0; - ipa_rn = &ipaddrtree_root; - while (level < 4) - { - ipa_node = NULL; - snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node); - if ((level != 3) && (ipa_node != NULL)) - { - if (ipa_node->nptr == NULL) - { - ipa_rn = snmp_mib_lrn_alloc(); - ipa_node->nptr = (struct mib_node*)ipa_rn; - if (ipa_rn != NULL) - { - if (level == 2) - { - ipa_rn->get_object_def = ip_addrentry_get_object_def; - ipa_rn->get_value = ip_addrentry_get_value; - ipa_rn->set_test = noleafs_set_test; - ipa_rn->set_value = noleafs_set_value; - } - } - else - { - /* ipa_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full")); - break; - } - } - else - { - ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr; - } - } - level++; - } - /* enable getnext traversal on filled table */ - ipaddrtable.maxlength = 1; -} - -/** - * Removes ipAddrTable indexes (.ipAdEntAddr) - * from index tree. - */ -void snmp_delete_ipaddridx_tree(struct netif *ni) -{ - struct mib_list_rootnode *ipa_rn, *next, *del_rn[4]; - struct mib_list_node *ipa_n, *del_n[4]; - s32_t ipaddridx[4]; - u8_t fc, level, del_cnt; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); - - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - ipa_rn = &ipaddrtree_root; - while ((level < 4) && (ipa_rn != NULL)) - { - fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n); - if (fc == 0) - { - /* ipaddridx[level] does not exist */ - del_cnt = 0; - ipa_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = ipa_rn; - del_n[del_cnt] = ipa_n; - del_cnt++; - ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - ipa_rn = del_rn[del_cnt]; - ipa_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(ipa_rn, ipa_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - /* disable getnext traversal on empty table */ - if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0; -} - -/** - * Inserts ipRouteTable indexes (.ipRouteDest) - * into index tree. - * - * @param dflt non-zero for the default rte, zero for network rte - * @param ni points to network interface for this rte - * - * @todo record sysuptime for _this_ route when it is installed - * (needed for ipRouteAge) in the netif. - */ -void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni) -{ - u8_t insert = 0; - ip_addr_t dst; - - if (dflt != 0) - { - /* the default route 0.0.0.0 */ - ip_addr_set_any(&dst); - insert = 1; - } - else - { - /* route to the network address */ - ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); - /* exclude 0.0.0.0 network (reserved for default rte) */ - if (!ip_addr_isany(&dst)) { - insert = 1; - } - } - if (insert) - { - struct mib_list_rootnode *iprte_rn; - struct mib_list_node *iprte_node; - s32_t iprteidx[4]; - u8_t level; - - snmp_iptooid(&dst, &iprteidx[0]); - level = 0; - iprte_rn = &iprtetree_root; - while (level < 4) - { - iprte_node = NULL; - snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node); - if ((level != 3) && (iprte_node != NULL)) - { - if (iprte_node->nptr == NULL) - { - iprte_rn = snmp_mib_lrn_alloc(); - iprte_node->nptr = (struct mib_node*)iprte_rn; - if (iprte_rn != NULL) - { - if (level == 2) - { - iprte_rn->get_object_def = ip_rteentry_get_object_def; - iprte_rn->get_value = ip_rteentry_get_value; - iprte_rn->set_test = noleafs_set_test; - iprte_rn->set_value = noleafs_set_value; - } - } - else - { - /* iprte_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full")); - break; - } - } - else - { - iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr; - } - } - level++; - } - } - /* enable getnext traversal on filled table */ - iprtetable.maxlength = 1; -} - -/** - * Removes ipRouteTable indexes (.ipRouteDest) - * from index tree. - * - * @param dflt non-zero for the default rte, zero for network rte - * @param ni points to network interface for this rte or NULL - * for default route to be removed. - */ -void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni) -{ - u8_t del = 0; - ip_addr_t dst; - - if (dflt != 0) - { - /* the default route 0.0.0.0 */ - ip_addr_set_any(&dst); - del = 1; - } - else - { - /* route to the network address */ - ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); - /* exclude 0.0.0.0 network (reserved for default rte) */ - if (!ip_addr_isany(&dst)) { - del = 1; - } - } - if (del) - { - struct mib_list_rootnode *iprte_rn, *next, *del_rn[4]; - struct mib_list_node *iprte_n, *del_n[4]; - s32_t iprteidx[4]; - u8_t fc, level, del_cnt; - - snmp_iptooid(&dst, &iprteidx[0]); - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - iprte_rn = &iprtetree_root; - while ((level < 4) && (iprte_rn != NULL)) - { - fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n); - if (fc == 0) - { - /* iprteidx[level] does not exist */ - del_cnt = 0; - iprte_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = iprte_rn; - del_n[del_cnt] = iprte_n; - del_cnt++; - iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - iprte_rn = del_rn[del_cnt]; - iprte_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(iprte_rn, iprte_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty table */ - if (iprtetree_root.count == 0) iprtetable.maxlength = 0; -} - - -void snmp_inc_icmpinmsgs(void) -{ - icmpinmsgs++; -} - -void snmp_inc_icmpinerrors(void) -{ - icmpinerrors++; -} - -void snmp_inc_icmpindestunreachs(void) -{ - icmpindestunreachs++; -} - -void snmp_inc_icmpintimeexcds(void) -{ - icmpintimeexcds++; -} - -void snmp_inc_icmpinparmprobs(void) -{ - icmpinparmprobs++; -} - -void snmp_inc_icmpinsrcquenchs(void) -{ - icmpinsrcquenchs++; -} - -void snmp_inc_icmpinredirects(void) -{ - icmpinredirects++; -} - -void snmp_inc_icmpinechos(void) -{ - icmpinechos++; -} - -void snmp_inc_icmpinechoreps(void) -{ - icmpinechoreps++; -} - -void snmp_inc_icmpintimestamps(void) -{ - icmpintimestamps++; -} - -void snmp_inc_icmpintimestampreps(void) -{ - icmpintimestampreps++; -} - -void snmp_inc_icmpinaddrmasks(void) -{ - icmpinaddrmasks++; -} - -void snmp_inc_icmpinaddrmaskreps(void) -{ - icmpinaddrmaskreps++; -} - -void snmp_inc_icmpoutmsgs(void) -{ - icmpoutmsgs++; -} - -void snmp_inc_icmpouterrors(void) -{ - icmpouterrors++; -} - -void snmp_inc_icmpoutdestunreachs(void) -{ - icmpoutdestunreachs++; -} - -void snmp_inc_icmpouttimeexcds(void) -{ - icmpouttimeexcds++; -} - -void snmp_inc_icmpoutparmprobs(void) -{ - icmpoutparmprobs++; -} - -void snmp_inc_icmpoutsrcquenchs(void) -{ - icmpoutsrcquenchs++; -} - -void snmp_inc_icmpoutredirects(void) -{ - icmpoutredirects++; -} - -void snmp_inc_icmpoutechos(void) -{ - icmpoutechos++; -} - -void snmp_inc_icmpoutechoreps(void) -{ - icmpoutechoreps++; -} - -void snmp_inc_icmpouttimestamps(void) -{ - icmpouttimestamps++; -} - -void snmp_inc_icmpouttimestampreps(void) -{ - icmpouttimestampreps++; -} - -void snmp_inc_icmpoutaddrmasks(void) -{ - icmpoutaddrmasks++; -} - -void snmp_inc_icmpoutaddrmaskreps(void) -{ - icmpoutaddrmaskreps++; -} - -void snmp_inc_tcpactiveopens(void) -{ - tcpactiveopens++; -} - -void snmp_inc_tcppassiveopens(void) -{ - tcppassiveopens++; -} - -void snmp_inc_tcpattemptfails(void) -{ - tcpattemptfails++; -} - -void snmp_inc_tcpestabresets(void) -{ - tcpestabresets++; -} - -void snmp_inc_tcpinsegs(void) -{ - tcpinsegs++; -} - -void snmp_inc_tcpoutsegs(void) -{ - tcpoutsegs++; -} - -void snmp_inc_tcpretranssegs(void) -{ - tcpretranssegs++; -} - -void snmp_inc_tcpinerrs(void) -{ - tcpinerrs++; -} - -void snmp_inc_tcpoutrsts(void) -{ - tcpoutrsts++; -} - -void snmp_inc_udpindatagrams(void) -{ - udpindatagrams++; -} - -void snmp_inc_udpnoports(void) -{ - udpnoports++; -} - -void snmp_inc_udpinerrors(void) -{ - udpinerrors++; -} - -void snmp_inc_udpoutdatagrams(void) -{ - udpoutdatagrams++; -} - -/** - * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort) - * into index tree. - */ -void snmp_insert_udpidx_tree(struct udp_pcb *pcb) -{ - struct mib_list_rootnode *udp_rn; - struct mib_list_node *udp_node; - s32_t udpidx[5]; - u8_t level; - - LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); - udpidx[4] = pcb->local_port; - - udp_rn = &udp_root; - for (level = 0; level < 5; level++) - { - udp_node = NULL; - snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node); - if ((level != 4) && (udp_node != NULL)) - { - if (udp_node->nptr == NULL) - { - udp_rn = snmp_mib_lrn_alloc(); - udp_node->nptr = (struct mib_node*)udp_rn; - if (udp_rn != NULL) - { - if (level == 3) - { - udp_rn->get_object_def = udpentry_get_object_def; - udp_rn->get_value = udpentry_get_value; - udp_rn->set_test = noleafs_set_test; - udp_rn->set_value = noleafs_set_value; - } - } - else - { - /* udp_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full")); - break; - } - } - else - { - udp_rn = (struct mib_list_rootnode*)udp_node->nptr; - } - } - } - udptable.maxlength = 1; -} - -/** - * Removes udpTable indexes (.udpLocalAddress.udpLocalPort) - * from index tree. - */ -void snmp_delete_udpidx_tree(struct udp_pcb *pcb) -{ - struct udp_pcb *npcb; - struct mib_list_rootnode *udp_rn, *next, *del_rn[5]; - struct mib_list_node *udp_n, *del_n[5]; - s32_t udpidx[5]; - u8_t bindings, fc, level, del_cnt; - - LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); - udpidx[4] = pcb->local_port; - - /* count PCBs for a given binding - (e.g. when reusing ports or for temp output PCBs) */ - bindings = 0; - npcb = udp_pcbs; - while ((npcb != NULL)) - { - if (ipX_addr_cmp(0, &npcb->local_ip, &pcb->local_ip) && - (npcb->local_port == udpidx[4])) - { - bindings++; - } - npcb = npcb->next; - } - if (bindings == 1) - { - /* selectively remove */ - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - udp_rn = &udp_root; - while ((level < 5) && (udp_rn != NULL)) - { - fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n); - if (fc == 0) - { - /* udpidx[level] does not exist */ - del_cnt = 0; - udp_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = udp_rn; - del_n[del_cnt] = udp_n; - del_cnt++; - udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - udp_rn = del_rn[del_cnt]; - udp_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(udp_rn, udp_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty table */ - if (udp_root.count == 0) udptable.maxlength = 0; -} - - -void snmp_inc_snmpinpkts(void) -{ - snmpinpkts++; -} - -void snmp_inc_snmpoutpkts(void) -{ - snmpoutpkts++; -} - -void snmp_inc_snmpinbadversions(void) -{ - snmpinbadversions++; -} - -void snmp_inc_snmpinbadcommunitynames(void) -{ - snmpinbadcommunitynames++; -} - -void snmp_inc_snmpinbadcommunityuses(void) -{ - snmpinbadcommunityuses++; -} - -void snmp_inc_snmpinasnparseerrs(void) -{ - snmpinasnparseerrs++; -} - -void snmp_inc_snmpintoobigs(void) -{ - snmpintoobigs++; -} - -void snmp_inc_snmpinnosuchnames(void) -{ - snmpinnosuchnames++; -} - -void snmp_inc_snmpinbadvalues(void) -{ - snmpinbadvalues++; -} - -void snmp_inc_snmpinreadonlys(void) -{ - snmpinreadonlys++; -} - -void snmp_inc_snmpingenerrs(void) -{ - snmpingenerrs++; -} - -void snmp_add_snmpintotalreqvars(u8_t value) -{ - snmpintotalreqvars += value; -} - -void snmp_add_snmpintotalsetvars(u8_t value) -{ - snmpintotalsetvars += value; -} - -void snmp_inc_snmpingetrequests(void) -{ - snmpingetrequests++; -} - -void snmp_inc_snmpingetnexts(void) -{ - snmpingetnexts++; -} - -void snmp_inc_snmpinsetrequests(void) -{ - snmpinsetrequests++; -} - -void snmp_inc_snmpingetresponses(void) -{ - snmpingetresponses++; -} - -void snmp_inc_snmpintraps(void) -{ - snmpintraps++; -} - -void snmp_inc_snmpouttoobigs(void) -{ - snmpouttoobigs++; -} - -void snmp_inc_snmpoutnosuchnames(void) -{ - snmpoutnosuchnames++; -} - -void snmp_inc_snmpoutbadvalues(void) -{ - snmpoutbadvalues++; -} - -void snmp_inc_snmpoutgenerrs(void) -{ - snmpoutgenerrs++; -} - -void snmp_inc_snmpoutgetrequests(void) -{ - snmpoutgetrequests++; -} - -void snmp_inc_snmpoutgetnexts(void) -{ - snmpoutgetnexts++; -} - -void snmp_inc_snmpoutsetrequests(void) -{ - snmpoutsetrequests++; -} - -void snmp_inc_snmpoutgetresponses(void) -{ - snmpoutgetresponses++; -} - -void snmp_inc_snmpouttraps(void) -{ - snmpouttraps++; -} - -void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid) -{ - *oid = &snmpgrp_id; -} - -void snmp_set_snmpenableauthentraps(u8_t *value) -{ - if (value != NULL) - { - snmpenableauthentraps_ptr = value; - } -} - -void snmp_get_snmpenableauthentraps(u8_t *value) -{ - *value = *snmpenableauthentraps_ptr; -} - -void -noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - LWIP_UNUSED_ARG(ident_len); - LWIP_UNUSED_ARG(ident); - od->instance = MIB_OBJECT_NONE; -} - -void -noleafs_get_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); -} - -u8_t -noleafs_set_test(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); - /* can't set */ - return 0; -} - -void -noleafs_set_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); -} - - -/** - * Returns systems object definitions. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param od points to object definition. - */ -static void -system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id)); - switch (id) - { - case 1: /* sysDescr */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *sysdescr_len_ptr; - break; - case 2: /* sysObjectID */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = sysobjid.len * sizeof(s32_t); - break; - case 3: /* sysUpTime */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); - od->v_len = sizeof(u32_t); - break; - case 4: /* sysContact */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *syscontact_len_ptr; - break; - case 5: /* sysName */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *sysname_len_ptr; - break; - case 6: /* sysLocation */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *syslocation_len_ptr; - break; - case 7: /* sysServices */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns system object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -system_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* sysDescr */ - ocstrncpy((u8_t*)value, sysdescr_ptr, len); - break; - case 2: /* sysObjectID */ - objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t))); - break; - case 3: /* sysUpTime */ - { - snmp_get_sysuptime((u32_t*)value); - } - break; - case 4: /* sysContact */ - ocstrncpy((u8_t*)value, syscontact_ptr, len); - break; - case 5: /* sysName */ - ocstrncpy((u8_t*)value, sysname_ptr, len); - break; - case 6: /* sysLocation */ - ocstrncpy((u8_t*)value, syslocation_ptr, len); - break; - case 7: /* sysServices */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = sysservices; - } - break; - }; -} - -static u8_t -system_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - - LWIP_UNUSED_ARG(value); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 4: /* sysContact */ - if ((syscontact_ptr != syscontact_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - case 5: /* sysName */ - if ((sysname_ptr != sysname_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - case 6: /* sysLocation */ - if ((syslocation_ptr != syslocation_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - }; - return set_ok; -} - -static void -system_set_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_ASSERT("invalid len", len <= 0xff); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 4: /* sysContact */ - ocstrncpy(syscontact_ptr, (u8_t*)value, len); - *syscontact_len_ptr = (u8_t)len; - break; - case 5: /* sysName */ - ocstrncpy(sysname_ptr, (u8_t*)value, len); - *sysname_len_ptr = (u8_t)len; - break; - case 6: /* sysLocation */ - ocstrncpy(syslocation_ptr, (u8_t*)value, len); - *syslocation_len_ptr = (u8_t)len; - break; - }; -} - -/** - * Returns interfaces.ifnumber object definition. - * - * @param ident_len the address length (2) - * @param ident points to objectname.index - * @param od points to object definition. - */ -static void -interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns interfaces.ifnumber object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -interfaces_get_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(len); - if (od->id_inst_ptr[0] == 1) - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = iflist_root.count; - } -} - -/** - * Returns ifentry object definitions. - * - * @param ident_len the address length (2) - * @param ident points to objectname.index - * @param od points to object definition. - */ -static void -ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id)); - switch (id) - { - case 1: /* ifIndex */ - case 3: /* ifType */ - case 4: /* ifMtu */ - case 8: /* ifOperStatus */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* ifDescr */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - /** @todo this should be some sort of sizeof(struct netif.name) */ - od->v_len = 2; - break; - case 5: /* ifSpeed */ - case 21: /* ifOutQLen */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); - od->v_len = sizeof(u32_t); - break; - case 6: /* ifPhysAddress */ - { - struct netif *netif; - - snmp_ifindextonetif(ident[1], &netif); - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = netif->hwaddr_len; - } - break; - case 7: /* ifAdminStatus */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 9: /* ifLastChange */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); - od->v_len = sizeof(u32_t); - break; - case 10: /* ifInOctets */ - case 11: /* ifInUcastPkts */ - case 12: /* ifInNUcastPkts */ - case 13: /* ifInDiscarts */ - case 14: /* ifInErrors */ - case 15: /* ifInUnkownProtos */ - case 16: /* ifOutOctets */ - case 17: /* ifOutUcastPkts */ - case 18: /* ifOutNUcastPkts */ - case 19: /* ifOutDiscarts */ - case 20: /* ifOutErrors */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 22: /* ifSpecific */ - /** @note returning zeroDotZero (0.0) no media specific MIB support */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = ifspecific.len * sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns ifentry object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -ifentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id; - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ifIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* ifDescr */ - ocstrncpy((u8_t*)value, (u8_t*)netif->name, len); - break; - case 3: /* ifType */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = netif->link_type; - } - break; - case 4: /* ifMtu */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = netif->mtu; - } - break; - case 5: /* ifSpeed */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->link_speed; - } - break; - case 6: /* ifPhysAddress */ - ocstrncpy((u8_t*)value, netif->hwaddr, len); - break; - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (netif_is_up(netif)) - { - if (netif_is_link_up(netif)) - { - *sint_ptr = 1; /* up */ - } - else - { - *sint_ptr = 7; /* lowerLayerDown */ - } - } - else - { - *sint_ptr = 2; /* down */ - } - } - break; - case 8: /* ifOperStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (netif_is_up(netif)) - { - *sint_ptr = 1; - } - else - { - *sint_ptr = 2; - } - } - break; - case 9: /* ifLastChange */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ts; - } - break; - case 10: /* ifInOctets */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinoctets; - } - break; - case 11: /* ifInUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinucastpkts; - } - break; - case 12: /* ifInNUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinnucastpkts; - } - break; - case 13: /* ifInDiscarts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifindiscards; - } - break; - case 14: /* ifInErrors */ - case 15: /* ifInUnkownProtos */ - /** @todo add these counters! */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 16: /* ifOutOctets */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutoctets; - } - break; - case 17: /* ifOutUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutucastpkts; - } - break; - case 18: /* ifOutNUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutnucastpkts; - } - break; - case 19: /* ifOutDiscarts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutdiscards; - } - break; - case 20: /* ifOutErrors */ - /** @todo add this counter! */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 21: /* ifOutQLen */ - /** @todo figure out if this must be 0 (no queue) or 1? */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 22: /* ifSpecific */ - objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t))); - break; - }; -} - -#if !SNMP_SAFE_REQUESTS -static u8_t -ifentry_set_test(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id, set_ok; - LWIP_UNUSED_ARG(len); - - set_ok = 0; - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (*sint_ptr == 1 || *sint_ptr == 2) - set_ok = 1; - } - break; - } - return set_ok; -} - -static void -ifentry_set_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id; - LWIP_UNUSED_ARG(len); - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (*sint_ptr == 1) - { - netif_set_up(netif); - } - else if (*sint_ptr == 2) - { - netif_set_down(netif); - } - } - break; - } -} -#endif /* SNMP_SAFE_REQUESTS */ - -/** - * Returns atentry object definitions. - * - * @param ident_len the address length (6) - * @param ident points to objectname.atifindex.atnetaddress - * @param od points to object definition. - */ -static void -atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - switch (ident[0]) - { - case 1: /* atIfIndex */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* atPhysAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = 6; /** @todo try to use netif::hwaddr_len */ - break; - case 3: /* atNetAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -atentry_get_value(struct obj_def *od, u16_t len, void *value) -{ -#if LWIP_ARP - u8_t id; - struct eth_addr* ethaddr_ret; - ip_addr_t* ipaddr_ret; -#endif /* LWIP_ARP */ - ip_addr_t ip; - struct netif *netif; - - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - snmp_oidtoip(&od->id_inst_ptr[2], &ip); - -#if LWIP_ARP /** @todo implement a netif_find_addr */ - if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* atIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* atPhysAddress */ - { - struct eth_addr *dst = (struct eth_addr*)value; - - *dst = *ethaddr_ret; - } - break; - case 3: /* atNetAddress */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - *dst = *ipaddr_ret; - } - break; - } - } -#endif /* LWIP_ARP */ -} - -static void -ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id)); - switch (id) - { - case 1: /* ipForwarding */ - case 2: /* ipDefaultTTL */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 3: /* ipInReceives */ - case 4: /* ipInHdrErrors */ - case 5: /* ipInAddrErrors */ - case 6: /* ipForwDatagrams */ - case 7: /* ipInUnknownProtos */ - case 8: /* ipInDiscards */ - case 9: /* ipInDelivers */ - case 10: /* ipOutRequests */ - case 11: /* ipOutDiscards */ - case 12: /* ipOutNoRoutes */ - case 14: /* ipReasmReqds */ - case 15: /* ipReasmOKs */ - case 16: /* ipReasmFails */ - case 17: /* ipFragOKs */ - case 18: /* ipFragFails */ - case 19: /* ipFragCreates */ - case 23: /* ipRoutingDiscards */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 13: /* ipReasmTimeout */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipForwarding */ - { - s32_t *sint_ptr = (s32_t*)value; -#if IP_FORWARD - /* forwarding */ - *sint_ptr = 1; -#else - /* not-forwarding */ - *sint_ptr = 2; -#endif - } - break; - case 2: /* ipDefaultTTL */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = IP_DEFAULT_TTL; - } - break; - case 3: /* ipInReceives */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinreceives; - } - break; - case 4: /* ipInHdrErrors */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinhdrerrors; - } - break; - case 5: /* ipInAddrErrors */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinaddrerrors; - } - break; - case 6: /* ipForwDatagrams */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipforwdatagrams; - } - break; - case 7: /* ipInUnknownProtos */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinunknownprotos; - } - break; - case 8: /* ipInDiscards */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipindiscards; - } - break; - case 9: /* ipInDelivers */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipindelivers; - } - break; - case 10: /* ipOutRequests */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutrequests; - } - break; - case 11: /* ipOutDiscards */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutdiscards; - } - break; - case 12: /* ipOutNoRoutes */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutnoroutes; - } - break; - case 13: /* ipReasmTimeout */ - { - s32_t *sint_ptr = (s32_t*)value; -#if IP_REASSEMBLY - *sint_ptr = IP_REASS_MAXAGE; -#else - *sint_ptr = 0; -#endif - } - break; - case 14: /* ipReasmReqds */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmreqds; - } - break; - case 15: /* ipReasmOKs */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmoks; - } - break; - case 16: /* ipReasmFails */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmfails; - } - break; - case 17: /* ipFragOKs */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragoks; - } - break; - case 18: /* ipFragFails */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragfails; - } - break; - case 19: /* ipFragCreates */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragcreates; - } - break; - case 23: /* ipRoutingDiscards */ - /** @todo can lwIP discard routes at all?? hardwire this to 0?? */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = iproutingdiscards; - } - break; - }; -} - -/** - * Test ip object value before setting. - * - * @param od is the object definition - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value from. - * - * @note we allow set if the value matches the hardwired value, - * otherwise return badvalue. - */ -static u8_t -ip_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - s32_t *sint_ptr = (s32_t*)value; - - LWIP_UNUSED_ARG(len); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipForwarding */ -#if IP_FORWARD - /* forwarding */ - if (*sint_ptr == 1) -#else - /* not-forwarding */ - if (*sint_ptr == 2) -#endif - { - set_ok = 1; - } - break; - case 2: /* ipDefaultTTL */ - if (*sint_ptr == IP_DEFAULT_TTL) - { - set_ok = 1; - } - break; - }; - return set_ok; -} - -static void -ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (4) */ - ident_len += 4; - ident -= 4; - - if (ident_len == 5) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipAdEntAddr */ - case 3: /* ipAdEntNetMask */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* ipAdEntIfIndex */ - case 4: /* ipAdEntBcastAddr */ - case 5: /* ipAdEntReasmMaxSize */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - u16_t ifidx; - ip_addr_t ip; - struct netif *netif = netif_list; - - LWIP_UNUSED_ARG(len); - snmp_oidtoip(&od->id_inst_ptr[1], &ip); - ifidx = 0; - while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) - { - netif = netif->next; - ifidx++; - } - - if (netif != NULL) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipAdEntAddr */ - { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = netif->ip_addr; - } - break; - case 2: /* ipAdEntIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = ifidx + 1; - } - break; - case 3: /* ipAdEntNetMask */ - { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = netif->netmask; - } - break; - case 4: /* ipAdEntBcastAddr */ - { - s32_t *sint_ptr = (s32_t*)value; - - /* lwIP oddity, there's no broadcast - address in the netif we can rely on */ - *sint_ptr = IPADDR_BROADCAST & 1; - } - break; - case 5: /* ipAdEntReasmMaxSize */ - { - s32_t *sint_ptr = (s32_t*)value; -#if IP_REASSEMBLY - /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, - * but only if receiving one fragmented packet at a time. - * The current solution is to calculate for 2 simultaneous packets... - */ - *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * - (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN))); -#else - /** @todo returning MTU would be a bad thing and - returning a wild guess like '576' isn't good either */ - *sint_ptr = 0; -#endif - } - break; - } - } -} - -/** - * @note - * lwIP IP routing is currently using the network addresses in netif_list. - * if no suitable network IP is found in netif_list, the default_netif is used. - */ -static void -ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (4) */ - ident_len += 4; - ident -= 4; - - if (ident_len == 5) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipRouteDest */ - case 7: /* ipRouteNextHop */ - case 11: /* ipRouteMask */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* ipRouteIfIndex */ - case 3: /* ipRouteMetric1 */ - case 4: /* ipRouteMetric2 */ - case 5: /* ipRouteMetric3 */ - case 6: /* ipRouteMetric4 */ - case 8: /* ipRouteType */ - case 10: /* ipRouteAge */ - case 12: /* ipRouteMetric5 */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 9: /* ipRouteProto */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 13: /* ipRouteInfo */ - /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = iprouteinfo.len * sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - ip_addr_t dest; - s32_t *ident; - u8_t id; - - ident = od->id_inst_ptr; - snmp_oidtoip(&ident[1], &dest); - - if (ip_addr_isany(&dest)) - { - /* ip_route() uses default netif for default route */ - netif = netif_default; - } - else - { - /* not using ip_route(), need exact match! */ - netif = netif_list; - while ((netif != NULL) && - !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) ) - { - netif = netif->next; - } - } - if (netif != NULL) - { - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipRouteDest */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte has 0.0.0.0 dest */ - ip_addr_set_zero(dst); - } - else - { - /* netifs have netaddress dest */ - ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask); - } - } - break; - case 2: /* ipRouteIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - - snmp_netiftoifindex(netif, sint_ptr); - } - break; - case 3: /* ipRouteMetric1 */ - { - s32_t *sint_ptr = (s32_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte has metric 1 */ - *sint_ptr = 1; - } - else - { - /* other rtes have metric 0 */ - *sint_ptr = 0; - } - } - break; - case 4: /* ipRouteMetric2 */ - case 5: /* ipRouteMetric3 */ - case 6: /* ipRouteMetric4 */ - case 12: /* ipRouteMetric5 */ - { - s32_t *sint_ptr = (s32_t*)value; - /* not used */ - *sint_ptr = -1; - } - break; - case 7: /* ipRouteNextHop */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte: gateway */ - *dst = netif->gw; - } - else - { - /* other rtes: netif ip_addr */ - *dst = netif->ip_addr; - } - } - break; - case 8: /* ipRouteType */ - { - s32_t *sint_ptr = (s32_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte is indirect */ - *sint_ptr = 4; - } - else - { - /* other rtes are direct */ - *sint_ptr = 3; - } - } - break; - case 9: /* ipRouteProto */ - { - s32_t *sint_ptr = (s32_t*)value; - /* locally defined routes */ - *sint_ptr = 2; - } - break; - case 10: /* ipRouteAge */ - { - s32_t *sint_ptr = (s32_t*)value; - /** @todo (sysuptime - timestamp last change) / 100 - @see snmp_insert_iprteidx_tree() */ - *sint_ptr = 0; - } - break; - case 11: /* ipRouteMask */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte use 0.0.0.0 mask */ - ip_addr_set_zero(dst); - } - else - { - /* other rtes use netmask */ - *dst = netif->netmask; - } - } - break; - case 13: /* ipRouteInfo */ - objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t))); - break; - } - } -} - -static void -ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipNetToMediaIfIndex */ - case 4: /* ipNetToMediaType */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* ipNetToMediaPhysAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = 6; /** @todo try to use netif::hwaddr_len */ - break; - case 3: /* ipNetToMediaNetAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value) -{ -#if LWIP_ARP - u8_t id; - struct eth_addr* ethaddr_ret; - ip_addr_t* ipaddr_ret; -#endif /* LWIP_ARP */ - ip_addr_t ip; - struct netif *netif; - - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - snmp_oidtoip(&od->id_inst_ptr[2], &ip); - -#if LWIP_ARP /** @todo implement a netif_find_addr */ - if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipNetToMediaIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* ipNetToMediaPhysAddress */ - { - struct eth_addr *dst = (struct eth_addr*)value; - - *dst = *ethaddr_ret; - } - break; - case 3: /* ipNetToMediaNetAddress */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - *dst = *ipaddr_ret; - } - break; - case 4: /* ipNetToMediaType */ - { - s32_t *sint_ptr = (s32_t*)value; - /* dynamic (?) */ - *sint_ptr = 3; - } - break; - } - } -#endif /* LWIP_ARP */ -} - -static void -icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if ((ident_len == 2) && - (ident[0] > 0) && (ident[0] < 27)) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -icmp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* icmpInMsgs */ - *uint_ptr = icmpinmsgs; - break; - case 2: /* icmpInErrors */ - *uint_ptr = icmpinerrors; - break; - case 3: /* icmpInDestUnreachs */ - *uint_ptr = icmpindestunreachs; - break; - case 4: /* icmpInTimeExcds */ - *uint_ptr = icmpintimeexcds; - break; - case 5: /* icmpInParmProbs */ - *uint_ptr = icmpinparmprobs; - break; - case 6: /* icmpInSrcQuenchs */ - *uint_ptr = icmpinsrcquenchs; - break; - case 7: /* icmpInRedirects */ - *uint_ptr = icmpinredirects; - break; - case 8: /* icmpInEchos */ - *uint_ptr = icmpinechos; - break; - case 9: /* icmpInEchoReps */ - *uint_ptr = icmpinechoreps; - break; - case 10: /* icmpInTimestamps */ - *uint_ptr = icmpintimestamps; - break; - case 11: /* icmpInTimestampReps */ - *uint_ptr = icmpintimestampreps; - break; - case 12: /* icmpInAddrMasks */ - *uint_ptr = icmpinaddrmasks; - break; - case 13: /* icmpInAddrMaskReps */ - *uint_ptr = icmpinaddrmaskreps; - break; - case 14: /* icmpOutMsgs */ - *uint_ptr = icmpoutmsgs; - break; - case 15: /* icmpOutErrors */ - *uint_ptr = icmpouterrors; - break; - case 16: /* icmpOutDestUnreachs */ - *uint_ptr = icmpoutdestunreachs; - break; - case 17: /* icmpOutTimeExcds */ - *uint_ptr = icmpouttimeexcds; - break; - case 18: /* icmpOutParmProbs */ - *uint_ptr = icmpoutparmprobs; - break; - case 19: /* icmpOutSrcQuenchs */ - *uint_ptr = icmpoutsrcquenchs; - break; - case 20: /* icmpOutRedirects */ - *uint_ptr = icmpoutredirects; - break; - case 21: /* icmpOutEchos */ - *uint_ptr = icmpoutechos; - break; - case 22: /* icmpOutEchoReps */ - *uint_ptr = icmpoutechoreps; - break; - case 23: /* icmpOutTimestamps */ - *uint_ptr = icmpouttimestamps; - break; - case 24: /* icmpOutTimestampReps */ - *uint_ptr = icmpouttimestampreps; - break; - case 25: /* icmpOutAddrMasks */ - *uint_ptr = icmpoutaddrmasks; - break; - case 26: /* icmpOutAddrMaskReps */ - *uint_ptr = icmpoutaddrmaskreps; - break; - } -} - -#if LWIP_TCP -/** @todo tcp grp */ -static void -tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); - - switch (id) - { - case 1: /* tcpRtoAlgorithm */ - case 2: /* tcpRtoMin */ - case 3: /* tcpRtoMax */ - case 4: /* tcpMaxConn */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 5: /* tcpActiveOpens */ - case 6: /* tcpPassiveOpens */ - case 7: /* tcpAttemptFails */ - case 8: /* tcpEstabResets */ - case 10: /* tcpInSegs */ - case 11: /* tcpOutSegs */ - case 12: /* tcpRetransSegs */ - case 14: /* tcpInErrs */ - case 15: /* tcpOutRsts */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 9: /* tcpCurrEstab */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); - od->v_len = sizeof(u32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -tcp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - s32_t *sint_ptr = (s32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* tcpRtoAlgorithm, vanj(4) */ - *sint_ptr = 4; - break; - case 2: /* tcpRtoMin */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 1000; - break; - case 3: /* tcpRtoMax */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 60000; - break; - case 4: /* tcpMaxConn */ - *sint_ptr = MEMP_NUM_TCP_PCB; - break; - case 5: /* tcpActiveOpens */ - *uint_ptr = tcpactiveopens; - break; - case 6: /* tcpPassiveOpens */ - *uint_ptr = tcppassiveopens; - break; - case 7: /* tcpAttemptFails */ - *uint_ptr = tcpattemptfails; - break; - case 8: /* tcpEstabResets */ - *uint_ptr = tcpestabresets; - break; - case 9: /* tcpCurrEstab */ - { - u16_t tcpcurrestab = 0; - struct tcp_pcb *pcb = tcp_active_pcbs; - while (pcb != NULL) - { - if ((pcb->state == ESTABLISHED) || - (pcb->state == CLOSE_WAIT)) - { - tcpcurrestab++; - } - pcb = pcb->next; - } - *uint_ptr = tcpcurrestab; - } - break; - case 10: /* tcpInSegs */ - *uint_ptr = tcpinsegs; - break; - case 11: /* tcpOutSegs */ - *uint_ptr = tcpoutsegs; - break; - case 12: /* tcpRetransSegs */ - *uint_ptr = tcpretranssegs; - break; - case 14: /* tcpInErrs */ - *uint_ptr = tcpinerrs; - break; - case 15: /* tcpOutRsts */ - *uint_ptr = tcpoutrsts; - break; - } -} -#ifdef THIS_SEEMS_UNUSED -static void -tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (10) */ - ident_len += 10; - ident -= 10; - - if (ident_len == 11) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - id = ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); - - switch (id) - { - case 1: /* tcpConnState */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* tcpConnLocalAddress */ - case 4: /* tcpConnRemAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 3: /* tcpConnLocalPort */ - case 5: /* tcpConnRemPort */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - ip_addr_t lip, rip; - u16_t lport, rport; - s32_t *ident; - - ident = od->id_inst_ptr; - snmp_oidtoip(&ident[1], &lip); - lport = ident[5]; - snmp_oidtoip(&ident[6], &rip); - rport = ident[10]; - - /** @todo find matching PCB */ -} -#endif /* if 0 */ -#endif - -static void -udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if ((ident_len == 2) && - (ident[0] > 0) && (ident[0] < 6)) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -udp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* udpInDatagrams */ - *uint_ptr = udpindatagrams; - break; - case 2: /* udpNoPorts */ - *uint_ptr = udpnoports; - break; - case 3: /* udpInErrors */ - *uint_ptr = udpinerrors; - break; - case 4: /* udpOutDatagrams */ - *uint_ptr = udpoutdatagrams; - break; - } -} - -static void -udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - switch (ident[0]) - { - case 1: /* udpLocalAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* udpLocalPort */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -udpentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - struct udp_pcb *pcb; - ipX_addr_t ip; - u16_t port; - - LWIP_UNUSED_ARG(len); - snmp_oidtoip(&od->id_inst_ptr[1], (ip_addr_t*)&ip); - LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff)); - port = (u16_t)od->id_inst_ptr[5]; - - pcb = udp_pcbs; - while ((pcb != NULL) && - !(ipX_addr_cmp(0, &pcb->local_ip, &ip) && - (pcb->local_port == port))) - { - pcb = pcb->next; - } - - if (pcb != NULL) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* udpLocalAddress */ - { - ipX_addr_t *dst = (ipX_addr_t*)value; - ipX_addr_copy(0, *dst, pcb->local_ip); - } - break; - case 2: /* udpLocalPort */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = pcb->local_port; - } - break; - } - } -} - -static void -snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* snmpInPkts */ - case 2: /* snmpOutPkts */ - case 3: /* snmpInBadVersions */ - case 4: /* snmpInBadCommunityNames */ - case 5: /* snmpInBadCommunityUses */ - case 6: /* snmpInASNParseErrs */ - case 8: /* snmpInTooBigs */ - case 9: /* snmpInNoSuchNames */ - case 10: /* snmpInBadValues */ - case 11: /* snmpInReadOnlys */ - case 12: /* snmpInGenErrs */ - case 13: /* snmpInTotalReqVars */ - case 14: /* snmpInTotalSetVars */ - case 15: /* snmpInGetRequests */ - case 16: /* snmpInGetNexts */ - case 17: /* snmpInSetRequests */ - case 18: /* snmpInGetResponses */ - case 19: /* snmpInTraps */ - case 20: /* snmpOutTooBigs */ - case 21: /* snmpOutNoSuchNames */ - case 22: /* snmpOutBadValues */ - case 24: /* snmpOutGenErrs */ - case 25: /* snmpOutGetRequests */ - case 26: /* snmpOutGetNexts */ - case 27: /* snmpOutSetRequests */ - case 28: /* snmpOutGetResponses */ - case 29: /* snmpOutTraps */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 30: /* snmpEnableAuthenTraps */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -snmp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* snmpInPkts */ - *uint_ptr = snmpinpkts; - break; - case 2: /* snmpOutPkts */ - *uint_ptr = snmpoutpkts; - break; - case 3: /* snmpInBadVersions */ - *uint_ptr = snmpinbadversions; - break; - case 4: /* snmpInBadCommunityNames */ - *uint_ptr = snmpinbadcommunitynames; - break; - case 5: /* snmpInBadCommunityUses */ - *uint_ptr = snmpinbadcommunityuses; - break; - case 6: /* snmpInASNParseErrs */ - *uint_ptr = snmpinasnparseerrs; - break; - case 8: /* snmpInTooBigs */ - *uint_ptr = snmpintoobigs; - break; - case 9: /* snmpInNoSuchNames */ - *uint_ptr = snmpinnosuchnames; - break; - case 10: /* snmpInBadValues */ - *uint_ptr = snmpinbadvalues; - break; - case 11: /* snmpInReadOnlys */ - *uint_ptr = snmpinreadonlys; - break; - case 12: /* snmpInGenErrs */ - *uint_ptr = snmpingenerrs; - break; - case 13: /* snmpInTotalReqVars */ - *uint_ptr = snmpintotalreqvars; - break; - case 14: /* snmpInTotalSetVars */ - *uint_ptr = snmpintotalsetvars; - break; - case 15: /* snmpInGetRequests */ - *uint_ptr = snmpingetrequests; - break; - case 16: /* snmpInGetNexts */ - *uint_ptr = snmpingetnexts; - break; - case 17: /* snmpInSetRequests */ - *uint_ptr = snmpinsetrequests; - break; - case 18: /* snmpInGetResponses */ - *uint_ptr = snmpingetresponses; - break; - case 19: /* snmpInTraps */ - *uint_ptr = snmpintraps; - break; - case 20: /* snmpOutTooBigs */ - *uint_ptr = snmpouttoobigs; - break; - case 21: /* snmpOutNoSuchNames */ - *uint_ptr = snmpoutnosuchnames; - break; - case 22: /* snmpOutBadValues */ - *uint_ptr = snmpoutbadvalues; - break; - case 24: /* snmpOutGenErrs */ - *uint_ptr = snmpoutgenerrs; - break; - case 25: /* snmpOutGetRequests */ - *uint_ptr = snmpoutgetrequests; - break; - case 26: /* snmpOutGetNexts */ - *uint_ptr = snmpoutgetnexts; - break; - case 27: /* snmpOutSetRequests */ - *uint_ptr = snmpoutsetrequests; - break; - case 28: /* snmpOutGetResponses */ - *uint_ptr = snmpoutgetresponses; - break; - case 29: /* snmpOutTraps */ - *uint_ptr = snmpouttraps; - break; - case 30: /* snmpEnableAuthenTraps */ - *uint_ptr = *snmpenableauthentraps_ptr; - break; - }; -} - -/** - * Test snmp object value before setting. - * - * @param od is the object definition - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value from. - */ -static u8_t -snmp_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - - LWIP_UNUSED_ARG(len); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - if (id == 30) - { - /* snmpEnableAuthenTraps */ - s32_t *sint_ptr = (s32_t*)value; - - if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default) - { - /* we should have writable non-volatile mem here */ - if ((*sint_ptr == 1) || (*sint_ptr == 2)) - { - set_ok = 1; - } - } - else - { - /* const or hardwired value */ - if (*sint_ptr == snmpenableauthentraps_default) - { - set_ok = 1; - } - } - } - return set_ok; -} - -static void -snmp_set_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - if (id == 30) - { - /* snmpEnableAuthenTraps */ - /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */ - u8_t *ptr = (u8_t*)value; - *snmpenableauthentraps_ptr = *ptr; - } -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/mib_structs.c b/external/badvpn_dns/lwip/src/core/snmp/mib_structs.c deleted file mode 100644 index 2f185cb..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/mib_structs.c +++ /dev/null @@ -1,1174 +0,0 @@ -/** - * @file - * MIB tree access/construction functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_structs.h" -#include "lwip/memp.h" -#include "lwip/netif.h" - -/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ -const s32_t prefix[4] = {1, 3, 6, 1}; - -#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) -/** node stack entry (old news?) */ -struct nse -{ - /** right child */ - struct mib_node* r_ptr; - /** right child identifier */ - s32_t r_id; - /** right child next level */ - u8_t r_nl; -}; -static u8_t node_stack_cnt; -static struct nse node_stack[NODE_STACK_SIZE]; - -/** - * Pushes nse struct onto stack. - */ -static void -push_node(struct nse* node) -{ - LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); - if (node_stack_cnt < NODE_STACK_SIZE) - { - node_stack[node_stack_cnt] = *node; - node_stack_cnt++; - } -} - -/** - * Pops nse struct from stack. - */ -static void -pop_node(struct nse* node) -{ - if (node_stack_cnt > 0) - { - node_stack_cnt--; - *node = node_stack[node_stack_cnt]; - } - LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); -} - -/** - * Conversion from ifIndex to lwIP netif - * @param ifindex is a s32_t object sub-identifier - * @param netif points to returned netif struct pointer - */ -void -snmp_ifindextonetif(s32_t ifindex, struct netif **netif) -{ - struct netif *nif = netif_list; - s32_t i, ifidx; - - ifidx = ifindex - 1; - i = 0; - while ((nif != NULL) && (i < ifidx)) - { - nif = nif->next; - i++; - } - *netif = nif; -} - -/** - * Conversion from lwIP netif to ifIndex - * @param netif points to a netif struct - * @param ifidx points to s32_t object sub-identifier - */ -void -snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) -{ - struct netif *nif = netif_list; - u16_t i; - - i = 0; - while ((nif != NULL) && (nif != netif)) - { - nif = nif->next; - i++; - } - *ifidx = i+1; -} - -/** - * Conversion from oid to lwIP ip_addr - * @param ident points to s32_t ident[4] input - * @param ip points to output struct - */ -void -snmp_oidtoip(s32_t *ident, ip_addr_t *ip) -{ - IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]); -} - -/** - * Conversion from lwIP ip_addr to oid - * @param ip points to input struct - * @param ident points to s32_t ident[4] output - */ -void -snmp_iptooid(ip_addr_t *ip, s32_t *ident) -{ - ident[0] = ip4_addr1(ip); - ident[1] = ip4_addr2(ip); - ident[2] = ip4_addr3(ip); - ident[3] = ip4_addr4(ip); -} - -struct mib_list_node * -snmp_mib_ln_alloc(s32_t id) -{ - struct mib_list_node *ln; - - ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE); - if (ln != NULL) - { - ln->prev = NULL; - ln->next = NULL; - ln->objid = id; - ln->nptr = NULL; - } - return ln; -} - -void -snmp_mib_ln_free(struct mib_list_node *ln) -{ - memp_free(MEMP_SNMP_NODE, ln); -} - -struct mib_list_rootnode * -snmp_mib_lrn_alloc(void) -{ - struct mib_list_rootnode *lrn; - - lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE); - if (lrn != NULL) - { - lrn->get_object_def = noleafs_get_object_def; - lrn->get_value = noleafs_get_value; - lrn->set_test = noleafs_set_test; - lrn->set_value = noleafs_set_value; - lrn->node_type = MIB_NODE_LR; - lrn->maxlength = 0; - lrn->head = NULL; - lrn->tail = NULL; - lrn->count = 0; - } - return lrn; -} - -void -snmp_mib_lrn_free(struct mib_list_rootnode *lrn) -{ - memp_free(MEMP_SNMP_ROOTNODE, lrn); -} - -/** - * Inserts node in idx list in a sorted - * (ascending order) fashion and - * allocates the node if needed. - * - * @param rn points to the root node - * @param objid is the object sub identifier - * @param insn points to a pointer to the inserted node - * used for constructing the tree. - * @return -1 if failed, 1 if inserted, 2 if present. - */ -s8_t -snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) -{ - struct mib_list_node *nn; - s8_t insert; - - LWIP_ASSERT("rn != NULL",rn != NULL); - - /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ - insert = 0; - if (rn->head == NULL) - { - /* empty list, add first node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - rn->head = nn; - rn->tail = nn; - *insn = nn; - insert = 1; - } - else - { - insert = -1; - } - } - else - { - struct mib_list_node *n; - /* at least one node is present */ - n = rn->head; - while ((n != NULL) && (insert == 0)) - { - if (n->objid == objid) - { - /* node is already there */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); - *insn = n; - insert = 2; - } - else if (n->objid < objid) - { - if (n->next == NULL) - { - /* alloc and insert at the tail */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - nn->next = NULL; - nn->prev = n; - n->next = nn; - rn->tail = nn; - *insn = nn; - insert = 1; - } - else - { - /* insertion failure */ - insert = -1; - } - } - else - { - /* there's more to explore: traverse list */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); - n = n->next; - } - } - else - { - /* n->objid > objid */ - /* alloc and insert between n->prev and n */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - if (n->prev == NULL) - { - /* insert at the head */ - nn->next = n; - nn->prev = NULL; - rn->head = nn; - n->prev = nn; - } - else - { - /* insert in the middle */ - nn->next = n; - nn->prev = n->prev; - n->prev->next = nn; - n->prev = nn; - } - *insn = nn; - insert = 1; - } - else - { - /* insertion failure */ - insert = -1; - } - } - } - } - if (insert == 1) - { - rn->count += 1; - } - LWIP_ASSERT("insert != 0",insert != 0); - return insert; -} - -/** - * Finds node in idx list and returns deletion mark. - * - * @param rn points to the root node - * @param objid is the object sub identifier - * @param fn returns pointer to found node - * @return 0 if not found, 1 if deletable, - * 2 can't delete (2 or more children), 3 not a list_node - */ -s8_t -snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) -{ - s8_t fc; - struct mib_list_node *n; - - LWIP_ASSERT("rn != NULL",rn != NULL); - n = rn->head; - while ((n != NULL) && (n->objid != objid)) - { - n = n->next; - } - if (n == NULL) - { - fc = 0; - } - else if (n->nptr == NULL) - { - /* leaf, can delete node */ - fc = 1; - } - else - { - struct mib_list_rootnode *r; - - if (n->nptr->node_type == MIB_NODE_LR) - { - r = (struct mib_list_rootnode *)n->nptr; - if (r->count > 1) - { - /* can't delete node */ - fc = 2; - } - else - { - /* count <= 1, can delete node */ - fc = 1; - } - } - else - { - /* other node type */ - fc = 3; - } - } - *fn = n; - return fc; -} - -/** - * Removes node from idx list - * if it has a single child left. - * - * @param rn points to the root node - * @param n points to the node to delete - * @return the nptr to be freed by caller - */ -struct mib_list_rootnode * -snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) -{ - struct mib_list_rootnode *next; - - LWIP_ASSERT("rn != NULL",rn != NULL); - LWIP_ASSERT("n != NULL",n != NULL); - - /* caller must remove this sub-tree */ - next = (struct mib_list_rootnode*)(n->nptr); - rn->count -= 1; - - if (n == rn->head) - { - rn->head = n->next; - if (n->next != NULL) - { - /* not last node, new list begin */ - n->next->prev = NULL; - } - } - else if (n == rn->tail) - { - rn->tail = n->prev; - if (n->prev != NULL) - { - /* not last node, new list end */ - n->prev->next = NULL; - } - } - else - { - /* node must be in the middle */ - n->prev->next = n->next; - n->next->prev = n->prev; - } - LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); - snmp_mib_ln_free(n); - if (rn->count == 0) - { - rn->head = NULL; - rn->tail = NULL; - } - return next; -} - - - -/** - * Searches tree for the supplied (scalar?) object identifier. - * - * @param node points to the root of the tree ('.internet') - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @param np points to the found object instance (return) - * @return pointer to the requested parent (!) node if success, NULL otherwise - */ -struct mib_node * -snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) -{ - u8_t node_type, ext_level; - - ext_level = 0; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); - while (node != NULL) - { - node_type = node->node_type; - if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - u16_t i; - - if (ident_len > 0) - { - /* array node (internal ROM or RAM, fixed length) */ - an = (struct mib_array_node *)node; - i = 0; - while ((i < an->maxlength) && (an->objid[i] != *ident)) - { - i++; - } - if (i < an->maxlength) - { - /* found it, if available proceed to child, otherwise inspect leaf */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); - if (an->nptr[i] == NULL) - { - /* a scalar leaf OR table, - inspect remaining instance number / table index */ - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)an; - } - else - { - /* follow next child pointer */ - ident++; - ident_len--; - node = an->nptr[i]; - } - } - else - { - /* search failed, identifier mismatch (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); - return NULL; - } - } - else if(node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - struct mib_list_node *ln; - - if (ident_len > 0) - { - /* list root node (internal 'RAM', variable length) */ - lrn = (struct mib_list_rootnode *)node; - ln = lrn->head; - /* iterate over list, head to tail */ - while ((ln != NULL) && (ln->objid != *ident)) - { - ln = ln->next; - } - if (ln != NULL) - { - /* found it, proceed to child */; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); - if (ln->nptr == NULL) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)lrn; - } - else - { - /* follow next child pointer */ - ident_len--; - ident++; - node = ln->nptr; - } - } - else - { - /* search failed */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); - return NULL; - } - } - else if(node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - u16_t i, len; - - if (ident_len > 0) - { - /* external node (addressing and access via functions) */ - en = (struct mib_external_node *)node; - - i = 0; - len = en->level_length(en->addr_inf,ext_level); - while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) - { - i++; - } - if (i < len) - { - s32_t debug_id; - - en->get_objid(en->addr_inf,ext_level,i,&debug_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); - if ((ext_level + 1) == en->tree_levels) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)en; - } - else - { - /* found it, proceed to child */ - ident_len--; - ident++; - ext_level++; - } - } - else - { - /* search failed */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); - return NULL; - } - } - else if (node_type == MIB_NODE_SC) - { - mib_scalar_node *sn; - - sn = (mib_scalar_node *)node; - if ((ident_len == 1) && (*ident == 0)) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)sn; - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); - return NULL; - } - } - else - { - /* unknown node_type */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); - return NULL; - } - } - /* done, found nothing */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); - return NULL; -} - -/** - * Test table for presence of at least one table entry. - */ -static u8_t -empty_table(struct mib_node *node) -{ - u8_t node_type; - u8_t empty = 0; - - if (node != NULL) - { - node_type = node->node_type; - if (node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - lrn = (struct mib_list_rootnode *)node; - if ((lrn->count == 0) || (lrn->head == NULL)) - { - empty = 1; - } - } - else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - an = (struct mib_array_node *)node; - if ((an->maxlength == 0) || (an->nptr == NULL)) - { - empty = 1; - } - } - else if (node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - en = (struct mib_external_node *)node; - if (en->tree_levels == 0) - { - empty = 1; - } - } - } - return empty; -} - -/** - * Tree expansion. - */ -struct mib_node * -snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) -{ - u8_t node_type, ext_level, climb_tree; - - ext_level = 0; - /* reset node stack */ - node_stack_cnt = 0; - while (node != NULL) - { - climb_tree = 0; - node_type = node->node_type; - if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - u16_t i; - - /* array node (internal ROM or RAM, fixed length) */ - an = (struct mib_array_node *)node; - if (ident_len > 0) - { - i = 0; - while ((i < an->maxlength) && (an->objid[i] < *ident)) - { - i++; - } - if (i < an->maxlength) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); - /* add identifier to oidret */ - oidret->id[oidret->len] = an->objid[i]; - (oidret->len)++; - - if (an->nptr[i] == NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); - /* leaf node (e.g. in a fixed size table) */ - if (an->objid[i] > *ident) - { - return (struct mib_node*)an; - } - else if ((i + 1) < an->maxlength) - { - /* an->objid[i] == *ident */ - (oidret->len)--; - oidret->id[oidret->len] = an->objid[i + 1]; - (oidret->len)++; - return (struct mib_node*)an; - } - else - { - /* (i + 1) == an->maxlength */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - u8_t j; - struct nse cur_node; - - LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); - /* non-leaf, store right child ptr and id */ - LWIP_ASSERT("i < 0xff", i < 0xff); - j = (u8_t)i + 1; - while ((j < an->maxlength) && (empty_table(an->nptr[j]))) - { - j++; - } - if (j < an->maxlength) - { - cur_node.r_ptr = an->nptr[j]; - cur_node.r_id = an->objid[j]; - cur_node.r_nl = 0; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (an->objid[i] == *ident) - { - ident_len--; - ident++; - } - else - { - /* an->objid[i] < *ident */ - ident_len = 0; - } - /* follow next child pointer */ - node = an->nptr[i]; - } - } - else - { - /* i == an->maxlength */ - climb_tree = 1; - } - } - else - { - u8_t j; - /* ident_len == 0, complete with leftmost '.thing' */ - j = 0; - while ((j < an->maxlength) && empty_table(an->nptr[j])) - { - j++; - } - if (j < an->maxlength) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); - oidret->id[oidret->len] = an->objid[j]; - (oidret->len)++; - if (an->nptr[j] == NULL) - { - /* leaf node */ - return (struct mib_node*)an; - } - else - { - /* no leaf, continue */ - node = an->nptr[j]; - } - } - else - { - /* j == an->maxlength */ - climb_tree = 1; - } - } - } - else if(node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - struct mib_list_node *ln; - - /* list root node (internal 'RAM', variable length) */ - lrn = (struct mib_list_rootnode *)node; - if (ident_len > 0) - { - ln = lrn->head; - /* iterate over list, head to tail */ - while ((ln != NULL) && (ln->objid < *ident)) - { - ln = ln->next; - } - if (ln != NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); - oidret->id[oidret->len] = ln->objid; - (oidret->len)++; - if (ln->nptr == NULL) - { - /* leaf node */ - if (ln->objid > *ident) - { - return (struct mib_node*)lrn; - } - else if (ln->next != NULL) - { - /* ln->objid == *ident */ - (oidret->len)--; - oidret->id[oidret->len] = ln->next->objid; - (oidret->len)++; - return (struct mib_node*)lrn; - } - else - { - /* ln->next == NULL */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - struct mib_list_node *jn; - struct nse cur_node; - - /* non-leaf, store right child ptr and id */ - jn = ln->next; - while ((jn != NULL) && empty_table(jn->nptr)) - { - jn = jn->next; - } - if (jn != NULL) - { - cur_node.r_ptr = jn->nptr; - cur_node.r_id = jn->objid; - cur_node.r_nl = 0; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (ln->objid == *ident) - { - ident_len--; - ident++; - } - else - { - /* ln->objid < *ident */ - ident_len = 0; - } - /* follow next child pointer */ - node = ln->nptr; - } - - } - else - { - /* ln == NULL */ - climb_tree = 1; - } - } - else - { - struct mib_list_node *jn; - /* ident_len == 0, complete with leftmost '.thing' */ - jn = lrn->head; - while ((jn != NULL) && empty_table(jn->nptr)) - { - jn = jn->next; - } - if (jn != NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); - oidret->id[oidret->len] = jn->objid; - (oidret->len)++; - if (jn->nptr == NULL) - { - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); - return (struct mib_node*)lrn; - } - else - { - /* no leaf, continue */ - node = jn->nptr; - } - } - else - { - /* jn == NULL */ - climb_tree = 1; - } - } - } - else if(node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - s32_t ex_id; - - /* external node (addressing and access via functions) */ - en = (struct mib_external_node *)node; - if (ident_len > 0) - { - u16_t i, len; - - i = 0; - len = en->level_length(en->addr_inf,ext_level); - while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) - { - i++; - } - if (i < len) - { - /* add identifier to oidret */ - en->get_objid(en->addr_inf,ext_level,i,&ex_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - - if ((ext_level + 1) == en->tree_levels) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); - /* leaf node */ - if (ex_id > *ident) - { - return (struct mib_node*)en; - } - else if ((i + 1) < len) - { - /* ex_id == *ident */ - en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); - (oidret->len)--; - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - return (struct mib_node*)en; - } - else - { - /* (i + 1) == len */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - u8_t j; - struct nse cur_node; - - LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); - /* non-leaf, store right child ptr and id */ - LWIP_ASSERT("i < 0xff", i < 0xff); - j = (u8_t)i + 1; - if (j < len) - { - /* right node is the current external node */ - cur_node.r_ptr = node; - en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); - cur_node.r_nl = ext_level + 1; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) - { - ident_len--; - ident++; - } - else - { - /* external id < *ident */ - ident_len = 0; - } - /* proceed to child */ - ext_level++; - } - } - else - { - /* i == len (en->level_len()) */ - climb_tree = 1; - } - } - else - { - /* ident_len == 0, complete with leftmost '.thing' */ - en->get_objid(en->addr_inf,ext_level,0,&ex_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - if ((ext_level + 1) == en->tree_levels) - { - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); - return (struct mib_node*)en; - } - else - { - /* no leaf, proceed to child */ - ext_level++; - } - } - } - else if(node_type == MIB_NODE_SC) - { - mib_scalar_node *sn; - - /* scalar node */ - sn = (mib_scalar_node *)node; - if (ident_len > 0) - { - /* at .0 */ - climb_tree = 1; - } - else - { - /* ident_len == 0, complete object identifier */ - oidret->id[oidret->len] = 0; - (oidret->len)++; - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); - return (struct mib_node*)sn; - } - } - else - { - /* unknown/unhandled node_type */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); - return NULL; - } - - if (climb_tree) - { - struct nse child; - - /* find right child ptr */ - child.r_ptr = NULL; - child.r_id = 0; - child.r_nl = 0; - while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) - { - pop_node(&child); - /* trim returned oid */ - (oidret->len)--; - } - if (child.r_ptr != NULL) - { - /* incoming ident is useless beyond this point */ - ident_len = 0; - oidret->id[oidret->len] = child.r_id; - oidret->len++; - node = child.r_ptr; - ext_level = child.r_nl; - } - else - { - /* tree ends here ... */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); - return NULL; - } - } - } - /* done, found nothing */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); - return NULL; -} - -/** - * Test object identifier for the iso.org.dod.internet prefix. - * - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @return 1 if it matches, 0 otherwise - */ -u8_t -snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) -{ - if ((ident_len > 3) && - (ident[0] == 1) && (ident[1] == 3) && - (ident[2] == 6) && (ident[3] == 1)) - { - return 1; - } - else - { - return 0; - } -} - -/** - * Expands object identifier to the iso.org.dod.internet - * prefix for use in getnext operation. - * - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @param oidret points to returned expanded object identifier - * @return 1 if it matches, 0 otherwise - * - * @note ident_len 0 is allowed, expanding to the first known object id!! - */ -u8_t -snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) -{ - const s32_t *prefix_ptr; - s32_t *ret_ptr; - u8_t i; - - i = 0; - prefix_ptr = &prefix[0]; - ret_ptr = &oidret->id[0]; - ident_len = ((ident_len < 4)?ident_len:4); - while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) - { - *ret_ptr++ = *prefix_ptr++; - ident++; - i++; - } - if (i == ident_len) - { - /* match, complete missing bits */ - while (i < 4) - { - *ret_ptr++ = *prefix_ptr++; - i++; - } - oidret->len = i; - return 1; - } - else - { - /* i != ident_len */ - return 0; - } -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/msg_in.c b/external/badvpn_dns/lwip/src/core/snmp/msg_in.c deleted file mode 100644 index be940c6..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/msg_in.c +++ /dev/null @@ -1,1453 +0,0 @@ -/** - * @file - * SNMP input message processing (RFC1157). - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_msg.h" -#include "lwip/snmp_structs.h" -#include "lwip/ip_addr.h" -#include "lwip/memp.h" -#include "lwip/udp.h" -#include "lwip/stats.h" - -#include <string.h> - -/* public (non-static) constants */ -/** SNMP v1 == 0 */ -const s32_t snmp_version = 0; -/** default SNMP community string */ -const char snmp_publiccommunity[7] = "public"; - -/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */ -struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS]; -/* UDP Protocol Control Block */ -struct udp_pcb *snmp1_pcb; - -static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); -static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); -static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); - - -/** - * Starts SNMP Agent. - * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161. - */ -void -snmp_init(void) -{ - struct snmp_msg_pstat *msg_ps; - u8_t i; - - snmp1_pcb = udp_new(); - if (snmp1_pcb != NULL) - { - udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT); - udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT); - } - msg_ps = &msg_input_list[0]; - for (i=0; i<SNMP_CONCURRENT_REQUESTS; i++) - { - msg_ps->state = SNMP_MSG_EMPTY; - msg_ps->error_index = 0; - msg_ps->error_status = SNMP_ES_NOERROR; - msg_ps++; - } - trap_msg.pcb = snmp1_pcb; - -#ifdef SNMP_PRIVATE_MIB_INIT - /* If defined, this must be a function-like define to initialize the - * private MIB after the stack has been initialized. - * The private MIB can also be initialized in tcpip_callback (or after - * the stack is initialized), this define is only for convenience. */ - SNMP_PRIVATE_MIB_INIT(); -#endif /* SNMP_PRIVATE_MIB_INIT */ - - /* The coldstart trap will only be output - if our outgoing interface is up & configured */ - snmp_coldstart_trap(); -} - -static void -snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) -{ - /* move names back from outvb to invb */ - int v; - struct snmp_varbind *vbi = msg_ps->invb.head; - struct snmp_varbind *vbo = msg_ps->outvb.head; - for (v=0; v<msg_ps->vb_idx; v++) { - vbi->ident_len = vbo->ident_len; - vbo->ident_len = 0; - vbi->ident = vbo->ident; - vbo->ident = NULL; - vbi = vbi->next; - vbo = vbo->next; - } - /* free outvb */ - snmp_varbind_list_free(&msg_ps->outvb); - /* we send invb back */ - msg_ps->outvb = msg_ps->invb; - msg_ps->invb.head = NULL; - msg_ps->invb.tail = NULL; - msg_ps->invb.count = 0; - msg_ps->error_status = error; - /* error index must be 0 for error too big */ - msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0; - snmp_send_response(msg_ps); - snmp_varbind_list_free(&msg_ps->outvb); - msg_ps->state = SNMP_MSG_EMPTY; -} - -static void -snmp_ok_response(struct snmp_msg_pstat *msg_ps) -{ - err_t err_ret; - - err_ret = snmp_send_response(msg_ps); - if (err_ret == ERR_MEM) - { - /* serious memory problem, can't return tooBig */ - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status)); - } - /* free varbinds (if available) */ - snmp_varbind_list_free(&msg_ps->invb); - snmp_varbind_list_free(&msg_ps->outvb); - msg_ps->state = SNMP_MSG_EMPTY; -} - -/** - * Service an internal or external event for SNMP GET. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) && - (msg_ps->ext_object_def.access & MIB_ACCESS_READ)) - { - msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; - en->get_value_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) - { - struct mib_external_node *en; - struct snmp_varbind *vb; - - /* get_value() answer */ - en = msg_ps->ext_mib_node; - - /* allocate output varbind */ - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - if (vb != NULL) - { - vb->next = NULL; - vb->prev = NULL; - - /* move name from invb to outvb */ - vb->ident = msg_ps->vb_ptr->ident; - vb->ident_len = msg_ps->vb_ptr->ident_len; - /* ensure this memory is refereced once only */ - msg_ps->vb_ptr->ident = NULL; - msg_ps->vb_ptr->ident_len = 0; - - vb->value_type = msg_ps->ext_object_def.asn_type; - LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); - vb->value_len = (u8_t)msg_ps->ext_object_def.v_len; - if (vb->value_len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); - vb->value = memp_malloc(MEMP_SNMP_VALUE); - if (vb->value != NULL) - { - en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - /* search again (if vb_idx < msg_ps->invb.count) */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n")); - msg_ps->vb_ptr->ident = vb->ident; - msg_ps->vb_ptr->ident_len = vb->ident_len; - memp_free(MEMP_SNMP_VARBIND, vb); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - else - { - /* vb->value_len == 0, empty value (e.g. empty string) */ - en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL); - vb->value = NULL; - snmp_varbind_tail_add(&msg_ps->outvb, vb); - /* search again (if vb_idx < msg_ps->invb.count) */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /** test object identifier for .iso.org.dod.internet prefix */ - if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) - { - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(np.ident_len, np.ident, &object_def); - if ((object_def.instance != MIB_OBJECT_NONE) && - (object_def.access & MIB_ACCESS_READ)) - { - mn = mn; - } - else - { - /* search failed, object id points to unknown object (nosuchname) */ - mn = NULL; - } - if (mn != NULL) - { - struct snmp_varbind *vb; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; - /* allocate output varbind */ - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - if (vb != NULL) - { - vb->next = NULL; - vb->prev = NULL; - - /* move name from invb to outvb */ - vb->ident = msg_ps->vb_ptr->ident; - vb->ident_len = msg_ps->vb_ptr->ident_len; - /* ensure this memory is refereced once only */ - msg_ps->vb_ptr->ident = NULL; - msg_ps->vb_ptr->ident_len = 0; - - vb->value_type = object_def.asn_type; - LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); - vb->value_len = (u8_t)object_def.v_len; - if (vb->value_len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", - vb->value_len <= SNMP_MAX_VALUE_SIZE); - vb->value = memp_malloc(MEMP_SNMP_VALUE); - if (vb->value != NULL) - { - mn->get_value(&object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); - msg_ps->vb_ptr->ident = vb->ident; - msg_ps->vb_ptr->ident_len = vb->ident_len; - vb->ident = NULL; - vb->ident_len = 0; - memp_free(MEMP_SNMP_VARBIND, vb); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - else - { - /* vb->value_len == 0, empty value (e.g. empty string) */ - vb->value = NULL; - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - } - } - } - else - { - mn = NULL; - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - snmp_ok_response(msg_ps); - } -} - -/** - * Service an internal or external event for SNMP GETNEXT. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; - en->get_value_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) - { - struct mib_external_node *en; - struct snmp_varbind *vb; - - /* get_value() answer */ - en = msg_ps->ext_mib_node; - - LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); - vb = snmp_varbind_alloc(&msg_ps->ext_oid, - msg_ps->ext_object_def.asn_type, - (u8_t)msg_ps->ext_object_def.v_len); - if (vb != NULL) - { - en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_obj_id oid; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid)) - { - if (msg_ps->vb_ptr->ident_len > 3) - { - /* can offset ident_len and ident */ - mn = snmp_expand_tree((struct mib_node*)&internet, - msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &oid); - } - else - { - /* can't offset ident_len -4, ident + 4 */ - mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid); - } - } - else - { - mn = NULL; - } - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_oid = oid; - - en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]); - } - else - { - /* internal object */ - struct obj_def object_def; - struct snmp_varbind *vb; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(1, &oid.id[oid.len - 1], &object_def); - - LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); - vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len); - if (vb != NULL) - { - msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; - mn->get_value(&object_def, object_def.v_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - snmp_ok_response(msg_ps); - } -} - -/** - * Service an internal or external event for SNMP SET. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST; - en->set_test_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST) - { - struct mib_external_node *en; - - /* set_test() answer*/ - en = msg_ps->ext_mib_node; - - if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE) - { - if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) && - (en->set_test_a(request_id,&msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) - { - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->set_test_pc(request_id,&msg_ps->ext_object_def); - /* bad value */ - snmp_error_response(msg_ps,SNMP_ES_BADVALUE); - } - } - else - { - en->set_test_pc(request_id,&msg_ps->ext_object_def); - /* object not available for set */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE; - en->set_value_q(request_id, &msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* set_value failed, object has disappeared for some odd reason?? */ - snmp_error_response(msg_ps,SNMP_ES_GENERROR); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE) - { - struct mib_external_node *en; - - /** set_value_a() */ - en = msg_ps->ext_mib_node; - en->set_value_a(request_id, &msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value); - - /** @todo use set_value_pc() if toobig */ - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - msg_ps->vb_idx += 1; - } - - /* test all values before setting */ - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /** test object identifier for .iso.org.dod.internet prefix */ - if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) - { - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(np.ident_len, np.ident, &object_def); - if (object_def.instance != MIB_OBJECT_NONE) - { - mn = mn; - } - else - { - /* search failed, object id points to unknown object (nosuchname) */ - mn = NULL; - } - if (mn != NULL) - { - msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST; - - if (object_def.access & MIB_ACCESS_WRITE) - { - if ((object_def.asn_type == msg_ps->vb_ptr->value_type) && - (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) - { - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - /* bad value */ - snmp_error_response(msg_ps,SNMP_ES_BADVALUE); - } - } - else - { - /* object not available for set */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - } - } - } - else - { - mn = NULL; - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - msg_ps->vb_idx = 0; - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - } - - /* set all values "atomically" (be as "atomic" as possible) */ - while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /* skip iso prefix test, was done previously while settesting() */ - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - /* check if object is still available - (e.g. external hot-plug thingy present?) */ - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S; - mn->get_object_def(np.ident_len, np.ident, &object_def); - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); - msg_ps->vb_idx += 1; - } - } - } - if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - /* simply echo the input if we can set it - @todo do we need to return the actual value? - e.g. if value is silently modified or behaves sticky? */ - msg_ps->outvb = msg_ps->invb; - msg_ps->invb.head = NULL; - msg_ps->invb.tail = NULL; - msg_ps->invb.count = 0; - snmp_ok_response(msg_ps); - } -} - - -/** - * Handle one internal or external event. - * Called for one async event. (recv external/private answer) - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - */ -void -snmp_msg_event(u8_t request_id) -{ - struct snmp_msg_pstat *msg_ps; - - if (request_id < SNMP_CONCURRENT_REQUESTS) - { - msg_ps = &msg_input_list[request_id]; - if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) - { - snmp_msg_getnext_event(request_id, msg_ps); - } - else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) - { - snmp_msg_get_event(request_id, msg_ps); - } - else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ) - { - snmp_msg_set_event(request_id, msg_ps); - } - } -} - - -/* lwIP UDP receive callback function */ -static void -snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - struct snmp_msg_pstat *msg_ps; - u8_t req_idx; - err_t err_ret; - u16_t payload_len = p->tot_len; - u16_t payload_ofs = 0; - u16_t varbind_ofs = 0; - - /* suppress unused argument warning */ - LWIP_UNUSED_ARG(arg); - - /* traverse input message process list, look for SNMP_MSG_EMPTY */ - msg_ps = &msg_input_list[0]; - req_idx = 0; - while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY)) - { - req_idx++; - msg_ps++; - } - if (req_idx == SNMP_CONCURRENT_REQUESTS) - { - /* exceeding number of concurrent requests */ - pbuf_free(p); - return; - } - - /* accepting request */ - snmp_inc_snmpinpkts(); - /* record used 'protocol control block' */ - msg_ps->pcb = pcb; - /* source address (network order) */ - msg_ps->sip = *addr; - /* source port (host order (lwIP oddity)) */ - msg_ps->sp = port; - - /* check total length, version, community, pdu type */ - err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps); - /* Only accept requests and requests without error (be robust) */ - /* Reject response and trap headers or error requests as input! */ - if ((err_ret != ERR_OK) || - ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) && - (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) && - (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) || - ((msg_ps->error_status != SNMP_ES_NOERROR) || - (msg_ps->error_index != 0)) ) - { - /* header check failed drop request silently, do not return error! */ - pbuf_free(p); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n")); - return; - } - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community)); - - /* Builds a list of variable bindings. Copy the varbinds from the pbuf - chain to glue them when these are divided over two or more pbuf's. */ - err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps); - /* we've decoded the incoming message, release input msg now */ - pbuf_free(p); - if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0)) - { - /* varbind-list decode failed, or varbind list empty. - drop request silently, do not return error! - (errors are only returned for a specific varbind failure) */ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n")); - return; - } - - msg_ps->error_status = SNMP_ES_NOERROR; - msg_ps->error_index = 0; - /* find object for each variable binding */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - /* first variable binding from list to inspect */ - msg_ps->vb_idx = 0; - - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count)); - - /* handle input event and as much objects as possible in one go */ - snmp_msg_event(req_idx); -} - -/** - * Checks and decodes incoming SNMP message header, logs header errors. - * - * @param p points to pbuf chain of SNMP message (UDP payload) - * @param ofs points to first octet of SNMP message - * @param pdu_len the length of the UDP payload - * @param ofs_ret returns the ofset of the variable bindings - * @param m_stat points to the current message request state return - * @return - * - ERR_OK SNMP header is sane and accepted - * - ERR_ARG SNMP header is either malformed or rejected - */ -static err_t -snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) -{ - err_t derr; - u16_t len, ofs_base; - u8_t len_octets; - u8_t type; - s32_t version; - - ofs_base = ofs; - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || - (pdu_len != (1 + len_octets + len)) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (version) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - if (version != 0) - { - /* not version 1 */ - snmp_inc_snmpinbadversions(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR))) - { - /* can't decode or no octet string (community) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community); - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* add zero terminator */ - len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN)); - m_stat->community[len] = 0; - m_stat->com_strlen = (u8_t)len; - if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0) - { - /** @todo: move this if we need to check more names */ - snmp_inc_snmpinbadcommunitynames(); - snmp_authfail_trap(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - switch(type) - { - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ): - /* GetRequest PDU */ - snmp_inc_snmpingetrequests(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ): - /* GetNextRequest PDU */ - snmp_inc_snmpingetnexts(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP): - /* GetResponse PDU */ - snmp_inc_snmpingetresponses(); - derr = ERR_ARG; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ): - /* SetRequest PDU */ - snmp_inc_snmpinsetrequests(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP): - /* Trap PDU */ - snmp_inc_snmpintraps(); - derr = ERR_ARG; - break; - default: - snmp_inc_snmpinasnparseerrs(); - derr = ERR_ARG; - break; - } - if (derr != ERR_OK) - { - /* unsupported input PDU for this agent (no parse error) */ - return ERR_ARG; - } - m_stat->rt = type & 0x1F; - ofs += (1 + len_octets); - if (len != (pdu_len - (ofs - ofs_base))) - { - /* decoded PDU length does not equal actual payload length */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (request ID) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (error-status) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* must be noError (0) for incoming requests. - log errors for mib-2 completeness and for debug purposes */ - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - switch (m_stat->error_status) - { - case SNMP_ES_TOOBIG: - snmp_inc_snmpintoobigs(); - break; - case SNMP_ES_NOSUCHNAME: - snmp_inc_snmpinnosuchnames(); - break; - case SNMP_ES_BADVALUE: - snmp_inc_snmpinbadvalues(); - break; - case SNMP_ES_READONLY: - snmp_inc_snmpinreadonlys(); - break; - case SNMP_ES_GENERROR: - snmp_inc_snmpingenerrs(); - break; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (error-index) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* must be 0 for incoming requests. - decode anyway to catch bad integers (and dirty tricks) */ - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - *ofs_ret = ofs; - return ERR_OK; -} - -static err_t -snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) -{ - err_t derr; - u16_t len, vb_len; - u8_t len_octets; - u8_t type; - - /* variable binding list */ - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len); - if ((derr != ERR_OK) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets); - - /* start with empty list */ - m_stat->invb.count = 0; - m_stat->invb.head = NULL; - m_stat->invb.tail = NULL; - - while (vb_len > 0) - { - struct snmp_obj_id oid, oid_value; - struct snmp_varbind *vb; - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) || - (len == 0) || (len > vb_len)) - { - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets); - vb_len -= (1 + len_octets); - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID))) - { - /* can't decode object name length */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid); - if (derr != ERR_OK) - { - /* can't decode object name */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - vb_len -= (1 + len_octets + len); - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if (derr != ERR_OK) - { - /* can't decode object value length */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - - switch (type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t)); - if (vb != NULL) - { - s32_t *vptr = (s32_t*)vb->value; - - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t)); - if (vb != NULL) - { - u32_t *vptr = (u32_t*)vb->value; - - derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - LWIP_ASSERT("invalid length", len <= 0xff); - vb = snmp_varbind_alloc(&oid, type, (u8_t)len); - if (vb != NULL) - { - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - vb = snmp_varbind_alloc(&oid, type, 0); - if (vb != NULL) - { - snmp_varbind_tail_add(&m_stat->invb, vb); - derr = ERR_OK; - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value); - if (derr == ERR_OK) - { - vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t)); - if (vb != NULL) - { - u8_t i = oid_value.len; - s32_t *vptr = (s32_t*)vb->value; - - while(i > 0) - { - i--; - vptr[i] = oid_value.id[i]; - } - snmp_varbind_tail_add(&m_stat->invb, vb); - derr = ERR_OK; - } - else - { - derr = ERR_ARG; - } - } - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - if (len == 4) - { - /* must be exactly 4 octets! */ - vb = snmp_varbind_alloc(&oid, type, 4); - if (vb != NULL) - { - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - } - else - { - derr = ERR_ARG; - } - break; - default: - derr = ERR_ARG; - break; - } - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - vb_len -= (1 + len_octets + len); - } - - if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ) - { - snmp_add_snmpintotalsetvars(m_stat->invb.count); - } - else - { - snmp_add_snmpintotalreqvars(m_stat->invb.count); - } - - *ofs_ret = ofs; - return ERR_OK; -} - -struct snmp_varbind* -snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) -{ - struct snmp_varbind *vb; - - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - if (vb != NULL) - { - u8_t i; - - vb->next = NULL; - vb->prev = NULL; - i = oid->len; - vb->ident_len = i; - if (i > 0) - { - LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH); - /* allocate array of s32_t for our object identifier */ - vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE); - if (vb->ident == NULL) - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n")); - memp_free(MEMP_SNMP_VARBIND, vb); - return NULL; - } - while(i > 0) - { - i--; - vb->ident[i] = oid->id[i]; - } - } - else - { - /* i == 0, pass zero length object identifier */ - vb->ident = NULL; - } - vb->value_type = type; - vb->value_len = len; - if (len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); - /* allocate raw bytes for our object value */ - vb->value = memp_malloc(MEMP_SNMP_VALUE); - if (vb->value == NULL) - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n")); - if (vb->ident != NULL) - { - memp_free(MEMP_SNMP_VALUE, vb->ident); - } - memp_free(MEMP_SNMP_VARBIND, vb); - return NULL; - } - } - else - { - /* ASN1_NUL type, or zero length ASN1_OC_STR */ - vb->value = NULL; - } - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n")); - } - return vb; -} - -void -snmp_varbind_free(struct snmp_varbind *vb) -{ - if (vb->value != NULL ) - { - memp_free(MEMP_SNMP_VALUE, vb->value); - } - if (vb->ident != NULL ) - { - memp_free(MEMP_SNMP_VALUE, vb->ident); - } - memp_free(MEMP_SNMP_VARBIND, vb); -} - -void -snmp_varbind_list_free(struct snmp_varbind_root *root) -{ - struct snmp_varbind *vb, *prev; - - vb = root->tail; - while ( vb != NULL ) - { - prev = vb->prev; - snmp_varbind_free(vb); - vb = prev; - } - root->count = 0; - root->head = NULL; - root->tail = NULL; -} - -void -snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb) -{ - if (root->count == 0) - { - /* add first varbind to list */ - root->head = vb; - root->tail = vb; - } - else - { - /* add nth varbind to list tail */ - root->tail->next = vb; - vb->prev = root->tail; - root->tail = vb; - } - root->count += 1; -} - -struct snmp_varbind* -snmp_varbind_tail_remove(struct snmp_varbind_root *root) -{ - struct snmp_varbind* vb; - - if (root->count > 0) - { - /* remove tail varbind */ - vb = root->tail; - root->tail = vb->prev; - vb->prev->next = NULL; - root->count -= 1; - } - else - { - /* nothing to remove */ - vb = NULL; - } - return vb; -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/snmp/msg_out.c b/external/badvpn_dns/lwip/src/core/snmp/msg_out.c deleted file mode 100644 index fc0807c..0000000 --- a/external/badvpn_dns/lwip/src/core/snmp/msg_out.c +++ /dev/null @@ -1,678 +0,0 @@ -/** - * @file - * SNMP output message processing (RFC1157). - * - * Output responses and traps are build in two passes: - * - * Pass 0: iterate over the output message backwards to determine encoding lengths - * Pass 1: the actual forward encoding of internal form into ASN1 - * - * The single-pass encoding method described by Comer & Stevens - * requires extra buffer space and copying for reversal of the packet. - * The buffer requirement can be prohibitively large for big payloads - * (>= 484) therefore we use the two encoding passes. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/netif.h" -#include "lwip/snmp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_msg.h" - -struct snmp_trap_dst -{ - /* destination IP address in network order */ - ip_addr_t dip; - /* set to 0 when disabled, >0 when enabled */ - u8_t enable; -}; -struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; - -/** TRAP message structure */ -struct snmp_msg_trap trap_msg; - -static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len); -static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len); -static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root); - -static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p); -static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p); -static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs); - -/** - * Sets enable switch for this trap destination. - * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 - * @param enable switch if 0 destination is disabled >0 enabled. - */ -void -snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) -{ - if (dst_idx < SNMP_TRAP_DESTINATIONS) - { - trap_dst[dst_idx].enable = enable; - } -} - -/** - * Sets IPv4 address for this trap destination. - * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 - * @param dst IPv4 address in host order. - */ -void -snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst) -{ - if (dst_idx < SNMP_TRAP_DESTINATIONS) - { - ip_addr_set(&trap_dst[dst_idx].dip, dst); - } -} - -/** - * Sends a 'getresponse' message to the request originator. - * - * @param m_stat points to the current message request state source - * @return ERR_OK when success, ERR_MEM if we're out of memory - * - * @note the caller is responsible for filling in outvb in the m_stat - * and provide error-status and index (except for tooBig errors) ... - */ -err_t -snmp_send_response(struct snmp_msg_pstat *m_stat) -{ - struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0}; - struct pbuf *p; - u16_t tot_len; - err_t err; - - /* pass 0, calculate length fields */ - tot_len = snmp_varbind_list_sum(&m_stat->outvb); - tot_len = snmp_resp_header_sum(m_stat, tot_len); - - /* try allocating pbuf(s) for complete response */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - if (p == NULL) - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n")); - - /* can't construct reply, return error-status tooBig */ - m_stat->error_status = SNMP_ES_TOOBIG; - m_stat->error_index = 0; - /* pass 0, recalculate lengths, for empty varbind-list */ - tot_len = snmp_varbind_list_sum(&emptyvb); - tot_len = snmp_resp_header_sum(m_stat, tot_len); - /* retry allocation once for header and empty varbind-list */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - } - if (p != NULL) - { - /* first pbuf alloc try or retry alloc success */ - u16_t ofs; - - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n")); - - /* pass 1, size error, encode packet ino the pbuf(s) */ - ofs = snmp_resp_header_enc(m_stat, p); - snmp_varbind_list_enc(&m_stat->outvb, p, ofs); - - switch (m_stat->error_status) - { - case SNMP_ES_TOOBIG: - snmp_inc_snmpouttoobigs(); - break; - case SNMP_ES_NOSUCHNAME: - snmp_inc_snmpoutnosuchnames(); - break; - case SNMP_ES_BADVALUE: - snmp_inc_snmpoutbadvalues(); - break; - case SNMP_ES_GENERROR: - snmp_inc_snmpoutgenerrs(); - break; - } - snmp_inc_snmpoutgetresponses(); - snmp_inc_snmpoutpkts(); - - /** @todo do we need separate rx and tx pcbs for threaded case? */ - /** connect to the originating source */ - udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp); - err = udp_send(m_stat->pcb, p); - if (err == ERR_MEM) - { - /** @todo release some memory, retry and return tooBig? tooMuchHassle? */ - err = ERR_MEM; - } - else - { - err = ERR_OK; - } - /** disassociate remote address and port with this pcb */ - udp_disconnect(m_stat->pcb); - - pbuf_free(p); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n")); - return err; - } - else - { - /* first pbuf alloc try or retry alloc failed - very low on memory, couldn't return tooBig */ - return ERR_MEM; - } -} - - -/** - * Sends an generic or enterprise specific trap message. - * - * @param generic_trap is the trap code - * @param eoid points to enterprise object identifier - * @param specific_trap used for enterprise traps when generic_trap == 6 - * @return ERR_OK when success, ERR_MEM if we're out of memory - * - * @note the caller is responsible for filling in outvb in the trap_msg - * @note the use of the enterpise identifier field - * is per RFC1215. - * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps - * and .iso.org.dod.internet.private.enterprises.yourenterprise - * (sysObjectID) for specific traps. - */ -err_t -snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) -{ - struct snmp_trap_dst *td; - struct netif *dst_if; - ip_addr_t dst_ip; - struct pbuf *p; - u16_t i,tot_len; - err_t err = ERR_OK; - - for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++) - { - if ((td->enable != 0) && !ip_addr_isany(&td->dip)) - { - /* network order trap destination */ - ip_addr_copy(trap_msg.dip, td->dip); - /* lookup current source address for this dst */ - dst_if = ip_route(&td->dip); - if (dst_if != NULL) { - ip_addr_copy(dst_ip, dst_if->ip_addr); - /* @todo: what about IPv6? */ - trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); - trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); - trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); - trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); - trap_msg.gen_trap = generic_trap; - trap_msg.spc_trap = specific_trap; - if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) - { - /* enterprise-Specific trap */ - trap_msg.enterprise = eoid; - } - else - { - /* generic (MIB-II) trap */ - snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); - } - snmp_get_sysuptime(&trap_msg.ts); - - /* pass 0, calculate length fields */ - tot_len = snmp_varbind_list_sum(&trap_msg.outvb); - tot_len = snmp_trap_header_sum(&trap_msg, tot_len); - - /* allocate pbuf(s) */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - if (p != NULL) - { - u16_t ofs; - - /* pass 1, encode packet ino the pbuf(s) */ - ofs = snmp_trap_header_enc(&trap_msg, p); - snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); - - snmp_inc_snmpouttraps(); - snmp_inc_snmpoutpkts(); - - /** send to the TRAP destination */ - udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); - - pbuf_free(p); - } else { - err = ERR_MEM; - } - } else { - /* routing error */ - err = ERR_RTE; - } - } - } - return err; -} - -void -snmp_coldstart_trap(void) -{ - trap_msg.outvb.head = NULL; - trap_msg.outvb.tail = NULL; - trap_msg.outvb.count = 0; - snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0); -} - -void -snmp_authfail_trap(void) -{ - u8_t enable; - snmp_get_snmpenableauthentraps(&enable); - if (enable == 1) - { - trap_msg.outvb.head = NULL; - trap_msg.outvb.tail = NULL; - trap_msg.outvb.count = 0; - snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0); - } -} - -/** - * Sums response header field lengths from tail to head and - * returns resp_header_lengths for second encoding pass. - * - * @param vb_len varbind-list length - * @param rhl points to returned header lengths - * @return the required lenght for encoding the response header - */ -static u16_t -snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) -{ - u16_t tot_len; - struct snmp_resp_header_lengths *rhl; - - rhl = &m_stat->rhl; - tot_len = vb_len; - snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen); - snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen); - tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen; - - snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen); - snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen); - tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen; - - snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen); - snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen); - tot_len += 1 + rhl->ridlenlen + rhl->ridlen; - - rhl->pdulen = tot_len; - snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen); - tot_len += 1 + rhl->pdulenlen; - - rhl->comlen = m_stat->com_strlen; - snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen); - tot_len += 1 + rhl->comlenlen + rhl->comlen; - - snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen); - snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen); - tot_len += 1 + rhl->verlen + rhl->verlenlen; - - rhl->seqlen = tot_len; - snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen); - tot_len += 1 + rhl->seqlenlen; - - return tot_len; -} - -/** - * Sums trap header field lengths from tail to head and - * returns trap_header_lengths for second encoding pass. - * - * @param vb_len varbind-list length - * @param thl points to returned header lengths - * @return the required lenght for encoding the trap header - */ -static u16_t -snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) -{ - u16_t tot_len; - struct snmp_trap_header_lengths *thl; - - thl = &m_trap->thl; - tot_len = vb_len; - - snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen); - snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen); - tot_len += 1 + thl->tslen + thl->tslenlen; - - snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen); - snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen); - tot_len += 1 + thl->strplen + thl->strplenlen; - - snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen); - snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen); - tot_len += 1 + thl->gtrplen + thl->gtrplenlen; - - thl->aaddrlen = 4; - snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen); - tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen; - - snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen); - snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen); - tot_len += 1 + thl->eidlen + thl->eidlenlen; - - thl->pdulen = tot_len; - snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen); - tot_len += 1 + thl->pdulenlen; - - thl->comlen = sizeof(snmp_publiccommunity) - 1; - snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen); - tot_len += 1 + thl->comlenlen + thl->comlen; - - snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen); - snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen); - tot_len += 1 + thl->verlen + thl->verlenlen; - - thl->seqlen = tot_len; - snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen); - tot_len += 1 + thl->seqlenlen; - - return tot_len; -} - -/** - * Sums varbind lengths from tail to head and - * annotates lengths in varbind for second encoding pass. - * - * @param root points to the root of the variable binding list - * @return the required lenght for encoding the variable bindings - */ -static u16_t -snmp_varbind_list_sum(struct snmp_varbind_root *root) -{ - struct snmp_varbind *vb; - u32_t *uint_ptr; - s32_t *sint_ptr; - u16_t tot_len; - - tot_len = 0; - vb = root->tail; - while ( vb != NULL ) - { - /* encoded value lenght depends on type */ - switch (vb->value_type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen); - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - uint_ptr = (u32_t*)vb->value; - snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - vb->vlen = vb->value_len; - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen); - break; - default: - /* unsupported type */ - vb->vlen = 0; - break; - }; - /* encoding length of value length field */ - snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen); - snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen); - snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen); - - vb->seqlen = 1 + vb->vlenlen + vb->vlen; - vb->seqlen += 1 + vb->olenlen + vb->olen; - snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen); - - /* varbind seq */ - tot_len += 1 + vb->seqlenlen + vb->seqlen; - - vb = vb->prev; - } - - /* varbind-list seq */ - root->seqlen = tot_len; - snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen); - tot_len += 1 + root->seqlenlen; - - return tot_len; -} - -/** - * Encodes response header from head to tail. - */ -static u16_t -snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p) -{ - u16_t ofs; - - ofs = 0; - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen); - ofs += m_stat->rhl.seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen); - ofs += m_stat->rhl.verlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version); - ofs += m_stat->rhl.verlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen); - ofs += m_stat->rhl.comlenlen; - snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community); - ofs += m_stat->rhl.comlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen); - ofs += m_stat->rhl.pdulenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen); - ofs += m_stat->rhl.ridlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid); - ofs += m_stat->rhl.ridlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen); - ofs += m_stat->rhl.errstatlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status); - ofs += m_stat->rhl.errstatlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen); - ofs += m_stat->rhl.erridxlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index); - ofs += m_stat->rhl.erridxlen; - - return ofs; -} - -/** - * Encodes trap header from head to tail. - */ -static u16_t -snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p) -{ - u16_t ofs; - - ofs = 0; - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen); - ofs += m_trap->thl.seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen); - ofs += m_trap->thl.verlenlen; - snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version); - ofs += m_trap->thl.verlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen); - ofs += m_trap->thl.comlenlen; - snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]); - ofs += m_trap->thl.comlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen); - ofs += m_trap->thl.pdulenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen); - ofs += m_trap->thl.eidlenlen; - snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]); - ofs += m_trap->thl.eidlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen); - ofs += m_trap->thl.aaddrlenlen; - snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]); - ofs += m_trap->thl.aaddrlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen); - ofs += m_trap->thl.gtrplenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap); - ofs += m_trap->thl.gtrplen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen); - ofs += m_trap->thl.strplenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap); - ofs += m_trap->thl.strplen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen); - ofs += m_trap->thl.tslenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts); - ofs += m_trap->thl.tslen; - - return ofs; -} - -/** - * Encodes varbind list from head to tail. - */ -static u16_t -snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs) -{ - struct snmp_varbind *vb; - s32_t *sint_ptr; - u32_t *uint_ptr; - u8_t *raw_ptr; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, root->seqlen); - ofs += root->seqlenlen; - - vb = root->head; - while ( vb != NULL ) - { - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->seqlen); - ofs += vb->seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->olen); - ofs += vb->olenlen; - snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]); - ofs += vb->olen; - - snmp_asn1_enc_type(p, ofs, vb->value_type); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->vlen); - ofs += vb->vlenlen; - - switch (vb->value_type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr); - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - uint_ptr = (u32_t*)vb->value; - snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - raw_ptr = (u8_t*)vb->value; - snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr); - break; - default: - /* unsupported type */ - break; - }; - ofs += vb->vlen; - vb = vb->next; - } - return ofs; -} - -#endif /* LWIP_SNMP */ diff --git a/external/badvpn_dns/lwip/src/core/stats.c b/external/badvpn_dns/lwip/src/core/stats.c deleted file mode 100644 index 06fbe0f..0000000 --- a/external/badvpn_dns/lwip/src/core/stats.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @file - * Statistics module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/mem.h" - -#include <string.h> - -struct stats_ lwip_stats; - -void stats_init(void) -{ -#ifdef LWIP_DEBUG -#if MEMP_STATS - const char * memp_names[] = { -#define LWIP_MEMPOOL(name,num,size,desc) desc, -#include "lwip/memp_std.h" - }; - int i; - for (i = 0; i < MEMP_MAX; i++) { - lwip_stats.memp[i].name = memp_names[i]; - } -#endif /* MEMP_STATS */ -#if MEM_STATS - lwip_stats.mem.name = "MEM"; -#endif /* MEM_STATS */ -#endif /* LWIP_DEBUG */ -} - -#if LWIP_STATS_DISPLAY -void -stats_display_proto(struct stats_proto *proto, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); - LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); - LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); - LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); - LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); - LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); -} - -#if IGMP_STATS -void -stats_display_igmp(struct stats_igmp *igmp, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); - LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); - LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group)); - LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general)); - LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); - LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); - LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); - LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); -} -#endif /* IGMP_STATS */ - -#if MEM_STATS || MEMP_STATS -void -stats_display_mem(struct stats_mem *mem, const char *name) -{ - LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); - LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); - LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); - LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); - LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); -} - -#if MEMP_STATS -void -stats_display_memp(struct stats_mem *mem, int index) -{ - char * memp_names[] = { -#define LWIP_MEMPOOL(name,num,size,desc) desc, -#include "lwip/memp_std.h" - }; - if(index < MEMP_MAX) { - stats_display_mem(mem, memp_names[index]); - } -} -#endif /* MEMP_STATS */ -#endif /* MEM_STATS || MEMP_STATS */ - -#if SYS_STATS -void -stats_display_sys(struct stats_sys *sys) -{ - LWIP_PLATFORM_DIAG(("\nSYS\n\t")); - LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); - LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); - LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); - LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); - LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max)); - LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err)); - LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); - LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); - LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err)); -} -#endif /* SYS_STATS */ - -void -stats_display(void) -{ - s16_t i; - - LINK_STATS_DISPLAY(); - ETHARP_STATS_DISPLAY(); - IPFRAG_STATS_DISPLAY(); - IP6_FRAG_STATS_DISPLAY(); - IP_STATS_DISPLAY(); - ND6_STATS_DISPLAY(); - IP6_STATS_DISPLAY(); - IGMP_STATS_DISPLAY(); - MLD6_STATS_DISPLAY(); - ICMP_STATS_DISPLAY(); - ICMP6_STATS_DISPLAY(); - UDP_STATS_DISPLAY(); - TCP_STATS_DISPLAY(); - MEM_STATS_DISPLAY(); - for (i = 0; i < MEMP_MAX; i++) { - MEMP_STATS_DISPLAY(i); - } - SYS_STATS_DISPLAY(); -} -#endif /* LWIP_STATS_DISPLAY */ - -#endif /* LWIP_STATS */ - diff --git a/external/badvpn_dns/lwip/src/core/sys.c b/external/badvpn_dns/lwip/src/core/sys.c deleted file mode 100644 index f177737..0000000 --- a/external/badvpn_dns/lwip/src/core/sys.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * lwIP Operating System abstraction - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#include "lwip/sys.h" - -/* Most of the functions defined in sys.h must be implemented in the - * architecture-dependent file sys_arch.c */ - -#if !NO_SYS - -#ifndef sys_msleep -/** - * Sleep for some ms. Timeouts are NOT processed while sleeping. - * - * @param ms number of milliseconds to sleep - */ -void -sys_msleep(u32_t ms) -{ - if (ms > 0) { - sys_sem_t delaysem; - err_t err = sys_sem_new(&delaysem, 0); - if (err == ERR_OK) { - sys_arch_sem_wait(&delaysem, ms); - sys_sem_free(&delaysem); - } - } -} -#endif /* sys_msleep */ - -#endif /* !NO_SYS */ diff --git a/external/badvpn_dns/lwip/src/core/tcp.c b/external/badvpn_dns/lwip/src/core/tcp.c deleted file mode 100644 index 55496d0..0000000 --- a/external/badvpn_dns/lwip/src/core/tcp.c +++ /dev/null @@ -1,1852 +0,0 @@ -/** - * @file - * Transmission Control Protocol for IP - * - * This file contains common functions for the TCP implementation, such as functinos - * for manipulating the data structures and the TCP timer functions. TCP functions - * related to input and output is found in tcp_in.c and tcp_out.c respectively. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/snmp.h" -#include "lwip/tcp.h" -#include "lwip/tcp_impl.h" -#include "lwip/debug.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/nd6.h" - -#include <string.h> - -#ifndef TCP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define TCP_LOCAL_PORT_RANGE_START 0xc000 -#define TCP_LOCAL_PORT_RANGE_END 0xffff -#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) -#endif - -#if LWIP_TCP_KEEPALIVE -#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) -#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) -#else /* LWIP_TCP_KEEPALIVE */ -#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE -#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT -#endif /* LWIP_TCP_KEEPALIVE */ - -const char * const tcp_state_str[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; - -/* last local TCP port */ -static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; - -/* Incremented every coarse grained timer shot (typically every 500 ms). */ -u32_t tcp_ticks; -const u8_t tcp_backoff[13] = - { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; - /* Times per slowtmr hits */ -const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; - -/* The TCP PCB lists. */ - -/** List of all TCP PCBs bound but not yet (connected || listening) */ -struct tcp_pcb *tcp_bound_pcbs; -/** List of all TCP PCBs in LISTEN state */ -union tcp_listen_pcbs_t tcp_listen_pcbs; -/** List of all TCP PCBs that are in a state in which - * they accept or send data. */ -struct tcp_pcb *tcp_active_pcbs; -/** List of all TCP PCBs in TIME-WAIT state */ -struct tcp_pcb *tcp_tw_pcbs; - -#define NUM_TCP_PCB_LISTS 4 -#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 -/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ -struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, - &tcp_active_pcbs, &tcp_tw_pcbs}; - -/** Only used for temporary storage. */ -struct tcp_pcb *tcp_tmp_pcb; - -u8_t tcp_active_pcbs_changed; - -/** Timer counter to handle calling slow-timer from tcp_tmr() */ -static u8_t tcp_timer; -static u8_t tcp_timer_ctr; -static u16_t tcp_new_port(void); - -/** - * Initialize this module. - */ -void -tcp_init(void) -{ -#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) - tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ -} - -/** - * Called periodically to dispatch TCP timers. - */ -void -tcp_tmr(void) -{ - /* Call tcp_fasttmr() every 250 ms */ - tcp_fasttmr(); - - if (++tcp_timer & 1) { - /* Call tcp_tmr() every 500 ms, i.e., every other timer - tcp_tmr() is called. */ - tcp_slowtmr(); - } -} - -/** - * Closes the TX side of a connection held by the PCB. - * For tcp_close(), a RST is sent if the application didn't receive all data - * (tcp_recved() not called for all data passed to recv callback). - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it. - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -static err_t -tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) -{ - err_t err; - - if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { - if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { - /* Not all data received by application, send RST to tell the remote - side about this. */ - LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); - - /* don't call tcp_abort here: we must not deallocate the pcb since - that might not be expected when calling tcp_close */ - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); - - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - if (pcb->state == ESTABLISHED) { - /* move to TIME_WAIT since we close actively */ - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ - memp_free(MEMP_TCP_PCB, pcb); - } - return ERR_OK; - } - } - - switch (pcb->state) { - case CLOSED: - /* Closing a pcb in the CLOSED state might seem erroneous, - * however, it is in this state once allocated and as yet unused - * and the user needs some way to free it should the need arise. - * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) - * or for a pcb that has been used and then entered the CLOSED state - * is erroneous, but this should never happen as the pcb has in those cases - * been freed, and so any remaining handles are bogus. */ - err = ERR_OK; - if (pcb->local_port != 0 || pcb->bound_to_netif) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - memp_free(MEMP_TCP_PCB, pcb); - pcb = NULL; - break; - case LISTEN: - err = ERR_OK; - tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); - memp_free(MEMP_TCP_PCB_LISTEN, pcb); - pcb = NULL; - break; - case SYN_SENT: - err = ERR_OK; - TCP_PCB_REMOVE_ACTIVE(pcb); - memp_free(MEMP_TCP_PCB, pcb); - pcb = NULL; - snmp_inc_tcpattemptfails(); - break; - case SYN_RCVD: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - snmp_inc_tcpattemptfails(); - pcb->state = FIN_WAIT_1; - } - break; - case ESTABLISHED: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - snmp_inc_tcpestabresets(); - pcb->state = FIN_WAIT_1; - } - break; - case CLOSE_WAIT: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - snmp_inc_tcpestabresets(); - pcb->state = LAST_ACK; - } - break; - default: - /* Has already been closed, do nothing. */ - err = ERR_OK; - pcb = NULL; - break; - } - - if (pcb != NULL && err == ERR_OK) { - /* To ensure all data has been sent when tcp_close returns, we have - to make sure tcp_output doesn't fail. - Since we don't really have to ensure all data has been sent when tcp_close - returns (unsent data is sent from tcp timer functions, also), we don't care - for the return value of tcp_output for now. */ - /* @todo: When implementing SO_LINGER, this must be changed somehow: - If SOF_LINGER is set, the data should be sent and acked before close returns. - This can only be valid for sequential APIs, not for the raw API. */ - tcp_output(pcb); - } - return err; -} - -/** - * Closes the connection held by the PCB. - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it (unless an error is returned). - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -err_t -tcp_close(struct tcp_pcb *pcb) -{ -#if TCP_DEBUG - LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ - - if (pcb->state != LISTEN) { - /* Set a flag not to receive any more data... */ - pcb->flags |= TF_RXCLOSED; - } - /* ... and close */ - return tcp_close_shutdown(pcb, 1); -} - -/** - * Causes all or part of a full-duplex connection of this PCB to be shut down. - * This doesn't deallocate the PCB unless shutting down both sides! - * Shutting down both sides is the same as calling tcp_close, so if it succeds, - * the PCB should not be referenced any more. - * - * @param pcb PCB to shutdown - * @param shut_rx shut down receive side if this is != 0 - * @param shut_tx shut down send side if this is != 0 - * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) - * another err_t on error. - */ -err_t -tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) -{ - if (pcb->state == LISTEN) { - return ERR_CONN; - } - if (shut_rx) { - /* shut down the receive side: set a flag not to receive any more data... */ - pcb->flags |= TF_RXCLOSED; - if (shut_tx) { - /* shutting down the tx AND rx side is the same as closing for the raw API */ - return tcp_close_shutdown(pcb, 1); - } - /* ... and free buffered data */ - if (pcb->refused_data != NULL) { - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - } - if (shut_tx) { - /* This can't happen twice since if it succeeds, the pcb's state is changed. - Only close in these states as the others directly deallocate the PCB */ - switch (pcb->state) { - case SYN_RCVD: - case ESTABLISHED: - case CLOSE_WAIT: - return tcp_close_shutdown(pcb, shut_rx); - default: - /* Not (yet?) connected, cannot shutdown the TX side as that would bring us - into CLOSED state, where the PCB is deallocated. */ - return ERR_CONN; - } - } - return ERR_OK; -} - -/** - * Abandons a connection and optionally sends a RST to the remote - * host. Deletes the local protocol control block. This is done when - * a connection is killed because of shortage of memory. - * - * @param pcb the tcp_pcb to abort - * @param reset boolean to indicate whether a reset should be sent - */ -void -tcp_abandon(struct tcp_pcb *pcb, int reset) -{ - u32_t seqno, ackno; -#if LWIP_CALLBACK_API - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - void *errf_arg; - - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", - pcb->state != LISTEN); - /* Figure out on which TCP PCB list we are, and remove us. If we - are in an active state, call the receive function associated with - the PCB with a NULL argument, and send an RST to the remote end. */ - if (pcb->state == TIME_WAIT) { - tcp_pcb_remove(&tcp_tw_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else { - int send_rst = reset && (pcb->state != CLOSED); - seqno = pcb->snd_nxt; - ackno = pcb->rcv_nxt; -#if LWIP_CALLBACK_API - errf = pcb->errf; -#endif /* LWIP_CALLBACK_API */ - errf_arg = pcb->callback_arg; - TCP_PCB_REMOVE_ACTIVE(pcb); - if (pcb->unacked != NULL) { - tcp_segs_free(pcb->unacked); - } - if (pcb->unsent != NULL) { - tcp_segs_free(pcb->unsent); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - tcp_segs_free(pcb->ooseq); - } -#endif /* TCP_QUEUE_OOSEQ */ - if (send_rst) { - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); - } - memp_free(MEMP_TCP_PCB, pcb); - TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); - } -} - -/** - * Aborts the connection by sending a RST (reset) segment to the remote - * host. The pcb is deallocated. This function never fails. - * - * ATTENTION: When calling this from one of the TCP callbacks, make - * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise - * or you will risk accessing deallocated memory or memory leaks! - * - * @param pcb the tcp pcb to abort - */ -void -tcp_abort(struct tcp_pcb *pcb) -{ - tcp_abandon(pcb, 1); -} - -/** - * Binds the connection to a local portnumber and IP address. If the - * IP address is not given (i.e., ipaddr == NULL), the IP address of - * the outgoing network interface is used instead. - * - * @param pcb the tcp_pcb to bind (no check is done whether this pcb is - * already bound!) - * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind - * to any local address - * @param port the local port to bind to - * @return ERR_USE if the port is already in use - * ERR_VAL if bind failed because the PCB is not in a valid state - * ERR_OK if bound - */ -err_t -tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) -{ - int i; - int max_pcb_list = NUM_TCP_PCB_LISTS; - struct tcp_pcb *cpcb; - - LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); - -#if SO_REUSE - /* Unless the REUSEADDR flag is set, - we have to check the pcbs in TIME-WAIT state, also. - We do not dump TIME_WAIT pcb's; they can still be matched by incoming - packets using both local and remote IP addresses and ports to distinguish. - */ - if (ip_get_option(pcb, SOF_REUSEADDR)) { - max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; - } -#endif /* SO_REUSE */ - - if (port == 0) { - port = tcp_new_port(); - if (port == 0) { - return ERR_BUF; - } - } - - /* Check if the address already is in use (on all lists) */ - for (i = 0; i < max_pcb_list; i++) { - for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if (cpcb->local_port == port) { -#if SO_REUSE - /* Omit checking for the same port if both pcbs have REUSEADDR set. - For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in - tcp_connect. */ - if (!ip_get_option(pcb, SOF_REUSEADDR) || - !ip_get_option(cpcb, SOF_REUSEADDR)) -#endif /* SO_REUSE */ - { - /* @todo: check accept_any_ip_version */ - if (IP_PCB_IPVER_EQ(pcb, cpcb) && - (ipX_addr_isany(PCB_ISIPV6(pcb), &cpcb->local_ip) || - ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr)) || - ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, ip_2_ipX(ipaddr)))) { - return ERR_USE; - } - } - } - } - } - - pcb->bound_to_netif = 0; - if (!ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr))) { - ipX_addr_set(PCB_ISIPV6(pcb), &pcb->local_ip, ip_2_ipX(ipaddr)); - } - pcb->local_port = port; - TCP_REG(&tcp_bound_pcbs, pcb); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); - return ERR_OK; -} - -err_t -tcp_bind_to_netif(struct tcp_pcb *pcb, const char ifname[3]) -{ - LWIP_ERROR("tcp_bind_if: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); - - /* Check if the interface is already in use */ - for (int i = 0; i < NUM_TCP_PCB_LISTS; i++) { - for(struct tcp_pcb *cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if (IP_PCB_IPVER_EQ(pcb, cpcb) && - cpcb->bound_to_netif && - !memcmp(cpcb->local_netif, ifname, sizeof(cpcb->local_netif))) { - return ERR_USE; - } - } - } - - pcb->bound_to_netif = 1; - ipX_addr_set_any(PCB_ISIPV6(pcb), &pcb->local_ip); - pcb->local_port = 0; - memcpy(pcb->local_netif, ifname, sizeof(pcb->local_netif)); - TCP_REG(&tcp_bound_pcbs, pcb); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind_to_netif: bind to interface %c%c%c\n", ifname[0], ifname[1], ifname[2])); - return ERR_OK; -} - -#if LWIP_CALLBACK_API -/** - * Default accept callback if no accept callback is specified by the user. - */ -static err_t -tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) -{ - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(err); - - return ERR_ABRT; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * Set the state of the connection to be LISTEN, which means that it - * is able to accept incoming connections. The protocol control block - * is reallocated in order to consume less memory. Setting the - * connection to LISTEN is an irreversible process. - * - * @param pcb the original tcp_pcb - * @param backlog the incoming connections queue limit - * @return tcp_pcb used for listening, consumes less memory. - * - * @note The original tcp_pcb is freed. This function therefore has to be - * called like this: - * tpcb = tcp_listen(tpcb); - */ -struct tcp_pcb * -tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) -{ - struct tcp_pcb_listen *lpcb; - - LWIP_UNUSED_ARG(backlog); - LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); - - /* already listening? */ - if (pcb->state == LISTEN) { - return pcb; - } -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR) && !pcb->have_local_netif) { - /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage - is declared (listen-/connection-pcb), we have to make sure now that - this port is only used once for every local IP. */ - for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if ((lpcb->local_port == pcb->local_port) && - IP_PCB_IPVER_EQ(pcb, lpcb)) { - if (ipX_addr_cmp(PCB_ISIPV6(pcb), &lpcb->local_ip, &pcb->local_ip)) { - /* this address/port is already used */ - return NULL; - } - } - } - } -#endif /* SO_REUSE */ - lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); - if (lpcb == NULL) { - return NULL; - } - lpcb->callback_arg = pcb->callback_arg; - lpcb->bound_to_netif = pcb->bound_to_netif; - lpcb->local_port = pcb->local_port; - memcpy(lpcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)); - lpcb->state = LISTEN; - lpcb->prio = pcb->prio; - lpcb->so_options = pcb->so_options; - ip_set_option(lpcb, SOF_ACCEPTCONN); - lpcb->ttl = pcb->ttl; - lpcb->tos = pcb->tos; -#if LWIP_IPV6 - PCB_ISIPV6(lpcb) = PCB_ISIPV6(pcb); - lpcb->accept_any_ip_version = 0; -#endif /* LWIP_IPV6 */ - ipX_addr_copy(PCB_ISIPV6(pcb), lpcb->local_ip, pcb->local_ip); - if (pcb->local_port != 0 || pcb->bound_to_netif) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - memp_free(MEMP_TCP_PCB, pcb); -#if LWIP_CALLBACK_API - lpcb->accept = tcp_accept_null; -#endif /* LWIP_CALLBACK_API */ -#if TCP_LISTEN_BACKLOG - lpcb->accepts_pending = 0; - lpcb->backlog = (backlog ? backlog : 1); -#endif /* TCP_LISTEN_BACKLOG */ - TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); - return (struct tcp_pcb *)lpcb; -} - -#if LWIP_IPV6 -/** - * Same as tcp_listen_with_backlog, but allows to accept IPv4 and IPv6 - * connections, if the pcb's local address is set to ANY. - */ -struct tcp_pcb * -tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog) -{ - struct tcp_pcb *lpcb; - - lpcb = tcp_listen_with_backlog(pcb, backlog); - if ((lpcb != NULL) && - ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { - /* The default behavior is to accept connections on either - * IPv4 or IPv6, if not bound. */ - /* @see NETCONN_FLAG_IPV6_V6ONLY for changing this behavior */ - ((struct tcp_pcb_listen*)lpcb)->accept_any_ip_version = 1; - } - return lpcb; -} -#endif /* LWIP_IPV6 */ - -/** - * Update the state that tracks the available window space to advertise. - * - * Returns how much extra window would be advertised if we sent an - * update now. - */ -u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) -{ - u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; - - if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { - /* we can advertise more window */ - pcb->rcv_ann_wnd = pcb->rcv_wnd; - return new_right_edge - pcb->rcv_ann_right_edge; - } else { - if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { - /* Can happen due to other end sending out of advertised window, - * but within actual available (but not yet advertised) window */ - pcb->rcv_ann_wnd = 0; - } else { - /* keep the right edge of window constant */ - u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; - LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); - pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; - } - return 0; - } -} - -/** - * This function should be called by the application when it has - * processed the data. The purpose is to advertise a larger window - * when the data has been processed. - * - * @param pcb the tcp_pcb for which data is read - * @param len the amount of bytes that have been read by the application - */ -void -tcp_recved(struct tcp_pcb *pcb, u16_t len) -{ - int wnd_inflation; - - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_recved for listen-pcbs", - pcb->state != LISTEN); - LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", - len <= 0xffff - pcb->rcv_wnd ); - - pcb->rcv_wnd += len; - if (pcb->rcv_wnd > TCP_WND) { - pcb->rcv_wnd = TCP_WND; - } - - wnd_inflation = tcp_update_rcv_ann_wnd(pcb); - - /* If the change in the right edge of window is significant (default - * watermark is TCP_WND/4), then send an explicit update now. - * Otherwise wait for a packet to be sent in the normal course of - * events (or more window to be available later) */ - if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { - tcp_ack_now(pcb); - tcp_output(pcb); - } - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", - len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); -} - -/** - * Allocate a new local TCP port. - * - * @return a new (free) local TCP port number - */ -static u16_t -tcp_new_port(void) -{ - u8_t i; - u16_t n = 0; - struct tcp_pcb *pcb; - -again: - if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { - tcp_port = TCP_LOCAL_PORT_RANGE_START; - } - /* Check all PCB lists. */ - for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { - for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == tcp_port) { - if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - } - return tcp_port; -} - -/** - * Connects to another host. The function given as the "connected" - * argument will be called when the connection has been established. - * - * @param pcb the tcp_pcb used to establish the connection - * @param ipaddr the remote ip address to connect to - * @param port the remote tcp port to connect to - * @param connected callback function to call when connected (or on error) - * @return ERR_VAL if invalid arguments are given - * ERR_OK if connect request has been sent - * other err_t values if connect request couldn't be sent - */ -err_t -tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, - tcp_connected_fn connected) -{ - err_t ret; - u32_t iss; - u16_t old_local_port; - - LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); - LWIP_ERROR("tcp_connect: cannot connect pcb bound to netif", !pcb->bound_to_netif, return ERR_VAL); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); - if (ipaddr != NULL) { - ipX_addr_set(PCB_ISIPV6(pcb), &pcb->remote_ip, ip_2_ipX(ipaddr)); - } else { - return ERR_VAL; - } - pcb->remote_port = port; - - /* check if we have a route to the remote host */ - if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { - /* no local IP address set, yet. */ - struct netif *netif; - ipX_addr_t *local_ip; - ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip); - if ((netif == NULL) || (local_ip == NULL)) { - /* Don't even try to send a SYN packet if we have no route - since that will fail. */ - return ERR_RTE; - } - /* Use the address as local address of the pcb. */ - ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip); - } - - old_local_port = pcb->local_port; - if (pcb->local_port == 0) { - pcb->local_port = tcp_new_port(); - if (pcb->local_port == 0) { - return ERR_BUF; - } - } -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR)) { - /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure - now that the 5-tuple is unique. */ - struct tcp_pcb *cpcb; - int i; - /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ - for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { - for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if ((cpcb->local_port == pcb->local_port) && - (cpcb->remote_port == port) && - IP_PCB_IPVER_EQ(cpcb, pcb) && - ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, &pcb->local_ip) && - ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->remote_ip, ip_2_ipX(ipaddr))) { - /* linux returns EISCONN here, but ERR_USE should be OK for us */ - return ERR_USE; - } - } - } - } -#endif /* SO_REUSE */ - iss = tcp_next_iss(); - pcb->rcv_nxt = 0; - pcb->snd_nxt = iss; - pcb->lastack = iss - 1; - pcb->snd_lbb = iss - 1; - pcb->rcv_wnd = TCP_WND; - pcb->rcv_ann_wnd = TCP_WND; - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->snd_wnd = TCP_WND; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb)); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - pcb->cwnd = 1; - pcb->ssthresh = pcb->mss * 10; -#if LWIP_CALLBACK_API - pcb->connected = connected; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(connected); -#endif /* LWIP_CALLBACK_API */ - - /* Send a SYN together with the MSS option. */ - ret = tcp_enqueue_flags(pcb, TCP_SYN); - if (ret == ERR_OK) { - /* SYN segment was enqueued, changed the pcbs state now */ - pcb->state = SYN_SENT; - if (old_local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - TCP_REG_ACTIVE(pcb); - snmp_inc_tcpactiveopens(); - - tcp_output(pcb); - } - return ret; -} - -/** - * Called every 500 ms and implements the retransmission timer and the timer that - * removes PCBs that have been in TIME-WAIT for enough time. It also increments - * various timers such as the inactivity timer in each PCB. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_slowtmr(void) -{ - struct tcp_pcb *pcb, *prev; - u16_t eff_wnd; - u8_t pcb_remove; /* flag if a PCB should be removed */ - u8_t pcb_reset; /* flag if a RST should be sent when removing */ - err_t err; - - err = ERR_OK; - - ++tcp_ticks; - ++tcp_timer_ctr; - -tcp_slowtmr_start: - /* Steps through all of the active PCBs. */ - prev = NULL; - pcb = tcp_active_pcbs; - if (pcb == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); - } - while (pcb != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); - if (pcb->last_timer == tcp_timer_ctr) { - /* skip this pcb, we have already processed it */ - pcb = pcb->next; - continue; - } - pcb->last_timer = tcp_timer_ctr; - - pcb_remove = 0; - pcb_reset = 0; - - if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); - } - else if (pcb->nrtx == TCP_MAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); - } else { - if (pcb->persist_backoff > 0) { - /* If snd_wnd is zero, use persist timer to send 1 byte probes - * instead of using the standard retransmission mechanism. */ - pcb->persist_cnt++; - if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { - pcb->persist_cnt = 0; - if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { - pcb->persist_backoff++; - } - tcp_zero_window_probe(pcb); - } - } else { - /* Increase the retransmission timer if it is running */ - if(pcb->rtime >= 0) { - ++pcb->rtime; - } - - if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { - /* Time for a retransmission. */ - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F - " pcb->rto %"S16_F"\n", - pcb->rtime, pcb->rto)); - - /* Double retransmission time-out unless we are trying to - * connect to somebody (i.e., we are in SYN_SENT). */ - if (pcb->state != SYN_SENT) { - pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; - } - - /* Reset the retransmission timer. */ - pcb->rtime = 0; - - /* Reduce congestion window and ssthresh. */ - eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); - pcb->ssthresh = eff_wnd >> 1; - if (pcb->ssthresh < (pcb->mss << 1)) { - pcb->ssthresh = (pcb->mss << 1); - } - pcb->cwnd = pcb->mss; - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F - " ssthresh %"U16_F"\n", - pcb->cwnd, pcb->ssthresh)); - - /* The following needs to be called AFTER cwnd is set to one - mss - STJ */ - tcp_rexmit_rto(pcb); - } - } - } - /* Check if this PCB has stayed too long in FIN-WAIT-2 */ - if (pcb->state == FIN_WAIT_2) { - /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ - if (pcb->flags & TF_RXCLOSED) { - /* PCB was fully closed (either through close() or SHUT_RDWR): - normal FIN-WAIT timeout handling. */ - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); - } - } - } - - /* Check if KEEPALIVE should be sent */ - if(ip_get_option(pcb, SOF_KEEPALIVE) && - ((pcb->state == ESTABLISHED) || - (pcb->state == CLOSE_WAIT))) { - if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) - { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - ++pcb_remove; - ++pcb_reset; - } - else if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) - / TCP_SLOW_INTERVAL) - { - tcp_keepalive(pcb); - pcb->keep_cnt_sent++; - } - } - - /* If this PCB has queued out of sequence data, but has been - inactive for too long, will drop the data (it will eventually - be retransmitted). */ -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL && - (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); - } -#endif /* TCP_QUEUE_OOSEQ */ - - /* Check if this PCB has stayed too long in SYN-RCVD */ - if (pcb->state == SYN_RCVD) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); - } - } - - /* Check if this PCB has stayed too long in LAST-ACK */ - if (pcb->state == LAST_ACK) { - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); - } - } - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; - tcp_err_fn err_fn; - void *err_arg; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_active_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); - tcp_active_pcbs = pcb->next; - } - - if (pcb_reset) { - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); - } - - err_fn = pcb->errf; - err_arg = pcb->callback_arg; - pcb2 = pcb; - pcb = pcb->next; - memp_free(MEMP_TCP_PCB, pcb2); - - tcp_active_pcbs_changed = 0; - TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - } else { - /* get the 'next' element now and work with 'prev' below (in case of abort) */ - prev = pcb; - pcb = pcb->next; - - /* We check if we should poll the connection. */ - ++prev->polltmr; - if (prev->polltmr >= prev->pollinterval) { - prev->polltmr = 0; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); - tcp_active_pcbs_changed = 0; - TCP_EVENT_POLL(prev, err); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - /* if err == ERR_ABRT, 'prev' is already deallocated */ - if (err == ERR_OK) { - tcp_output(prev); - } - } - } - } - - - /* Steps through all of the TIME-WAIT PCBs. */ - prev = NULL; - pcb = tcp_tw_pcbs; - while (pcb != NULL) { - LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - pcb_remove = 0; - - /* Check if this PCB has stayed long enough in TIME-WAIT */ - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - } - - - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_tw_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); - tcp_tw_pcbs = pcb->next; - } - pcb2 = pcb; - pcb = pcb->next; - memp_free(MEMP_TCP_PCB, pcb2); - } else { - prev = pcb; - pcb = pcb->next; - } - } -} - -/** - * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously - * "refused" by upper layer (application) and sends delayed ACKs. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_fasttmr(void) -{ - struct tcp_pcb *pcb; - - ++tcp_timer_ctr; - -tcp_fasttmr_start: - pcb = tcp_active_pcbs; - - while(pcb != NULL) { - if (pcb->last_timer != tcp_timer_ctr) { - struct tcp_pcb *next; - pcb->last_timer = tcp_timer_ctr; - /* send delayed ACKs */ - if (pcb->flags & TF_ACK_DELAY) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); - tcp_ack_now(pcb); - tcp_output(pcb); - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } - - next = pcb->next; - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - tcp_active_pcbs_changed = 0; - tcp_process_refused_data(pcb); - if (tcp_active_pcbs_changed) { - /* application callback has changed the pcb list: restart the loop */ - goto tcp_fasttmr_start; - } - } - pcb = next; - } - } -} - -/** Pass pcb->refused_data to the recv callback */ -err_t -tcp_process_refused_data(struct tcp_pcb *pcb) -{ - err_t err; - u8_t refused_flags = pcb->refused_data->flags; - /* set pcb->refused_data to NULL in case the callback frees it and then - closes the pcb */ - struct pbuf *refused_data = pcb->refused_data; - pcb->refused_data = NULL; - /* Notify again application with data previously received. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); - TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); - if (err == ERR_OK) { - /* did refused_data include a FIN? */ - if (refused_flags & PBUF_FLAG_TCP_FIN) { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - } - } else if (err == ERR_ABRT) { - /* if err == ERR_ABRT, 'pcb' is already deallocated */ - /* Drop incoming packets because pcb is "full" (only if the incoming - segment contains data). */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is "full"\n")); - return ERR_ABRT; - } else { - /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ - pcb->refused_data = refused_data; - } - return ERR_OK; -} - -/** - * Deallocates a list of TCP segments (tcp_seg structures). - * - * @param seg tcp_seg list of TCP segments to free - */ -void -tcp_segs_free(struct tcp_seg *seg) -{ - while (seg != NULL) { - struct tcp_seg *next = seg->next; - tcp_seg_free(seg); - seg = next; - } -} - -/** - * Frees a TCP segment (tcp_seg structure). - * - * @param seg single tcp_seg to free - */ -void -tcp_seg_free(struct tcp_seg *seg) -{ - if (seg != NULL) { - if (seg->p != NULL) { - pbuf_free(seg->p); -#if TCP_DEBUG - seg->p = NULL; -#endif /* TCP_DEBUG */ - } - memp_free(MEMP_TCP_SEG, seg); - } -} - -/** - * Sets the priority of a connection. - * - * @param pcb the tcp_pcb to manipulate - * @param prio new priority - */ -void -tcp_setprio(struct tcp_pcb *pcb, u8_t prio) -{ - pcb->prio = prio; -} - -#if TCP_QUEUE_OOSEQ -/** - * Returns a copy of the given TCP segment. - * The pbuf and data are not copied, only the pointers - * - * @param seg the old tcp_seg - * @return a copy of seg - */ -struct tcp_seg * -tcp_seg_copy(struct tcp_seg *seg) -{ - struct tcp_seg *cseg; - - cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); - if (cseg == NULL) { - return NULL; - } - SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); - pbuf_ref(cseg->p); - return cseg; -} -#endif /* TCP_QUEUE_OOSEQ */ - -#if LWIP_CALLBACK_API -/** - * Default receive callback that is called if the user didn't register - * a recv callback for the pcb. - */ -err_t -tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - LWIP_UNUSED_ARG(arg); - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } else if (err == ERR_OK) { - return tcp_close(pcb); - } - return ERR_OK; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * Kills the oldest active connection that has the same or lower priority than - * 'prio'. - * - * @param prio minimum priority - */ -static void -tcp_kill_prio(u8_t prio) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - u8_t mprio; - - - mprio = TCP_PRIO_MAX; - - /* We kill the oldest active connection that has lower priority than prio. */ - inactivity = 0; - inactive = NULL; - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->prio <= prio && - pcb->prio <= mprio && - (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - mprio = pcb->prio; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/** - * Kills the oldest connection that is in TIME_WAIT state. - * Called from tcp_alloc() if no more connections are available. - */ -static void -tcp_kill_timewait(void) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - inactivity = 0; - inactive = NULL; - /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/** - * Allocate a new tcp_pcb structure. - * - * @param prio priority for the new pcb - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_alloc(u8_t prio) -{ - struct tcp_pcb *pcb; - u32_t iss; - - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in TIME-WAIT. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); - tcp_kill_timewait(); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing active connections with lower priority than the new one. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); - tcp_kill_prio(prio); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed twice before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: timewait PCB was freed above */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - memset(pcb, 0, sizeof(struct tcp_pcb)); - pcb->prio = prio; - pcb->snd_buf = TCP_SND_BUF; - pcb->snd_queuelen = 0; - pcb->rcv_wnd = TCP_WND; - pcb->rcv_ann_wnd = TCP_WND; - pcb->tos = 0; - pcb->ttl = TCP_TTL; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; - pcb->rto = 3000 / TCP_SLOW_INTERVAL; - pcb->sa = 0; - pcb->sv = 3000 / TCP_SLOW_INTERVAL; - pcb->rtime = -1; - pcb->cwnd = 1; - iss = tcp_next_iss(); - pcb->snd_wl2 = iss; - pcb->snd_nxt = iss; - pcb->lastack = iss; - pcb->snd_lbb = iss; - pcb->tmr = tcp_ticks; - pcb->last_timer = tcp_timer_ctr; - - pcb->polltmr = 0; - -#if LWIP_CALLBACK_API - pcb->recv = tcp_recv_null; -#endif /* LWIP_CALLBACK_API */ - - /* Init KEEPALIVE timer */ - pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; - -#if LWIP_TCP_KEEPALIVE - pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; - pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; -#endif /* LWIP_TCP_KEEPALIVE */ - - pcb->keep_cnt_sent = 0; - } - return pcb; -} - -/** - * Creates a new TCP protocol control block but doesn't place it on - * any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * - * @internal: Maybe there should be a idle TCP PCB list where these - * PCBs are put on. Port reservation using tcp_bind() is implemented but - * allocated pcbs that are not bound can't be killed automatically if wanting - * to allocate a pcb with higher prio (@see tcp_kill_prio()) - * - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new(void) -{ - return tcp_alloc(TCP_PRIO_NORMAL); -} - -#if LWIP_IPV6 -/** - * Creates a new TCP-over-IPv6 protocol control block but doesn't - * place it on any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new_ip6(void) -{ - struct tcp_pcb * pcb; - pcb = tcp_alloc(TCP_PRIO_NORMAL); - ip_set_v6(pcb, 1); - return pcb; -} -#endif /* LWIP_IPV6 */ - -/** - * Used to specify the argument that should be passed callback - * functions. - * - * @param pcb tcp_pcb to set the callback argument - * @param arg void pointer argument to pass to callback functions - */ -void -tcp_arg(struct tcp_pcb *pcb, void *arg) -{ - /* This function is allowed to be called for both listen pcbs and - connection pcbs. */ - pcb->callback_arg = arg; -} -#if LWIP_CALLBACK_API - -/** - * Used to specify the function that should be called when a TCP - * connection receives data. - * - * @param pcb tcp_pcb to set the recv callback - * @param recv callback function to call for this pcb when data is received - */ -void -tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) -{ - LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); - pcb->recv = recv; -} - -/** - * Used to specify the function that should be called when TCP data - * has been successfully delivered to the remote host. - * - * @param pcb tcp_pcb to set the sent callback - * @param sent callback function to call for this pcb when data is successfully sent - */ -void -tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) -{ - LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); - pcb->sent = sent; -} - -/** - * Used to specify the function that should be called when a fatal error - * has occured on the connection. - * - * @param pcb tcp_pcb to set the err callback - * @param err callback function to call for this pcb when a fatal error - * has occured on the connection - */ -void -tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) -{ - LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); - pcb->errf = err; -} - -/** - * Used for specifying the function that should be called when a - * LISTENing connection has been connected to another host. - * - * @param pcb tcp_pcb to set the accept callback - * @param accept callback function to call for this pcb when LISTENing - * connection has been connected to another host - */ -void -tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) -{ - /* This function is allowed to be called for both listen pcbs and - connection pcbs. */ - pcb->accept = accept; -} -#endif /* LWIP_CALLBACK_API */ - - -/** - * Used to specify the function that should be called periodically - * from TCP. The interval is specified in terms of the TCP coarse - * timer interval, which is called twice a second. - * - */ -void -tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) -{ - LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); -#if LWIP_CALLBACK_API - pcb->poll = poll; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(poll); -#endif /* LWIP_CALLBACK_API */ - pcb->pollinterval = interval; -} - -/** - * Purges a TCP PCB. Removes any buffered data and frees the buffer memory - * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). - * - * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! - */ -void -tcp_pcb_purge(struct tcp_pcb *pcb) -{ - if (pcb->state != CLOSED && - pcb->state != TIME_WAIT && - pcb->state != LISTEN) { - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); - -#if TCP_LISTEN_BACKLOG - if (pcb->state == SYN_RCVD) { - /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ - struct tcp_pcb_listen *lpcb; - LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", - tcp_listen_pcbs.listen_pcbs != NULL); - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if ((!lpcb->bound_to_netif && !pcb->bound_to_netif && - (lpcb->local_port == pcb->local_port) && - IP_PCB_IPVER_EQ(pcb, lpcb) && - (ipX_addr_isany(PCB_ISIPV6(lpcb), &lpcb->local_ip) || - ipX_addr_cmp(PCB_ISIPV6(lpcb), &pcb->local_ip, &lpcb->local_ip))) || - (lpcb->bound_to_netif && pcb->bound_to_netif && - !memcmp(lpcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)))) { - /* port and address of the listen pcb match the timed-out pcb */ - LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", - lpcb->accepts_pending > 0); - lpcb->accepts_pending--; - break; - } - } - } -#endif /* TCP_LISTEN_BACKLOG */ - - - if (pcb->refused_data != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - if (pcb->unsent != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); - } - if (pcb->unacked != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); - } - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; -#endif /* TCP_QUEUE_OOSEQ */ - - /* Stop the retransmission timer as it will expect data on unacked - queue if it fires */ - pcb->rtime = -1; - - tcp_segs_free(pcb->unsent); - tcp_segs_free(pcb->unacked); - pcb->unacked = pcb->unsent = NULL; -#if TCP_OVERSIZE - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - } -} - -/** - * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. - * - * @param pcblist PCB list to purge. - * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! - */ -void -tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) -{ - TCP_RMV(pcblist, pcb); - - tcp_pcb_purge(pcb); - - /* if there is an outstanding delayed ACKs, send it */ - if (pcb->state != TIME_WAIT && - pcb->state != LISTEN && - pcb->flags & TF_ACK_DELAY) { - pcb->flags |= TF_ACK_NOW; - tcp_output(pcb); - } - - if (pcb->state != LISTEN) { - LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); - LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); -#if TCP_QUEUE_OOSEQ - LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); -#endif /* TCP_QUEUE_OOSEQ */ - } - - pcb->state = CLOSED; - - LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); -} - -/** - * Calculates a new initial sequence number for new connections. - * - * @return u32_t pseudo random sequence number - */ -u32_t -tcp_next_iss(void) -{ - static u32_t iss = 6510; - - iss += tcp_ticks; /* XXX */ - return iss; -} - -#if TCP_CALCULATE_EFF_SEND_MSS -/** - * Calcluates the effective send mss that can be used for a specific IP address - * by using ip_route to determin the netif used to send to the address and - * calculating the minimum of TCP_MSS and that netif's mtu (if set). - */ -u16_t -tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest -#if LWIP_IPV6 - , ipX_addr_t *src, u8_t isipv6 -#endif /* LWIP_IPV6 */ - ) -{ - u16_t mss_s; - struct netif *outif; - s16_t mtu; - - outif = ipX_route(isipv6, src, dest); -#if LWIP_IPV6 - if (isipv6) { - /* First look in destination cache, to see if there is a Path MTU. */ - mtu = nd6_get_destination_mtu(ipX_2_ip6(dest), outif); - } else -#endif /* LWIP_IPV6 */ - { - if (outif == NULL) { - return sendmss; - } - mtu = outif->mtu; - } - - if (mtu != 0) { - mss_s = mtu - IP_HLEN - TCP_HLEN; -#if LWIP_IPV6 - /* for IPv6, substract the difference in header size */ - mss_s -= (IP6_HLEN - IP_HLEN); -#endif /* LWIP_IPV6 */ - /* RFC 1122, chap 4.2.2.6: - * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize - * We correct for TCP options in tcp_write(), and don't support IP options. - */ - sendmss = LWIP_MIN(sendmss, mss_s); - } - return sendmss; -} -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -const char* -tcp_debug_state_str(enum tcp_state s) -{ - return tcp_state_str[s]; -} - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -/** - * Print a tcp header for debugging purposes. - * - * @param tcphdr pointer to a struct tcp_hdr - */ -void -tcp_debug_print(struct tcp_hdr *tcphdr) -{ - LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - ntohs(tcphdr->src), ntohs(tcphdr->dest))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", - ntohl(tcphdr->seqno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", - ntohl(tcphdr->ackno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", - TCPH_HDRLEN(tcphdr), - TCPH_FLAGS(tcphdr) >> 5 & 1, - TCPH_FLAGS(tcphdr) >> 4 & 1, - TCPH_FLAGS(tcphdr) >> 3 & 1, - TCPH_FLAGS(tcphdr) >> 2 & 1, - TCPH_FLAGS(tcphdr) >> 1 & 1, - TCPH_FLAGS(tcphdr) & 1, - ntohs(tcphdr->wnd))); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", - ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); -} - -/** - * Print a tcp state for debugging purposes. - * - * @param s enum tcp_state to print - */ -void -tcp_debug_print_state(enum tcp_state s) -{ - LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); -} - -/** - * Print tcp flags for debugging purposes. - * - * @param flags tcp flags, all active flags are printed - */ -void -tcp_debug_print_flags(u8_t flags) -{ - if (flags & TCP_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); - } - if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); - } - if (flags & TCP_RST) { - LWIP_DEBUGF(TCP_DEBUG, ("RST ")); - } - if (flags & TCP_PSH) { - LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); - } - if (flags & TCP_ACK) { - LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); - } - if (flags & TCP_URG) { - LWIP_DEBUGF(TCP_DEBUG, ("URG ")); - } - if (flags & TCP_ECE) { - LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); - } - if (flags & TCP_CWR) { - LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); - } - LWIP_DEBUGF(TCP_DEBUG, ("\n")); -} - -/** - * Print all tcp_pcbs in every list for debugging purposes. - */ -void -tcp_debug_print_pcbs(void) -{ - struct tcp_pcb *pcb; - LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } - LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); - for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } - LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } -} - -/** - * Check state consistency of the tcp_pcb lists. - */ -s16_t -tcp_pcbs_sane(void) -{ - struct tcp_pcb *pcb; - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - } - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - } - return 1; -} -#endif /* TCP_DEBUG */ - -#endif /* LWIP_TCP */ diff --git a/external/badvpn_dns/lwip/src/core/tcp_in.c b/external/badvpn_dns/lwip/src/core/tcp_in.c deleted file mode 100644 index 92ee2b2..0000000 --- a/external/badvpn_dns/lwip/src/core/tcp_in.c +++ /dev/null @@ -1,1666 +0,0 @@ -/** - * @file - * Transmission Control Protocol, incoming traffic - * - * The input processing functions of the TCP layer. - * - * These functions are generally called in the order (ip_input() ->) - * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp_impl.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "arch/perf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#if LWIP_ND6_TCP_REACHABILITY_HINTS -#include "lwip/nd6.h" -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -/* These variables are global to all functions involved in the input - processing of TCP segments. They are set by the tcp_input() - function. */ -static struct tcp_seg inseg; -static struct tcp_hdr *tcphdr; -static u32_t seqno, ackno; -static u8_t flags; -static u16_t tcplen; - -static u8_t recv_flags; -static struct pbuf *recv_data; - -struct tcp_pcb *tcp_input_pcb; - -/* Forward declarations. */ -static err_t tcp_process(struct tcp_pcb *pcb); -static void tcp_receive(struct tcp_pcb *pcb); -static void tcp_parseopt(struct tcp_pcb *pcb); - -static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); -static err_t tcp_timewait_input(struct tcp_pcb *pcb); - -/** - * The initial input processing of TCP. It verifies the TCP header, demultiplexes - * the segment between the PCBs and passes it on to tcp_process(), which implements - * the TCP finite state machine. This function is called by the IP layer (in - * ip_input()). - * - * @param p received TCP segment to process (p->payload pointing to the TCP header) - * @param inp network interface on which this segment was received - */ -void -tcp_input(struct pbuf *p, struct netif *inp) -{ - struct tcp_pcb *pcb, *prev; - struct tcp_pcb_listen *lpcb; -#if SO_REUSE - struct tcp_pcb *lpcb_prev = NULL; - struct tcp_pcb_listen *lpcb_any = NULL; -#endif /* SO_REUSE */ - u8_t hdrlen; - err_t err; -#if CHECKSUM_CHECK_TCP - u16_t chksum; -#endif /* CHECKSUM_CHECK_TCP */ - - PERF_START; - - TCP_STATS_INC(tcp.recv); - snmp_inc_tcpinsegs(); - - tcphdr = (struct tcp_hdr *)p->payload; - -#if TCP_INPUT_DEBUG - tcp_debug_print(tcphdr); -#endif - - /* Check that TCP header fits in payload */ - if (p->len < sizeof(struct tcp_hdr)) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Don't even process incoming broadcasts/multicasts. */ - if ((!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp)) || - ipX_addr_ismulticast(ip_current_is_v6(), ipX_current_dest_addr())) { - TCP_STATS_INC(tcp.proterr); - goto dropped; - } - -#if CHECKSUM_CHECK_TCP - /* Verify TCP checksum. */ - chksum = ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_TCP, p->tot_len, - ipX_current_src_addr(), ipX_current_dest_addr()); - if (chksum != 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - chksum)); - tcp_debug_print(tcphdr); - TCP_STATS_INC(tcp.chkerr); - goto dropped; - } -#endif /* CHECKSUM_CHECK_TCP */ - - /* Move the payload pointer in the pbuf so that it points to the - TCP data instead of the TCP header. */ - hdrlen = TCPH_HDRLEN(tcphdr); - if(pbuf_header(p, -(hdrlen * 4))){ - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Convert fields in TCP header to host byte order. */ - tcphdr->src = ntohs(tcphdr->src); - tcphdr->dest = ntohs(tcphdr->dest); - seqno = tcphdr->seqno = ntohl(tcphdr->seqno); - ackno = tcphdr->ackno = ntohl(tcphdr->ackno); - tcphdr->wnd = ntohs(tcphdr->wnd); - - flags = TCPH_FLAGS(tcphdr); - tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); - - /* Demultiplex an incoming segment. First, we check if it is destined - for an active connection. */ - prev = NULL; - - - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - IP_PCB_IPVER_INPUT_MATCH(pcb) && - ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && - ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); - if (prev != NULL) { - prev->next = pcb->next; - pcb->next = tcp_active_pcbs; - tcp_active_pcbs = pcb; - } - LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); - break; - } - prev = pcb; - } - - if (pcb == NULL) { - /* If it did not go to an active connection, we check the connections - in the TIME-WAIT state. */ - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - IP_PCB_IPVER_INPUT_MATCH(pcb) && - ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && - ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { - /* We don't really care enough to move this PCB to the front - of the list since we are not very likely to receive that - many segments for connections in TIME-WAIT. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); - tcp_timewait_input(pcb); - pbuf_free(p); - return; - } - } - - /* Finally, if we still did not get a match, we check all PCBs that - are LISTENing for incoming connections. */ - prev = NULL; - struct tcp_pcb_listen *netif_pcb = NULL; - struct tcp_pcb *netif_pcb_prev; - for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if (lpcb->bound_to_netif) { - if (IP_PCB_IPVER_INPUT_MATCH(lpcb) && netif_is_named(inp, lpcb->local_netif)) { - netif_pcb = lpcb; - netif_pcb_prev = prev; - } - } - else if (lpcb->local_port == tcphdr->dest) { -#if LWIP_IPV6 - if (lpcb->accept_any_ip_version) { - /* found an ANY-match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; -#endif /* SO_REUSE */ - } else -#endif /* LWIP_IPV6 */ - if (IP_PCB_IPVER_INPUT_MATCH(lpcb)) { - if (ipX_addr_cmp(ip_current_is_v6(), &lpcb->local_ip, ipX_current_dest_addr())) { - /* found an exact match */ - break; - } else if (ipX_addr_isany(ip_current_is_v6(), &lpcb->local_ip)) { - /* found an ANY-match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; - #endif /* SO_REUSE */ - } - } - } - prev = (struct tcp_pcb *)lpcb; - } -#if SO_REUSE - /* first try specific local IP */ - if (lpcb == NULL) { - /* only pass to ANY if no specific local IP has been found */ - lpcb = lpcb_any; - prev = lpcb_prev; - } -#endif /* SO_REUSE */ - if (lpcb == NULL && netif_pcb) { - lpcb = netif_pcb; - prev = netif_pcb_prev; - } - if (lpcb != NULL) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - if (prev != NULL) { - ((struct tcp_pcb_listen *)prev)->next = lpcb->next; - /* our successor is the remainder of the listening list */ - lpcb->next = tcp_listen_pcbs.listen_pcbs; - /* put this listening pcb at the head of the listening list */ - tcp_listen_pcbs.listen_pcbs = lpcb; - } - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); - tcp_listen_input(lpcb); - pbuf_free(p); - return; - } - } - -#if TCP_INPUT_DEBUG - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); -#endif /* TCP_INPUT_DEBUG */ - - - if (pcb != NULL) { - /* The incoming segment belongs to a connection. */ -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - - /* Set up a tcp_seg structure. */ - inseg.next = NULL; - inseg.len = p->tot_len; - inseg.p = p; - inseg.tcphdr = tcphdr; - - recv_data = NULL; - recv_flags = 0; - - if (flags & TCP_PSH) { - p->flags |= PBUF_FLAG_PUSH; - } - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - if ((tcp_process_refused_data(pcb) == ERR_ABRT) || - ((pcb->refused_data != NULL) && (tcplen > 0))) { - /* pcb has been aborted or refused data is still refused and the new - segment contains data */ - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - goto aborted; - } - } - tcp_input_pcb = pcb; - err = tcp_process(pcb); - /* A return value of ERR_ABRT means that tcp_abort() was called - and that the pcb has been freed. If so, we don't do anything. */ - if (err != ERR_ABRT) { - if (recv_flags & TF_RESET) { - /* TF_RESET means that the connection was reset by the other - end. We then call the error callback to inform the - application that the connection is dead before we - deallocate the PCB. */ - TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else if (recv_flags & TF_CLOSED) { - /* The connection has been closed and we will deallocate the - PCB. */ - if (!(pcb->flags & TF_RXCLOSED)) { - /* Connection closed although the application has only shut down the - tx side: call the PCB's err callback and indicate the closure to - ensure the application doesn't continue using the PCB. */ - TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); - } - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else { - err = ERR_OK; - /* If the application has registered a "sent" function to be - called when new send buffer space is available, we call it - now. */ - if (pcb->acked > 0) { - TCP_EVENT_SENT(pcb, pcb->acked, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - - if (recv_data != NULL) { - LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); - if (pcb->flags & TF_RXCLOSED) { - /* received data although already closed -> abort (send RST) to - notify the remote host that not all data has been processed */ - pbuf_free(recv_data); - tcp_abort(pcb); - goto aborted; - } - - /* Notify application that data has been received. */ - TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); - if (err == ERR_ABRT) { - goto aborted; - } - - /* If the upper layer can't receive this data, store it */ - if (err != ERR_OK) { - pcb->refused_data = recv_data; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is "full"\n")); - } - } - - /* If a FIN segment was received, we call the callback - function with a NULL buffer to indicate EOF. */ - if (recv_flags & TF_GOT_FIN) { - if (pcb->refused_data != NULL) { - /* Delay this if we have refused data. */ - pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; - } else { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - } - - tcp_input_pcb = NULL; - /* Try to send something out. */ - tcp_output(pcb); -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - } - } - /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). - Below this line, 'pcb' may not be dereferenced! */ -aborted: - tcp_input_pcb = NULL; - recv_data = NULL; - - /* give up our reference to inseg.p */ - if (inseg.p != NULL) - { - pbuf_free(inseg.p); - inseg.p = NULL; - } - } else { - - /* If no matching PCB was found, send a TCP RST (reset) to the - sender. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); - if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { - TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); - } - pbuf_free(p); - } - - LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); - PERF_STOP("tcp_input"); - return; -dropped: - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); -} - -/** - * Called by tcp_input() when a segment arrives for a listening - * connection (from tcp_input()). - * - * @param pcb the tcp_pcb_listen for which a segment arrived - * @return ERR_OK if the segment was processed - * another err_t on error - * - * @note the return value is not (yet?) used in tcp_input() - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_listen_input(struct tcp_pcb_listen *pcb) -{ - struct tcp_pcb *npcb; - err_t rc; - - if (flags & TCP_RST) { - /* An incoming RST should be ignored. Return. */ - return ERR_OK; - } - - /* In the LISTEN state, we check for incoming SYN segments, - creates a new PCB, and responds with a SYN|ACK. */ - if (flags & TCP_ACK) { - /* For incoming segments with the ACK flag set, respond with a - RST. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); - } else if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); -#if TCP_LISTEN_BACKLOG - if (pcb->accepts_pending >= pcb->backlog) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); - return ERR_ABRT; - } -#endif /* TCP_LISTEN_BACKLOG */ - npcb = tcp_alloc(pcb->prio); - /* If a new PCB could not be created (probably due to lack of memory), - we don't do anything, but rely on the sender will retransmit the - SYN at a time when we have more memory available. */ - if (npcb == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } -#if TCP_LISTEN_BACKLOG - pcb->accepts_pending++; -#endif /* TCP_LISTEN_BACKLOG */ - /* Set up the new PCB. */ -#if LWIP_IPV6 - PCB_ISIPV6(npcb) = ip_current_is_v6(); -#endif /* LWIP_IPV6 */ - ipX_addr_copy(ip_current_is_v6(), npcb->local_ip, *ipX_current_dest_addr()); - ipX_addr_copy(ip_current_is_v6(), npcb->remote_ip, *ipX_current_src_addr()); - npcb->bound_to_netif = pcb->bound_to_netif; - npcb->local_port = tcphdr->dest; - memcpy(npcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)); - npcb->remote_port = tcphdr->src; - npcb->state = SYN_RCVD; - npcb->rcv_nxt = seqno + 1; - npcb->rcv_ann_right_edge = npcb->rcv_nxt; - npcb->snd_wnd = tcphdr->wnd; - npcb->snd_wnd_max = tcphdr->wnd; - npcb->ssthresh = npcb->snd_wnd; - npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ - npcb->callback_arg = pcb->callback_arg; -#if LWIP_CALLBACK_API - npcb->accept = pcb->accept; -#endif /* LWIP_CALLBACK_API */ - /* inherit socket options */ - npcb->so_options = pcb->so_options & SOF_INHERITED; - /* Register the new PCB so that we can begin receiving segments - for it. */ - TCP_REG_ACTIVE(npcb); - - /* Parse any options in the SYN. */ - tcp_parseopt(npcb); -#if TCP_CALCULATE_EFF_SEND_MSS - npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, - &npcb->remote_ip, PCB_ISIPV6(npcb)); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - snmp_inc_tcppassiveopens(); - - /* Send a SYN|ACK together with the MSS option. */ - rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); - if (rc != ERR_OK) { - tcp_abandon(npcb, 0); - return rc; - } - return tcp_output(npcb); - } - return ERR_OK; -} - -/** - * Called by tcp_input() when a segment arrives for a connection in - * TIME_WAIT. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_timewait_input(struct tcp_pcb *pcb) -{ - /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ - /* RFC 793 3.9 Event Processing - Segment Arrives: - * - first check sequence number - we skip that one in TIME_WAIT (always - * acceptable since we only send ACKs) - * - second check the RST bit (... return) */ - if (flags & TCP_RST) { - return ERR_OK; - } - /* - fourth, check the SYN bit, */ - if (flags & TCP_SYN) { - /* If an incoming segment is not acceptable, an acknowledgment - should be sent in reply */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { - /* If the SYN is in the window it is an error, send a reset */ - tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); - return ERR_OK; - } - } else if (flags & TCP_FIN) { - /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. - Restart the 2 MSL time-wait timeout.*/ - pcb->tmr = tcp_ticks; - } - - if ((tcplen > 0)) { - /* Acknowledge data, FIN or out-of-window SYN */ - pcb->flags |= TF_ACK_NOW; - return tcp_output(pcb); - } - return ERR_OK; -} - -/** - * Implements the TCP state machine. Called by tcp_input. In some - * states tcp_receive() is called to receive data. The tcp_seg - * argument will be freed by the caller (tcp_input()) unless the - * recv_data pointer in the pcb is set. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_process(struct tcp_pcb *pcb) -{ - struct tcp_seg *rseg; - u8_t acceptable = 0; - err_t err; - - err = ERR_OK; - - /* Process incoming RST segments. */ - if (flags & TCP_RST) { - /* First, determine if the reset is acceptable. */ - if (pcb->state == SYN_SENT) { - if (ackno == pcb->snd_nxt) { - acceptable = 1; - } - } else { - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt+pcb->rcv_wnd)) { - acceptable = 1; - } - } - - if (acceptable) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); - LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); - recv_flags |= TF_RESET; - pcb->flags &= ~TF_ACK_DELAY; - return ERR_RST; - } else { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - return ERR_OK; - } - } - - if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { - /* Cope with new connection attempt after remote end crashed */ - tcp_ack_now(pcb); - return ERR_OK; - } - - if ((pcb->flags & TF_RXCLOSED) == 0) { - /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ - pcb->tmr = tcp_ticks; - } - pcb->keep_cnt_sent = 0; - - tcp_parseopt(pcb); - - /* Do different things depending on the TCP state. */ - switch (pcb->state) { - case SYN_SENT: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, - pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); - /* received SYN ACK with expected sequence number? */ - if ((flags & TCP_ACK) && (flags & TCP_SYN) - && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { - pcb->snd_buf++; - pcb->rcv_nxt = seqno + 1; - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->lastack = ackno; - pcb->snd_wnd = tcphdr->wnd; - pcb->snd_wnd_max = tcphdr->wnd; - pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ - pcb->state = ESTABLISHED; - -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, - PCB_ISIPV6(pcb)); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - /* Set ssthresh again after changing pcb->mss (already set in tcp_connect - * but for the default value of pcb->mss) */ - pcb->ssthresh = pcb->mss * 10; - - pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); - LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); - --pcb->snd_queuelen; - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - rseg = pcb->unacked; - pcb->unacked = rseg->next; - tcp_seg_free(rseg); - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if(pcb->unacked == NULL) - pcb->rtime = -1; - else { - pcb->rtime = 0; - pcb->nrtx = 0; - } - - /* Call the user specified function to call when sucessfully - * connected. */ - TCP_EVENT_CONNECTED(pcb, ERR_OK, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - tcp_ack_now(pcb); - } - /* received ACK? possibly a half-open connection */ - else if (flags & TCP_ACK) { - /* send a RST to bring the other side in a non-synchronized state. */ - tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); - } - break; - case SYN_RCVD: - if (flags & TCP_ACK) { - /* expected ACK number? */ - if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { - u16_t old_cwnd; - pcb->state = ESTABLISHED; - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); -#if LWIP_CALLBACK_API - LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); -#endif - /* Call the accept function. */ - TCP_EVENT_ACCEPT(pcb, ERR_OK, err); - if (err != ERR_OK) { - /* If the accept function returns with an error, we abort - * the connection. */ - /* Already aborted? */ - if (err != ERR_ABRT) { - tcp_abort(pcb); - } - return ERR_ABRT; - } - old_cwnd = pcb->cwnd; - /* If there was any data contained within this ACK, - * we'd better pass it on to the application as well. */ - tcp_receive(pcb); - - /* Prevent ACK for SYN to generate a sent event */ - if (pcb->acked != 0) { - pcb->acked--; - } - - pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); - - if (recv_flags & TF_GOT_FIN) { - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - } else { - /* incorrect ACK number, send RST */ - tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), - ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); - } - } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { - /* Looks like another copy of the SYN - retransmit our SYN-ACK */ - tcp_rexmit(pcb); - } - break; - case CLOSE_WAIT: - /* FALLTHROUGH */ - case ESTABLISHED: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { /* passive close */ - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - break; - case FIN_WAIT_1: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { - LWIP_DEBUGF(TCP_DEBUG, - ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - tcp_ack_now(pcb); - pcb->state = CLOSING; - } - } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { - pcb->state = FIN_WAIT_2; - } - break; - case FIN_WAIT_2: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case CLOSING: - tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case LAST_ACK: - tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ - recv_flags |= TF_CLOSED; - } - break; - default: - break; - } - return ERR_OK; -} - -#if TCP_QUEUE_OOSEQ -/** - * Insert segment into the list (segments covered with new one will be deleted) - * - * Called from tcp_receive() - */ -static void -tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) -{ - struct tcp_seg *old_seg; - - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - /* received segment overlaps all following segments */ - tcp_segs_free(next); - next = NULL; - } - else { - /* delete some following segments - oos queue may have segments with FIN flag */ - while (next && - TCP_SEQ_GEQ((seqno + cseg->len), - (next->tcphdr->seqno + next->len))) { - /* cseg with FIN already processed */ - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); - } - old_seg = next; - next = next->next; - tcp_seg_free(old_seg); - } - if (next && - TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { - /* We need to trim the incoming segment. */ - cseg->len = (u16_t)(next->tcphdr->seqno - seqno); - pbuf_realloc(cseg->p, cseg->len); - } - } - cseg->next = next; -} -#endif /* TCP_QUEUE_OOSEQ */ - -/** - * Called by tcp_process. Checks if the given segment is an ACK for outstanding - * data, and if so frees the memory of the buffered data. Next, is places the - * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment - * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until - * it has been removed from the buffer. - * - * If the incoming segment constitutes an ACK for a segment that was used for RTT - * estimation, the RTT is estimated here as well. - * - * Called from tcp_process(). - */ -static void -tcp_receive(struct tcp_pcb *pcb) -{ - struct tcp_seg *next; -#if TCP_QUEUE_OOSEQ - struct tcp_seg *prev, *cseg; -#endif /* TCP_QUEUE_OOSEQ */ - struct pbuf *p; - s32_t off; - s16_t m; - u32_t right_wnd_edge; - u16_t new_tot_len; - int found_dupack = 0; -#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS - u32_t ooseq_blen; - u16_t ooseq_qlen; -#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ - - LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); - - if (flags & TCP_ACK) { - right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; - - /* Update window. */ - if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || - (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || - (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { - pcb->snd_wnd = tcphdr->wnd; - /* keep track of the biggest window announced by the remote host to calculate - the maximum segment size */ - if (pcb->snd_wnd_max < tcphdr->wnd) { - pcb->snd_wnd_max = tcphdr->wnd; - } - pcb->snd_wl1 = seqno; - pcb->snd_wl2 = ackno; - if (pcb->snd_wnd == 0) { - if (pcb->persist_backoff == 0) { - /* start persist timer */ - pcb->persist_cnt = 0; - pcb->persist_backoff = 1; - } - } else if (pcb->persist_backoff > 0) { - /* stop persist timer */ - pcb->persist_backoff = 0; - } - LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); -#if TCP_WND_DEBUG - } else { - if (pcb->snd_wnd != tcphdr->wnd) { - LWIP_DEBUGF(TCP_WND_DEBUG, - ("tcp_receive: no window update lastack %"U32_F" ackno %" - U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", - pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); - } -#endif /* TCP_WND_DEBUG */ - } - - /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a - * duplicate ack if: - * 1) It doesn't ACK new data - * 2) length of received packet is zero (i.e. no payload) - * 3) the advertised window hasn't changed - * 4) There is outstanding unacknowledged data (retransmission timer running) - * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) - * - * If it passes all five, should process as a dupack: - * a) dupacks < 3: do nothing - * b) dupacks == 3: fast retransmit - * c) dupacks > 3: increase cwnd - * - * If it only passes 1-3, should reset dupack counter (and add to - * stats, which we don't do in lwIP) - * - * If it only passes 1, should reset dupack counter - * - */ - - /* Clause 1 */ - if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { - pcb->acked = 0; - /* Clause 2 */ - if (tcplen == 0) { - /* Clause 3 */ - if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ - /* Clause 4 */ - if (pcb->rtime >= 0) { - /* Clause 5 */ - if (pcb->lastack == ackno) { - found_dupack = 1; - if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { - ++pcb->dupacks; - } - if (pcb->dupacks > 3) { - /* Inflate the congestion window, but not if it means that - the value overflows. */ - if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - } else if (pcb->dupacks == 3) { - /* Do fast retransmit */ - tcp_rexmit_fast(pcb); - } - } - } - } - } - /* If Clause (1) or more is true, but not a duplicate ack, reset - * count of consecutive duplicate acks */ - if (!found_dupack) { - pcb->dupacks = 0; - } - } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ - /* We come here when the ACK acknowledges new data. */ - - /* Reset the "IN Fast Retransmit" flag, since we are no longer - in fast retransmit. Also reset the congestion window to the - slow start threshold. */ - if (pcb->flags & TF_INFR) { - pcb->flags &= ~TF_INFR; - pcb->cwnd = pcb->ssthresh; - } - - /* Reset the number of retransmissions. */ - pcb->nrtx = 0; - - /* Reset the retransmission time-out. */ - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - /* Update the send buffer space. Diff between the two can never exceed 64K? */ - pcb->acked = (u16_t)(ackno - pcb->lastack); - - pcb->snd_buf += pcb->acked; - - /* Reset the fast retransmit variables. */ - pcb->dupacks = 0; - pcb->lastack = ackno; - - /* Update the congestion control variables (cwnd and - ssthresh). */ - if (pcb->state >= ESTABLISHED) { - if (pcb->cwnd < pcb->ssthresh) { - if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); - } else { - u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); - if (new_cwnd > pcb->cwnd) { - pcb->cwnd = new_cwnd; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); - } - } - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", - ackno, - pcb->unacked != NULL? - ntohl(pcb->unacked->tcphdr->seqno): 0, - pcb->unacked != NULL? - ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); - - /* Remove segment from the unacknowledged list if the incoming - ACK acknowlegdes them. */ - while (pcb->unacked != NULL && - TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked), ackno)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", - ntohl(pcb->unacked->tcphdr->seqno), - ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked))); - - next = pcb->unacked; - pcb->unacked = pcb->unacked->next; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - /* Prevent ACK for FIN to generate a sent event */ - if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { - pcb->acked--; - } - - pcb->snd_queuelen -= pbuf_clen(next->p); - tcp_seg_free(next); - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - } - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if(pcb->unacked == NULL) - pcb->rtime = -1; - else - pcb->rtime = 0; - - pcb->polltmr = 0; - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (PCB_ISIPV6(pcb)) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - } else { - /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ - pcb->acked = 0; - } - - /* We go through the ->unsent list to see if any of the segments - on the list are acknowledged by the ACK. This may seem - strange since an "unsent" segment shouldn't be acked. The - rationale is that lwIP puts all outstanding segments on the - ->unsent list after a retransmission, so these segments may - in fact have been sent once. */ - while (pcb->unsent != NULL && - TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", - ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent))); - - next = pcb->unsent; - pcb->unsent = pcb->unsent->next; -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - /* Prevent ACK for FIN to generate a sent event */ - if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { - pcb->acked--; - } - pcb->snd_queuelen -= pbuf_clen(next->p); - tcp_seg_free(next); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - } - /* End of ACK for new data processing. */ - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", - pcb->rttest, pcb->rtseq, ackno)); - - /* RTT estimation calculations. This is done by checking if the - incoming segment acknowledges the segment we use to take a - round-trip time measurement. */ - if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { - /* diff between this shouldn't exceed 32K since this are tcp timer ticks - and a round-trip shouldn't be that long... */ - m = (s16_t)(tcp_ticks - pcb->rttest); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", - m, m * TCP_SLOW_INTERVAL)); - - /* This is taken directly from VJs original code in his paper */ - m = m - (pcb->sa >> 3); - pcb->sa += m; - if (m < 0) { - m = -m; - } - m = m - (pcb->sv >> 2); - pcb->sv += m; - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", - pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); - - pcb->rttest = 0; - } - } - - /* If the incoming segment contains data, we must process it - further unless the pcb already received a FIN. - (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, - LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ - if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { - /* This code basically does three things: - - +) If the incoming segment contains data that is the next - in-sequence data, this data is passed to the application. This - might involve trimming the first edge of the data. The rcv_nxt - variable and the advertised window are adjusted. - - +) If the incoming segment has data that is above the next - sequence number expected (->rcv_nxt), the segment is placed on - the ->ooseq queue. This is done by finding the appropriate - place in the ->ooseq queue (which is ordered by sequence - number) and trim the segment in both ends if needed. An - immediate ACK is sent to indicate that we received an - out-of-sequence segment. - - +) Finally, we check if the first segment on the ->ooseq queue - now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If - rcv_nxt > ooseq->seqno, we must trim the first edge of the - segment on ->ooseq before we adjust rcv_nxt. The data in the - segments that are now on sequence are chained onto the - incoming segment so that we only need to call the application - once. - */ - - /* First, we check if we must trim the first edge. We have to do - this if the sequence number of the incoming segment is less - than rcv_nxt, and the sequence number plus the length of the - segment is larger than rcv_nxt. */ - /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ - if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ - if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ - /* Trimming the first edge is done by pushing the payload - pointer in the pbuf downwards. This is somewhat tricky since - we do not want to discard the full contents of the pbuf up to - the new starting point of the data since we have to keep the - TCP header which is present in the first pbuf in the chain. - - What is done is really quite a nasty hack: the first pbuf in - the pbuf chain is pointed to by inseg.p. Since we need to be - able to deallocate the whole pbuf, we cannot change this - inseg.p pointer to point to any of the later pbufs in the - chain. Instead, we point the ->payload pointer in the first - pbuf to data in one of the later pbufs. We also set the - inseg.data pointer to point to the right place. This way, the - ->p pointer will still point to the first pbuf, but the - ->p->payload pointer will point to data in another pbuf. - - After we are done with adjusting the pbuf pointers we must - adjust the ->data pointer in the seg and the segment - length.*/ - - off = pcb->rcv_nxt - seqno; - p = inseg.p; - LWIP_ASSERT("inseg.p != NULL", inseg.p); - LWIP_ASSERT("insane offset!", (off < 0x7fff)); - if (inseg.p->len < off) { - LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); - new_tot_len = (u16_t)(inseg.p->tot_len - off); - while (p->len < off) { - off -= p->len; - /* KJM following line changed (with addition of new_tot_len var) - to fix bug #9076 - inseg.p->tot_len -= p->len; */ - p->tot_len = new_tot_len; - p->len = 0; - p = p->next; - } - if(pbuf_header(p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } else { - if(pbuf_header(inseg.p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } - inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); - inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; - } - else { - if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ - /* the whole segment is < rcv_nxt */ - /* must be a duplicate of a packet that has already been correctly handled */ - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); - tcp_ack_now(pcb); - } - } - - /* The sequence number must be within the window (above rcv_nxt - and below rcv_nxt + rcv_wnd) in order to be further - processed. */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd - 1)){ - if (pcb->rcv_nxt == seqno) { - /* The incoming segment is the next in sequence. We check if - we have to trim the end of the segment and update rcv_nxt - and pass the data to the application. */ - tcplen = TCP_TCPLEN(&inseg); - - if (tcplen > pcb->rcv_wnd) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - inseg.len = pcb->rcv_wnd; - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } -#if TCP_QUEUE_OOSEQ - /* Received in-sequence data, adjust ooseq data if: - - FIN has been received or - - inseq overlaps with ooseq */ - if (pcb->ooseq != NULL) { - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: received in-order FIN, binning ooseq queue\n")); - /* Received in-order FIN means anything that was received - * out of order must now have been received in-order, so - * bin the ooseq queue */ - while (pcb->ooseq != NULL) { - struct tcp_seg *old_ooseq = pcb->ooseq; - pcb->ooseq = pcb->ooseq->next; - tcp_seg_free(old_ooseq); - } - } else { - next = pcb->ooseq; - /* Remove all segments on ooseq that are covered by inseg already. - * FIN is copied from ooseq to inseg if present. */ - while (next && - TCP_SEQ_GEQ(seqno + tcplen, - next->tcphdr->seqno + next->len)) { - /* inseg cannot have FIN here (already processed above) */ - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && - (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { - TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); - tcplen = TCP_TCPLEN(&inseg); - } - prev = next; - next = next->next; - tcp_seg_free(prev); - } - /* Now trim right side of inseg if it overlaps with the first - * segment on ooseq */ - if (next && - TCP_SEQ_GT(seqno + tcplen, - next->tcphdr->seqno)) { - /* inseg cannot have FIN here (already processed above) */ - inseg.len = (u16_t)(next->tcphdr->seqno - seqno); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", - (seqno + tcplen) == next->tcphdr->seqno); - } - pcb->ooseq = next; - } - } -#endif /* TCP_QUEUE_OOSEQ */ - - pcb->rcv_nxt = seqno + tcplen; - - /* Update the receiver's (our) window. */ - LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); - pcb->rcv_wnd -= tcplen; - - tcp_update_rcv_ann_wnd(pcb); - - /* If there is data in the segment, we make preparations to - pass this up to the application. The ->recv_data variable - is used for holding the pbuf that goes to the - application. The code for reassembling out-of-sequence data - chains its data on this pbuf as well. - - If the segment was a FIN, we set the TF_GOT_FIN flag that will - be used to indicate to the application that the remote side has - closed its end of the connection. */ - if (inseg.p->tot_len > 0) { - recv_data = inseg.p; - /* Since this pbuf now is the responsibility of the - application, we delete our reference to it so that we won't - (mistakingly) deallocate it. */ - inseg.p = NULL; - } - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); - recv_flags |= TF_GOT_FIN; - } - -#if TCP_QUEUE_OOSEQ - /* We now check if we have segments on the ->ooseq queue that - are now in sequence. */ - while (pcb->ooseq != NULL && - pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { - - cseg = pcb->ooseq; - seqno = pcb->ooseq->tcphdr->seqno; - - pcb->rcv_nxt += TCP_TCPLEN(cseg); - LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", - pcb->rcv_wnd >= TCP_TCPLEN(cseg)); - pcb->rcv_wnd -= TCP_TCPLEN(cseg); - - tcp_update_rcv_ann_wnd(pcb); - - if (cseg->p->tot_len > 0) { - /* Chain this pbuf onto the pbuf that we will pass to - the application. */ - if (recv_data) { - pbuf_cat(recv_data, cseg->p); - } else { - recv_data = cseg->p; - } - cseg->p = NULL; - } - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); - recv_flags |= TF_GOT_FIN; - if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ - pcb->state = CLOSE_WAIT; - } - } - - pcb->ooseq = cseg->next; - tcp_seg_free(cseg); - } -#endif /* TCP_QUEUE_OOSEQ */ - - - /* Acknowledge the segment(s). */ - tcp_ack(pcb); - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (PCB_ISIPV6(pcb)) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - - } else { - /* We get here if the incoming segment is out-of-sequence. */ - tcp_send_empty_ack(pcb); -#if TCP_QUEUE_OOSEQ - /* We queue the segment on the ->ooseq queue. */ - if (pcb->ooseq == NULL) { - pcb->ooseq = tcp_seg_copy(&inseg); - } else { - /* If the queue is not empty, we walk through the queue and - try to find a place where the sequence number of the - incoming segment is between the sequence numbers of the - previous and the next segment on the ->ooseq queue. That is - the place where we put the incoming segment. If needed, we - trim the second edges of the previous and the incoming - segment so that it will fit into the sequence. - - If the incoming segment has the same sequence number as a - segment on the ->ooseq queue, we discard the segment that - contains less data. */ - - prev = NULL; - for(next = pcb->ooseq; next != NULL; next = next->next) { - if (seqno == next->tcphdr->seqno) { - /* The sequence number of the incoming segment is the - same as the sequence number of the segment on - ->ooseq. We check the lengths to see which one to - discard. */ - if (inseg.len > next->len) { - /* The incoming segment is larger than the old - segment. We replace some segments with the new - one. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (prev != NULL) { - prev->next = cseg; - } else { - pcb->ooseq = cseg; - } - tcp_oos_insert_segment(cseg, next); - } - break; - } else { - /* Either the lenghts are the same or the incoming - segment was smaller than the old one; in either - case, we ditch the incoming segment. */ - break; - } - } else { - if (prev == NULL) { - if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { - /* The sequence number of the incoming segment is lower - than the sequence number of the first segment on the - queue. We put the incoming segment first on the - queue. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - pcb->ooseq = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } else { - /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && - TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ - if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { - /* The sequence number of the incoming segment is in - between the sequence numbers of the previous and - the next segment on ->ooseq. We trim trim the previous - segment, delete next segments that included in received segment - and trim received, if needed. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { - /* We need to trim the prev segment. */ - prev->len = (u16_t)(seqno - prev->tcphdr->seqno); - pbuf_realloc(prev->p, prev->len); - } - prev->next = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } - /* If the "next" segment is the last segment on the - ooseq queue, we add the incoming segment to the end - of the list. */ - if (next->next == NULL && - TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - /* segment "next" already contains all data */ - break; - } - next->next = tcp_seg_copy(&inseg); - if (next->next != NULL) { - if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { - /* We need to trim the last segment. */ - next->len = (u16_t)(seqno - next->tcphdr->seqno); - pbuf_realloc(next->p, next->len); - } - /* check if the remote side overruns our receive window */ - if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; - pbuf_realloc(next->next->p, next->next->len); - tcplen = TCP_TCPLEN(next->next); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } - } - break; - } - } - prev = next; - } - } -#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS - /* Check that the data on ooseq doesn't exceed one of the limits - and throw away everything above that limit. */ - ooseq_blen = 0; - ooseq_qlen = 0; - prev = NULL; - for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) { - struct pbuf *p = next->p; - ooseq_blen += p->tot_len; - ooseq_qlen += pbuf_clen(p); - if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || - (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { - /* too much ooseq data, dump this and everything after it */ - tcp_segs_free(next); - if (prev == NULL) { - /* first ooseq segment is too much, dump the whole queue */ - pcb->ooseq = NULL; - } else { - /* just dump 'next' and everything after it */ - prev->next = NULL; - } - break; - } - } -#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ -#endif /* TCP_QUEUE_OOSEQ */ - } - } else { - /* The incoming segment is not withing the window. */ - tcp_send_empty_ack(pcb); - } - } else { - /* Segments with length 0 is taken care of here. Segments that - fall out of the window are ACKed. */ - /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || - TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ - if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ - tcp_ack_now(pcb); - } - } -} - -/** - * Parses the options contained in the incoming segment. - * - * Called from tcp_listen_input() and tcp_process(). - * Currently, only the MSS option is supported! - * - * @param pcb the tcp_pcb for which a segment arrived - */ -static void -tcp_parseopt(struct tcp_pcb *pcb) -{ - u16_t c, max_c; - u16_t mss; - u8_t *opts, opt; -#if LWIP_TCP_TIMESTAMPS - u32_t tsval; -#endif - - opts = (u8_t *)tcphdr + TCP_HLEN; - - /* Parse the TCP MSS option, if present. */ - if(TCPH_HDRLEN(tcphdr) > 0x5) { - max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; - for (c = 0; c < max_c; ) { - opt = opts[c]; - switch (opt) { - case 0x00: - /* End of options. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); - return; - case 0x01: - /* NOP option. */ - ++c; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); - break; - case 0x02: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); - if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An MSS option with the right option length. */ - mss = (opts[c + 2] << 8) | opts[c + 3]; - /* Limit the mss to the configured TCP_MSS and prevent division by zero */ - pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; - /* Advance to next option */ - c += 0x04; - break; -#if LWIP_TCP_TIMESTAMPS - case 0x08: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); - if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* TCP timestamp option with valid length */ - tsval = (opts[c+2]) | (opts[c+3] << 8) | - (opts[c+4] << 16) | (opts[c+5] << 24); - if (flags & TCP_SYN) { - pcb->ts_recent = ntohl(tsval); - pcb->flags |= TF_TIMESTAMP; - } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { - pcb->ts_recent = ntohl(tsval); - } - /* Advance to next option */ - c += 0x0A; - break; -#endif - default: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); - if (opts[c + 1] == 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - /* If the length field is zero, the options are malformed - and we don't process them further. */ - return; - } - /* All other options have a length field, so that we easily - can skip past them. */ - c += opts[c + 1]; - } - } - } -} - -#endif /* LWIP_TCP */ diff --git a/external/badvpn_dns/lwip/src/core/tcp_out.c b/external/badvpn_dns/lwip/src/core/tcp_out.c deleted file mode 100644 index b9fc339..0000000 --- a/external/badvpn_dns/lwip/src/core/tcp_out.c +++ /dev/null @@ -1,1499 +0,0 @@ -/** - * @file - * Transmission Control Protocol, outgoing traffic - * - * The output functions of TCP. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp_impl.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#if LWIP_TCP_TIMESTAMPS -#include "lwip/sys.h" -#endif - -#include <string.h> - -/* Define some copy-macros for checksum-on-copy so that the code looks - nicer by preventing too many ifdef's. */ -#if TCP_CHECKSUM_ON_COPY -#define TCP_DATA_COPY(dst, src, len, seg) do { \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ - len, &seg->chksum, &seg->chksum_swapped); \ - seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); -#else /* TCP_CHECKSUM_ON_COPY*/ -#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) -#endif /* TCP_CHECKSUM_ON_COPY*/ - -/** Define this to 1 for an extra check that the output checksum is valid - * (usefule when the checksum is generated by the application, not the stack) */ -#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK -#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 -#endif - -/* Forward declarations.*/ -static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); - -/** Allocate a pbuf and create a tcphdr at p->payload, used for output - * functions other than the default tcp_output -> tcp_output_segment - * (e.g. tcp_send_empty_ack, etc.) - * - * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) - * @param optlen length of header-options - * @param datalen length of tcp data to reserve in pbuf - * @param seqno_be seqno in network byte order (big-endian) - * @return pbuf with p->payload being the tcp_hdr - */ -static struct pbuf * -tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, - u32_t seqno_be /* already in network byte order */) -{ - struct tcp_hdr *tcphdr; - struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); - if (p != NULL) { - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= TCP_HLEN + optlen)); - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = htons(pcb->local_port); - tcphdr->dest = htons(pcb->remote_port); - tcphdr->seqno = seqno_be; - tcphdr->ackno = htonl(pcb->rcv_nxt); - TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); - tcphdr->wnd = htons(pcb->rcv_ann_wnd); - tcphdr->chksum = 0; - tcphdr->urgp = 0; - - /* If we're sending a packet, update the announced right window edge */ - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - } - return p; -} - -/** - * Called by tcp_close() to send a segment including FIN flag but not data. - * - * @param pcb the tcp_pcb over which to send a segment - * @return ERR_OK if sent, another err_t otherwise - */ -err_t -tcp_send_fin(struct tcp_pcb *pcb) -{ - /* first, try to add the fin to the last unsent segment */ - if (pcb->unsent != NULL) { - struct tcp_seg *last_unsent; - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { - /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ - TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); - pcb->flags |= TF_FIN; - return ERR_OK; - } - } - /* no data, no length, flags, copy=1, no optdata */ - return tcp_enqueue_flags(pcb, TCP_FIN); -} - -/** - * Create a TCP segment with prefilled header. - * - * Called by tcp_write and tcp_enqueue_flags. - * - * @param pcb Protocol control block for the TCP connection. - * @param p pbuf that is used to hold the TCP header. - * @param flags TCP flags for header. - * @param seqno TCP sequence number of this packet - * @param optflags options to include in TCP header - * @return a new tcp_seg pointing to p, or NULL. - * The TCP header is filled in except ackno and wnd. - * p is freed on failure. - */ -static struct tcp_seg * -tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) -{ - struct tcp_seg *seg; - u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); - - if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); - pbuf_free(p); - return NULL; - } - seg->flags = optflags; - seg->next = NULL; - seg->p = p; - seg->len = p->tot_len - optlen; -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = 0; - seg->chksum_swapped = 0; - /* check optflags */ - LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", - (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* build TCP header */ - if (pbuf_header(p, TCP_HLEN)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); - TCP_STATS_INC(tcp.err); - tcp_seg_free(seg); - return NULL; - } - seg->tcphdr = (struct tcp_hdr *)seg->p->payload; - seg->tcphdr->src = htons(pcb->local_port); - seg->tcphdr->dest = htons(pcb->remote_port); - seg->tcphdr->seqno = htonl(seqno); - /* ackno is set in tcp_output */ - TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); - /* wnd and chksum are set in tcp_output */ - seg->tcphdr->urgp = 0; - return seg; -} - -/** - * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. - * - * This function is like pbuf_alloc(layer, length, PBUF_RAM) except - * there may be extra bytes available at the end. - * - * @param layer flag to define header size. - * @param length size of the pbuf's payload. - * @param max_length maximum usable size of payload+oversize. - * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. - * @param pcb The TCP connection that willo enqueue the pbuf. - * @param apiflags API flags given to tcp_write. - * @param first_seg true when this pbuf will be used in the first enqueued segment. - * @param - */ -#if TCP_OVERSIZE -static struct pbuf * -tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, - u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, - u8_t first_seg) -{ - struct pbuf *p; - u16_t alloc = length; - -#if LWIP_NETIF_TX_SINGLE_PBUF - LWIP_UNUSED_ARG(max_length); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(apiflags); - LWIP_UNUSED_ARG(first_seg); - /* always create MSS-sized pbufs */ - alloc = max_length; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (length < max_length) { - /* Should we allocate an oversized pbuf, or just the minimum - * length required? If tcp_write is going to be called again - * before this segment is transmitted, we want the oversized - * buffer. If the segment will be transmitted immediately, we can - * save memory by allocating only length. We use a simple - * heuristic based on the following information: - * - * Did the user set TCP_WRITE_FLAG_MORE? - * - * Will the Nagle algorithm defer transmission of this segment? - */ - if ((apiflags & TCP_WRITE_FLAG_MORE) || - (!(pcb->flags & TF_NODELAY) && - (!first_seg || - pcb->unsent != NULL || - pcb->unacked != NULL))) { - alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE)); - } - } -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - p = pbuf_alloc(layer, alloc, PBUF_RAM); - if (p == NULL) { - return NULL; - } - LWIP_ASSERT("need unchained pbuf", p->next == NULL); - *oversize = p->len - length; - /* trim p->len to the currently used size */ - p->len = p->tot_len = length; - return p; -} -#else /* TCP_OVERSIZE */ -#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) -#endif /* TCP_OVERSIZE */ - -#if TCP_CHECKSUM_ON_COPY -/** Add a checksum of newly added data to the segment */ -static void -tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, - u8_t *seg_chksum_swapped) -{ - u32_t helper; - /* add chksum to old chksum and fold to u16_t */ - helper = chksum + *seg_chksum; - chksum = FOLD_U32T(helper); - if ((len & 1) != 0) { - *seg_chksum_swapped = 1 - *seg_chksum_swapped; - chksum = SWAP_BYTES_IN_WORD(chksum); - } - *seg_chksum = chksum; -} -#endif /* TCP_CHECKSUM_ON_COPY */ - -/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). - * - * @param pcb the tcp pcb to check for - * @param len length of data to send (checked agains snd_buf) - * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise - */ -static err_t -tcp_write_checks(struct tcp_pcb *pcb, u16_t len) -{ - /* connection is in invalid state for data transmission? */ - if ((pcb->state != ESTABLISHED) && - (pcb->state != CLOSE_WAIT) && - (pcb->state != SYN_SENT) && - (pcb->state != SYN_RCVD)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); - return ERR_CONN; - } else if (len == 0) { - return ERR_OK; - } - - /* fail on too much data */ - if (len > pcb->snd_buf) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", - len, pcb->snd_buf)); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - - /* If total number of pbufs on the unsent/unacked queues exceeds the - * configured maximum, return an error */ - /* check for configured max queuelen and possible overflow */ - if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, TCP_SND_QUEUELEN)); - TCP_STATS_INC(tcp.memerr); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", - pcb->unacked != NULL || pcb->unsent != NULL); - } else { - LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", - pcb->unacked == NULL && pcb->unsent == NULL); - } - return ERR_OK; -} - -/** - * Write data for sending (but does not send it immediately). - * - * It waits in the expectation of more data being sent soon (as - * it can send them more efficiently by combining them together). - * To prompt the system to send data now, call tcp_output() after - * calling tcp_write(). - * - * @param pcb Protocol control block for the TCP connection to enqueue data for. - * @param arg Pointer to the data to be enqueued for sending. - * @param len Data length in bytes - * @param apiflags combination of following flags : - * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack - * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, - * @return ERR_OK if enqueued, another err_t on error - */ -err_t -tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) -{ - struct pbuf *concat_p = NULL; - struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; - u16_t pos = 0; /* position in 'arg' data */ - u16_t queuelen; - u8_t optlen = 0; - u8_t optflags = 0; -#if TCP_OVERSIZE - u16_t oversize = 0; - u16_t oversize_used = 0; -#endif /* TCP_OVERSIZE */ -#if TCP_CHECKSUM_ON_COPY - u16_t concat_chksum = 0; - u8_t concat_chksum_swapped = 0; - u16_t concat_chksummed = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - err_t err; - /* don't allocate segments bigger than half the maximum window we ever received */ - u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2); - -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Always copy to try to create single pbufs for TX */ - apiflags |= TCP_WRITE_FLAG_COPY; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", - (void *)pcb, arg, len, (u16_t)apiflags)); - LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", - arg != NULL, return ERR_ARG;); - - err = tcp_write_checks(pcb, len); - if (err != ERR_OK) { - return err; - } - queuelen = pcb->snd_queuelen; - -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { - optflags = TF_SEG_OPTS_TS; - optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); - } -#endif /* LWIP_TCP_TIMESTAMPS */ - - - /* - * TCP segmentation is done in three phases with increasing complexity: - * - * 1. Copy data directly into an oversized pbuf. - * 2. Chain a new pbuf to the end of pcb->unsent. - * 3. Create new segments. - * - * We may run out of memory at any point. In that case we must - * return ERR_MEM and not change anything in pcb. Therefore, all - * changes are recorded in local variables and committed at the end - * of the function. Some pcb fields are maintained in local copies: - * - * queuelen = pcb->snd_queuelen - * oversize = pcb->unsent_oversize - * - * These variables are set consistently by the phases: - * - * seg points to the last segment tampered with. - * - * pos records progress as data is segmented. - */ - - /* Find the tail of the unsent queue. */ - if (pcb->unsent != NULL) { - u16_t space; - u16_t unsent_optlen; - - /* @todo: this could be sped up by keeping last_unsent in the pcb */ - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - /* Usable space at the end of the last unsent segment */ - unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); - space = mss_local - (last_unsent->len + unsent_optlen); - - /* - * Phase 1: Copy data directly into an oversized pbuf. - * - * The number of bytes copied is recorded in the oversize_used - * variable. The actual copying is done at the bottom of the - * function. - */ -#if TCP_OVERSIZE -#if TCP_OVERSIZE_DBGCHECK - /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */ - LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", - pcb->unsent_oversize == last_unsent->oversize_left); -#endif /* TCP_OVERSIZE_DBGCHECK */ - oversize = pcb->unsent_oversize; - if (oversize > 0) { - LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space); - seg = last_unsent; - oversize_used = oversize < len ? oversize : len; - pos += oversize_used; - oversize -= oversize_used; - space -= oversize_used; - } - /* now we are either finished or oversize is zero */ - LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len)); -#endif /* TCP_OVERSIZE */ - - /* - * Phase 2: Chain a new pbuf to the end of pcb->unsent. - * - * We don't extend segments containing SYN/FIN flags or options - * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at - * the end. - */ - if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { - u16_t seglen = space < len - pos ? space : len - pos; - seg = last_unsent; - - /* Create a pbuf with a copy or reference to seglen bytes. We - * can use PBUF_RAW here since the data appears in the middle of - * a segment. A header will never be prepended. */ - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* Data is copied */ - if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, - ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", - seglen)); - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - last_unsent->oversize_left += oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ - TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); -#if TCP_CHECKSUM_ON_COPY - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - } else { - /* Data is not copied */ - if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, - ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen, - &concat_chksum, &concat_chksum_swapped); - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - /* reference the non-volatile payload data */ - concat_p->payload = (u8_t*)arg + pos; - } - - pos += seglen; - queuelen += pbuf_clen(concat_p); - } - } else { -#if TCP_OVERSIZE - LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", - pcb->unsent_oversize == 0); -#endif /* TCP_OVERSIZE */ - } - - /* - * Phase 3: Create new segments. - * - * The new segments are chained together in the local 'queue' - * variable, ready to be appended to pcb->unsent. - */ - while (pos < len) { - struct pbuf *p; - u16_t left = len - pos; - u16_t max_len = mss_local - optlen; - u16_t seglen = left > max_len ? max_len : left; -#if TCP_CHECKSUM_ON_COPY - u16_t chksum = 0; - u8_t chksum_swapped = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* If copy is set, memory should be allocated and data copied - * into pbuf */ - if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); - goto memerr; - } - LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", - (p->len >= seglen)); - TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped); - } else { - /* Copy is not set: First allocate a pbuf for holding the data. - * Since the referenced data is available at least until it is - * sent out on the link (as it has to be ACKed by the remote - * party) we can safely use PBUF_ROM instead of PBUF_REF here. - */ - struct pbuf *p2; -#if TCP_OVERSIZE - LWIP_ASSERT("oversize == 0", oversize == 0); -#endif /* TCP_OVERSIZE */ - if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - chksum = ~inet_chksum((u8_t*)arg + pos, seglen); -#endif /* TCP_CHECKSUM_ON_COPY */ - /* reference the non-volatile payload data */ - p2->payload = (u8_t*)arg + pos; - - /* Second, allocate a pbuf for the headers. */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - /* If allocation fails, we have to deallocate the data pbuf as - * well. */ - pbuf_free(p2); - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n")); - goto memerr; - } - /* Concatenate the headers and data pbufs together. */ - pbuf_cat(p/*header*/, p2/*data*/); - } - - queuelen += pbuf_clen(p); - - /* Now that there are more segments queued, we check again if the - * length of the queue exceeds the configured maximum or - * overflows. */ - if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN)); - pbuf_free(p); - goto memerr; - } - - if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = chksum; - seg->chksum_swapped = chksum_swapped; - seg->flags |= TF_SEG_DATA_CHECKSUMMED; -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* first segment of to-be-queued data? */ - if (queue == NULL) { - queue = seg; - } else { - /* Attach the segment to the end of the queued segments */ - LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); - prev_seg->next = seg; - } - /* remember last segment of to-be-queued data for next iteration */ - prev_seg = seg; - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", - ntohl(seg->tcphdr->seqno), - ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); - - pos += seglen; - } - - /* - * All three segmentation phases were successful. We can commit the - * transaction. - */ - - /* - * Phase 1: If data has been added to the preallocated tail of - * last_unsent, we update the length fields of the pbuf chain. - */ -#if TCP_OVERSIZE - if (oversize_used > 0) { - struct pbuf *p; - /* Bump tot_len of whole chain, len of tail */ - for (p = last_unsent->p; p; p = p->next) { - p->tot_len += oversize_used; - if (p->next == NULL) { - TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); - p->len += oversize_used; - } - } - last_unsent->len += oversize_used; -#if TCP_OVERSIZE_DBGCHECK - LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", - last_unsent->oversize_left >= oversize_used); - last_unsent->oversize_left -= oversize_used; -#endif /* TCP_OVERSIZE_DBGCHECK */ - } - pcb->unsent_oversize = oversize; -#endif /* TCP_OVERSIZE */ - - /* - * Phase 2: concat_p can be concatenated onto last_unsent->p - */ - if (concat_p != NULL) { - LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", - (last_unsent != NULL)); - pbuf_cat(last_unsent->p, concat_p); - last_unsent->len += concat_p->tot_len; -#if TCP_CHECKSUM_ON_COPY - if (concat_chksummed) { - tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, - &last_unsent->chksum_swapped); - last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; - } -#endif /* TCP_CHECKSUM_ON_COPY */ - } - - /* - * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that - * is harmless - */ - if (last_unsent == NULL) { - pcb->unsent = queue; - } else { - last_unsent->next = queue; - } - - /* - * Finally update the pcb state. - */ - pcb->snd_lbb += len; - pcb->snd_buf -= len; - pcb->snd_queuelen = queuelen; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", - pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - /* Set the PSH flag in the last segment that we enqueued. */ - if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { - TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); - } - - return ERR_OK; -memerr: - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - - if (concat_p != NULL) { - pbuf_free(concat_p); - } - if (queue != NULL) { - tcp_segs_free(queue); - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); - return ERR_MEM; -} - -/** - * Enqueue TCP options for transmission. - * - * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl(). - * - * @param pcb Protocol control block for the TCP connection. - * @param flags TCP header flags to set in the outgoing segment. - * @param optdata pointer to TCP options, or NULL. - * @param optlen length of TCP options in bytes. - */ -err_t -tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) -{ - struct pbuf *p; - struct tcp_seg *seg; - u8_t optflags = 0; - u8_t optlen = 0; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - - LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", - (flags & (TCP_SYN | TCP_FIN)) != 0); - - /* check for configured max queuelen and possible overflow */ - if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, TCP_SND_QUEUELEN)); - TCP_STATS_INC(tcp.memerr); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - - if (flags & TCP_SYN) { - optflags = TF_SEG_OPTS_MSS; - } -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { - optflags |= TF_SEG_OPTS_TS; - } -#endif /* LWIP_TCP_TIMESTAMPS */ - optlen = LWIP_TCP_OPT_LENGTH(optflags); - - /* tcp_enqueue_flags is always called with either SYN or FIN in flags. - * We need one available snd_buf byte to do that. - * This means we can't send FIN while snd_buf==0. A better fix would be to - * not include SYN and FIN sequence numbers in the snd_buf count. */ - if (pcb->snd_buf == 0) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - - /* Allocate pbuf with room for TCP header + options */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", - (p->len >= optlen)); - - /* Allocate memory for tcp_seg, and fill in fields. */ - if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0); - LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, - ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", - ntohl(seg->tcphdr->seqno), - ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), - (u16_t)flags)); - - /* Now append seg to pcb->unsent queue */ - if (pcb->unsent == NULL) { - pcb->unsent = seg; - } else { - struct tcp_seg *useg; - for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); - useg->next = seg; - } -#if TCP_OVERSIZE - /* The new unsent tail has no space */ - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - - /* SYN and FIN bump the sequence number */ - if ((flags & TCP_SYN) || (flags & TCP_FIN)) { - pcb->snd_lbb++; - /* optlen does not influence snd_buf */ - pcb->snd_buf--; - } - if (flags & TCP_FIN) { - pcb->flags |= TF_FIN; - } - - /* update number of segments on the queues */ - pcb->snd_queuelen += pbuf_clen(seg->p); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - return ERR_OK; -} - -#if LWIP_TCP_TIMESTAMPS -/* Build a timestamp option (12 bytes long) at the specified options pointer) - * - * @param pcb tcp_pcb - * @param opts option pointer where to store the timestamp option - */ -static void -tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) -{ - /* Pad with two NOP options to make everything nicely aligned */ - opts[0] = PP_HTONL(0x0101080A); - opts[1] = htonl(sys_now()); - opts[2] = htonl(pcb->ts_recent); -} -#endif - -/** Send an ACK without data. - * - * @param pcb Protocol control block for the TCP connection to send the ACK - */ -err_t -tcp_send_empty_ack(struct tcp_pcb *pcb) -{ - struct pbuf *p; - u8_t optlen = 0; -#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP - struct tcp_hdr *tcphdr; -#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ - -#if LWIP_TCP_TIMESTAMPS - if (pcb->flags & TF_TIMESTAMP) { - optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); - } -#endif - - p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); - if (p == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); - return ERR_BUF; - } -#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP - tcphdr = (struct tcp_hdr *)p->payload; -#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, - ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); - /* remove ACK flags from the PCB, as we send an empty ACK now */ - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - - /* NB. MSS option is only sent on SYNs, so ignore it here */ -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; - - if (pcb->flags & TF_TIMESTAMP) { - tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); - } -#endif - -#if CHECKSUM_GEN_TCP - tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); -#endif -#if LWIP_NETIF_HWADDRHINT - ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, - IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, - IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - pbuf_free(p); - - return ERR_OK; -} - -/** - * Find out what we can send and send it - * - * @param pcb Protocol control block for the TCP connection to send data - * @return ERR_OK if data has been sent or nothing to send - * another err_t on error - */ -err_t -tcp_output(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg, *useg; - u32_t wnd, snd_nxt; -#if TCP_CWND_DEBUG - s16_t i = 0; -#endif /* TCP_CWND_DEBUG */ - - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_output for listen-pcbs", - pcb->state != LISTEN); - - /* First, check if we are invoked by the TCP input processing - code. If so, we do not output anything. Instead, we rely on the - input processing code to call us when input processing is done - with. */ - if (tcp_input_pcb == pcb) { - return ERR_OK; - } - - wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); - - seg = pcb->unsent; - - /* If the TF_ACK_NOW flag is set and no data will be sent (either - * because the ->unsent queue is empty or because the window does - * not allow it), construct an empty ACK segment and send it. - * - * If data is to be sent, we will just piggyback the ACK (see below). - */ - if (pcb->flags & TF_ACK_NOW && - (seg == NULL || - ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { - return tcp_send_empty_ack(pcb); - } - - /* useg should point to last segment on unacked queue */ - useg = pcb->unacked; - if (useg != NULL) { - for (; useg->next != NULL; useg = useg->next); - } - -#if TCP_OUTPUT_DEBUG - if (seg == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", - (void*)pcb->unsent)); - } -#endif /* TCP_OUTPUT_DEBUG */ -#if TCP_CWND_DEBUG - if (seg == NULL) { - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F - ", cwnd %"U16_F", wnd %"U32_F - ", seg == NULL, ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); - } else { - LWIP_DEBUGF(TCP_CWND_DEBUG, - ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F - ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, - ntohl(seg->tcphdr->seqno), pcb->lastack)); - } -#endif /* TCP_CWND_DEBUG */ - /* data available and window allows it to be sent? */ - while (seg != NULL && - ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { - LWIP_ASSERT("RST not expected here!", - (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); - /* Stop sending if the nagle algorithm would prevent it - * Don't stop: - * - if tcp_write had a memory error before (prevent delayed ACK timeout) or - * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - - * either seg->next != NULL or pcb->unacked == NULL; - * RST is no sent using tcp_write/tcp_output. - */ - if((tcp_do_output_nagle(pcb) == 0) && - ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ - break; - } -#if TCP_CWND_DEBUG - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - ntohl(seg->tcphdr->seqno) + seg->len - - pcb->lastack, - ntohl(seg->tcphdr->seqno), pcb->lastack, i)); - ++i; -#endif /* TCP_CWND_DEBUG */ - - pcb->unsent = seg->next; - - if (pcb->state != SYN_SENT) { - TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } - -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ - tcp_output_segment(seg, pcb); - snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); - if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { - pcb->snd_nxt = snd_nxt; - } - /* put segment on unacknowledged list if length > 0 */ - if (TCP_TCPLEN(seg) > 0) { - seg->next = NULL; - /* unacked list is empty? */ - if (pcb->unacked == NULL) { - pcb->unacked = seg; - useg = seg; - /* unacked list is not empty? */ - } else { - /* In the case of fast retransmit, the packet should not go to the tail - * of the unacked queue, but rather somewhere before it. We need to check for - * this case. -STJ Jul 27, 2004 */ - if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { - /* add segment to before tail of unacked list, keeping the list sorted */ - struct tcp_seg **cur_seg = &(pcb->unacked); - while (*cur_seg && - TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = (*cur_seg); - (*cur_seg) = seg; - } else { - /* add segment to tail of unacked list */ - useg->next = seg; - useg = useg->next; - } - } - /* do not queue empty segments on the unacked list */ - } else { - tcp_seg_free(seg); - } - seg = pcb->unsent; - } -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - /* last unsent has been removed, reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - pcb->flags &= ~TF_NAGLEMEMERR; - return ERR_OK; -} - -/** - * Called by tcp_output() to actually send a TCP segment over IP. - * - * @param seg the tcp_seg to send - * @param pcb the tcp_pcb for the TCP connection used to send the segment - */ -static void -tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) -{ - u16_t len; - u32_t *opts; - - /** @bug Exclude retransmitted segments from this count. */ - snmp_inc_tcpoutsegs(); - - /* The TCP header has already been constructed, but the ackno and - wnd fields remain. */ - seg->tcphdr->ackno = htonl(pcb->rcv_nxt); - - /* advertise our receive window size in this TCP segment */ - seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); - - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - - /* Add any requested options. NB MSS option is only set on SYN - packets, so ignore it here */ - opts = (u32_t *)(void *)(seg->tcphdr + 1); - if (seg->flags & TF_SEG_OPTS_MSS) { - u16_t mss; -#if TCP_CALCULATE_EFF_SEND_MSS - mss = tcp_eff_send_mss(TCP_MSS, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb)); -#else /* TCP_CALCULATE_EFF_SEND_MSS */ - mss = TCP_MSS; -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - *opts = TCP_BUILD_MSS_OPTION(mss); - opts += 1; - } -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; - - if (seg->flags & TF_SEG_OPTS_TS) { - tcp_build_timestamp_option(pcb, opts); - opts += 3; - } -#endif - - /* Set retransmission timer running if it is not currently enabled - This must be set before checking the route. */ - if (pcb->rtime == -1) { - pcb->rtime = 0; - } - - /* If we don't have a local IP address, we get one by - calling ip_route(). */ - if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { - struct netif *netif; - ipX_addr_t *local_ip; - ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip); - if ((netif == NULL) || (local_ip == NULL)) { - return; - } - ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip); - } - - if (pcb->rttest == 0) { - pcb->rttest = tcp_ticks; - pcb->rtseq = ntohl(seg->tcphdr->seqno); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); - } - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", - htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + - seg->len)); - - len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); - - seg->p->len -= len; - seg->p->tot_len -= len; - - seg->p->payload = seg->tcphdr; - - seg->tcphdr->chksum = 0; -#if TCP_CHECKSUM_ON_COPY - { - u32_t acc; -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - u16_t chksum_slow = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ - if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { - LWIP_ASSERT("data included but not checksummed", - seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4)); - } - - /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ - acc = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, - seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip); - /* add payload checksum */ - if (seg->chksum_swapped) { - seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); - seg->chksum_swapped = 0; - } - acc += (u16_t)~(seg->chksum); - seg->tcphdr->chksum = FOLD_U32T(acc); -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - if (chksum_slow != seg->tcphdr->chksum) { - LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", - seg->tcphdr->chksum, chksum_slow)); - seg->tcphdr->chksum = chksum_slow; - } -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ - } -#else /* TCP_CHECKSUM_ON_COPY */ -#if CHECKSUM_GEN_TCP - seg->tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* CHECKSUM_GEN_TCP */ -#endif /* TCP_CHECKSUM_ON_COPY */ - TCP_STATS_INC(tcp.xmit); - -#if LWIP_NETIF_HWADDRHINT - ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, - pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - pcb->tos, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ -} - -/** - * Send a TCP RESET packet (empty segment with RST flag set) either to - * abort a connection or to show that there is no matching local connection - * for a received segment. - * - * Called by tcp_abort() (to abort a local connection), tcp_input() (if no - * matching local pcb was found), tcp_listen_input() (if incoming segment - * has ACK flag set) and tcp_process() (received segment in the wrong state) - * - * Since a RST segment is in most cases not sent for an active connection, - * tcp_rst() has a number of arguments that are taken from a tcp_pcb for - * most other segment output functions. - * - * @param seqno the sequence number to use for the outgoing segment - * @param ackno the acknowledge number to use for the outgoing segment - * @param local_ip the local IP address to send the segment from - * @param remote_ip the remote IP address to send the segment to - * @param local_port the local TCP port to send the segment from - * @param remote_port the remote TCP port to send the segment to - */ -void -tcp_rst_impl(u32_t seqno, u32_t ackno, - ipX_addr_t *local_ip, ipX_addr_t *remote_ip, - u16_t local_port, u16_t remote_port -#if LWIP_IPV6 - , u8_t isipv6 -#endif /* LWIP_IPV6 */ - ) -{ - struct pbuf *p; - struct tcp_hdr *tcphdr; - p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); - return; - } - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= sizeof(struct tcp_hdr))); - - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = htons(local_port); - tcphdr->dest = htons(remote_port); - tcphdr->seqno = htonl(seqno); - tcphdr->ackno = htonl(ackno); - TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); - tcphdr->wnd = PP_HTONS(TCP_WND); - tcphdr->chksum = 0; - tcphdr->urgp = 0; - - TCP_STATS_INC(tcp.xmit); - snmp_inc_tcpoutrsts(); - -#if CHECKSUM_GEN_TCP - tcphdr->chksum = ipX_chksum_pseudo(isipv6, p, IP_PROTO_TCP, p->tot_len, - local_ip, remote_ip); -#endif - /* Send output with hardcoded TTL/HL since we have no access to the pcb */ - ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); - pbuf_free(p); - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); -} - -/** - * Requeue all unacked segments for retransmission - * - * Called by tcp_slowtmr() for slow retransmission. - * - * @param pcb the tcp_pcb for which to re-enqueue all unacked segments - */ -void -tcp_rexmit_rto(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - - if (pcb->unacked == NULL) { - return; - } - - /* Move all unacked segments to the head of the unsent queue */ - for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); - /* concatenate unsent queue after unacked queue */ - seg->next = pcb->unsent; - /* unsent queue is the concatenated queue (of unacked, unsent) */ - pcb->unsent = pcb->unacked; - /* unacked queue is now empty */ - pcb->unacked = NULL; - /* last unsent hasn't changed, no need to reset unsent_oversize */ - - /* increment number of retransmissions */ - ++pcb->nrtx; - - /* Don't take any RTT measurements after retransmitting. */ - pcb->rttest = 0; - - /* Do the actual retransmission */ - tcp_output(pcb); -} - -/** - * Requeue the first unacked segment for retransmission - * - * Called by tcp_receive() for fast retramsmit. - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -void -tcp_rexmit(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - struct tcp_seg **cur_seg; - - if (pcb->unacked == NULL) { - return; - } - - /* Move the first unacked segment to the unsent queue */ - /* Keep the unsent queue sorted. */ - seg = pcb->unacked; - pcb->unacked = seg->next; - - cur_seg = &(pcb->unsent); - while (*cur_seg && - TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = *cur_seg; - *cur_seg = seg; -#if TCP_OVERSIZE - if (seg->next == NULL) { - /* the retransmitted segment is last in unsent, so reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - ++pcb->nrtx; - - /* Don't take any rtt measurements after retransmitting. */ - pcb->rttest = 0; - - /* Do the actual retransmission. */ - snmp_inc_tcpretranssegs(); - /* No need to call tcp_output: we are always called from tcp_input() - and thus tcp_output directly returns. */ -} - - -/** - * Handle retransmission after three dupacks received - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -void -tcp_rexmit_fast(struct tcp_pcb *pcb) -{ - if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { - /* This is fast retransmit. Retransmit the first unacked segment. */ - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: dupacks %"U16_F" (%"U32_F - "), fast retransmit %"U32_F"\n", - (u16_t)pcb->dupacks, pcb->lastack, - ntohl(pcb->unacked->tcphdr->seqno))); - tcp_rexmit(pcb); - - /* Set ssthresh to half of the minimum of the current - * cwnd and the advertised window */ - if (pcb->cwnd > pcb->snd_wnd) { - pcb->ssthresh = pcb->snd_wnd / 2; - } else { - pcb->ssthresh = pcb->cwnd / 2; - } - - /* The minimum value for ssthresh should be 2 MSS */ - if (pcb->ssthresh < 2*pcb->mss) { - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: The minimum value for ssthresh %"U16_F - " should be min 2 mss %"U16_F"...\n", - pcb->ssthresh, 2*pcb->mss)); - pcb->ssthresh = 2*pcb->mss; - } - - pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; - pcb->flags |= TF_INFR; - } -} - - -/** - * Send keepalive packets to keep a connection active although - * no data is sent over it. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a keepalive packet - */ -void -tcp_keepalive(struct tcp_pcb *pcb) -{ - struct pbuf *p; -#if CHECKSUM_GEN_TCP - struct tcp_hdr *tcphdr; -#endif /* CHECKSUM_GEN_TCP */ - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); - - p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); - if(p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_keepalive: could not allocate memory for pbuf\n")); - return; - } -#if CHECKSUM_GEN_TCP - tcphdr = (struct tcp_hdr *)p->payload; - - tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); -#endif /* CHECKSUM_GEN_TCP */ - TCP_STATS_INC(tcp.xmit); - - /* Send output to IP */ -#if LWIP_NETIF_HWADDRHINT - ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, - pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - - pbuf_free(p); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", - pcb->snd_nxt - 1, pcb->rcv_nxt)); -} - - -/** - * Send persist timer zero-window probes to keep a connection active - * when a window update is lost. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a zero-window probe packet - */ -void -tcp_zero_window_probe(struct tcp_pcb *pcb) -{ - struct pbuf *p; - struct tcp_hdr *tcphdr; - struct tcp_seg *seg; - u16_t len; - u8_t is_fin; - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_zero_window_probe: tcp_ticks %"U32_F - " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); - - seg = pcb->unacked; - - if(seg == NULL) { - seg = pcb->unsent; - } - if(seg == NULL) { - return; - } - - is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); - /* we want to send one seqno: either FIN or data (no options) */ - len = is_fin ? 0 : 1; - - p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); - if(p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); - return; - } - tcphdr = (struct tcp_hdr *)p->payload; - - if (is_fin) { - /* FIN segment, no data */ - TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); - } else { - /* Data segment, copy in one byte from the head of the unacked queue */ - char *d = ((char *)p->payload + TCP_HLEN); - /* Depending on whether the segment has already been sent (unacked) or not - (unsent), seg->p->payload points to the IP header or TCP header. - Ensure we copy the first TCP data byte: */ - pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); - } - -#if CHECKSUM_GEN_TCP - tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); -#endif - TCP_STATS_INC(tcp.xmit); - - /* Send output to IP */ -#if LWIP_NETIF_HWADDRHINT - ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - 0, IP_PROTO_TCP, &pcb->addr_hint); -#else /* LWIP_NETIF_HWADDRHINT*/ - ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); -#endif /* LWIP_NETIF_HWADDRHINT*/ - - pbuf_free(p); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F - " ackno %"U32_F".\n", - pcb->snd_nxt - 1, pcb->rcv_nxt)); -} -#endif /* LWIP_TCP */ diff --git a/external/badvpn_dns/lwip/src/core/timers.c b/external/badvpn_dns/lwip/src/core/timers.c deleted file mode 100644 index c8ead4e..0000000 --- a/external/badvpn_dns/lwip/src/core/timers.c +++ /dev/null @@ -1,546 +0,0 @@ -/** - * @file - * Stack-internal timers implementation. - * This file includes timer callbacks for stack-internal timers as well as - * functions to set up or stop timers and check for expired timers. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#include "lwip/timers.h" -#include "lwip/tcp_impl.h" - -#if LWIP_TIMERS - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/tcpip.h" - -#include "lwip/ip_frag.h" -#include "netif/etharp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/nd6.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" -#include "lwip/sys.h" -#include "lwip/pbuf.h" - -/** The one and only timeout list */ -static struct sys_timeo *next_timeout; -#if NO_SYS -static u32_t timeouts_last_time; -#endif /* NO_SYS */ - -#if LWIP_TCP -/** global variable that shows if the tcp timer is currently scheduled or not */ -static int tcpip_tcp_timer_active; - -/** - * Timer callback function that calls tcp_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -tcpip_tcp_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - - /* call TCP timer handler */ - tcp_tmr(); - /* timer still needed? */ - if (tcp_active_pcbs || tcp_tw_pcbs) { - /* restart timer */ - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - } else { - /* disable timer */ - tcpip_tcp_timer_active = 0; - } -} - -/** - * Called from TCP_REG when registering a new PCB: - * the reason is to have the TCP timer only running when - * there are active (or time-wait) PCBs. - */ -void -tcp_timer_needed(void) -{ - /* timer is off but needed again? */ - if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { - /* enable and start timer */ - tcpip_tcp_timer_active = 1; - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - } -} -#endif /* LWIP_TCP */ - -#if IP_REASSEMBLY -/** - * Timer callback function that calls ip_reass_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -ip_reass_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); - ip_reass_tmr(); - sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); -} -#endif /* IP_REASSEMBLY */ - -#if LWIP_ARP -/** - * Timer callback function that calls etharp_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -arp_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); - etharp_tmr(); - sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); -} -#endif /* LWIP_ARP */ - -#if LWIP_DHCP -/** - * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -dhcp_timer_coarse(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); - dhcp_coarse_tmr(); - sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); -} - -/** - * Timer callback function that calls dhcp_fine_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -dhcp_timer_fine(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n")); - dhcp_fine_tmr(); - sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); -} -#endif /* LWIP_DHCP */ - -#if LWIP_AUTOIP -/** - * Timer callback function that calls autoip_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -autoip_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n")); - autoip_tmr(); - sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); -} -#endif /* LWIP_AUTOIP */ - -#if LWIP_IGMP -/** - * Timer callback function that calls igmp_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -igmp_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n")); - igmp_tmr(); - sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); -} -#endif /* LWIP_IGMP */ - -#if LWIP_DNS -/** - * Timer callback function that calls dns_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -dns_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n")); - dns_tmr(); - sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); -} -#endif /* LWIP_DNS */ - -#if LWIP_IPV6 -/** - * Timer callback function that calls nd6_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -nd6_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: nd6_tmr()\n")); - nd6_tmr(); - sys_timeout(ND6_TMR_INTERVAL, nd6_timer, NULL); -} - -#if LWIP_IPV6_REASS -/** - * Timer callback function that calls ip6_reass_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -ip6_reass_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip6_reass_tmr()\n")); - ip6_reass_tmr(); - sys_timeout(IP6_REASS_TMR_INTERVAL, ip6_reass_timer, NULL); -} -#endif /* LWIP_IPV6_REASS */ - -#if LWIP_IPV6_MLD -/** - * Timer callback function that calls mld6_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -mld6_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: mld6_tmr()\n")); - mld6_tmr(); - sys_timeout(MLD6_TMR_INTERVAL, mld6_timer, NULL); -} -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6 */ - -/** Initialize this module */ -void sys_timeouts_init(void) -{ -#if IP_REASSEMBLY - sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); -#endif /* IP_REASSEMBLY */ -#if LWIP_ARP - sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); -#endif /* LWIP_ARP */ -#if LWIP_DHCP - sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); - sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); -#endif /* LWIP_AUTOIP */ -#if LWIP_IGMP - sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); -#endif /* LWIP_IGMP */ -#if LWIP_DNS - sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); -#endif /* LWIP_DNS */ -#if LWIP_IPV6 - sys_timeout(ND6_TMR_INTERVAL, nd6_timer, NULL); -#if LWIP_IPV6_REASS - sys_timeout(IP6_REASS_TMR_INTERVAL, ip6_reass_timer, NULL); -#endif /* LWIP_IPV6_REASS */ -#if LWIP_IPV6_MLD - sys_timeout(MLD6_TMR_INTERVAL, mld6_timer, NULL); -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6 */ - -#if NO_SYS - /* Initialise timestamp for sys_check_timeouts */ - timeouts_last_time = sys_now(); -#endif -} - -/** - * Create a one-shot timer (aka timeout). Timeouts are processed in the - * following cases: - * - while waiting for a message using sys_timeouts_mbox_fetch() - * - by calling sys_check_timeouts() (NO_SYS==1 only) - * - * @param msecs time in milliseconds after that the timer should expire - * @param handler callback function to call when msecs have elapsed - * @param arg argument to pass to the callback function - */ -#if LWIP_DEBUG_TIMERNAMES -void -sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) -#else /* LWIP_DEBUG_TIMERNAMES */ -void -sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) -#endif /* LWIP_DEBUG_TIMERNAMES */ -{ - struct sys_timeo *timeout, *t; - - timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); - if (timeout == NULL) { - LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); - return; - } - timeout->next = NULL; - timeout->h = handler; - timeout->arg = arg; - timeout->time = msecs; -#if LWIP_DEBUG_TIMERNAMES - timeout->handler_name = handler_name; - LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", - (void *)timeout, msecs, handler_name, (void *)arg)); -#endif /* LWIP_DEBUG_TIMERNAMES */ - - if (next_timeout == NULL) { - next_timeout = timeout; - return; - } - - if (next_timeout->time > msecs) { - next_timeout->time -= msecs; - timeout->next = next_timeout; - next_timeout = timeout; - } else { - for(t = next_timeout; t != NULL; t = t->next) { - timeout->time -= t->time; - if (t->next == NULL || t->next->time > timeout->time) { - if (t->next != NULL) { - t->next->time -= timeout->time; - } - timeout->next = t->next; - t->next = timeout; - break; - } - } - } -} - -/** - * Go through timeout list (for this task only) and remove the first matching - * entry, even though the timeout has not triggered yet. - * - * @note This function only works as expected if there is only one timeout - * calling 'handler' in the list of timeouts. - * - * @param handler callback function that would be called by the timeout - * @param arg callback argument that would be passed to handler -*/ -void -sys_untimeout(sys_timeout_handler handler, void *arg) -{ - struct sys_timeo *prev_t, *t; - - if (next_timeout == NULL) { - return; - } - - for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { - if ((t->h == handler) && (t->arg == arg)) { - /* We have a match */ - /* Unlink from previous in list */ - if (prev_t == NULL) { - next_timeout = t->next; - } else { - prev_t->next = t->next; - } - /* If not the last one, add time of this one back to next */ - if (t->next != NULL) { - t->next->time += t->time; - } - memp_free(MEMP_SYS_TIMEOUT, t); - return; - } - } - return; -} - -#if NO_SYS - -/** Handle timeouts for NO_SYS==1 (i.e. without using - * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout - * handler functions when timeouts expire. - * - * Must be called periodically from your main loop. - */ -void -sys_check_timeouts(void) -{ - if (next_timeout) { - struct sys_timeo *tmptimeout; - u32_t diff; - sys_timeout_handler handler; - void *arg; - u8_t had_one; - u32_t now; - - now = sys_now(); - /* this cares for wraparounds */ - diff = now - timeouts_last_time; - do - { -#if PBUF_POOL_FREE_OOSEQ - PBUF_CHECK_FREE_OOSEQ(); -#endif /* PBUF_POOL_FREE_OOSEQ */ - had_one = 0; - tmptimeout = next_timeout; - if (tmptimeout && (tmptimeout->time <= diff)) { - /* timeout has expired */ - had_one = 1; - timeouts_last_time = now; - diff -= tmptimeout->time; - next_timeout = tmptimeout->next; - handler = tmptimeout->h; - arg = tmptimeout->arg; -#if LWIP_DEBUG_TIMERNAMES - if (handler != NULL) { - LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", - tmptimeout->handler_name, arg)); - } -#endif /* LWIP_DEBUG_TIMERNAMES */ - memp_free(MEMP_SYS_TIMEOUT, tmptimeout); - if (handler != NULL) { - handler(arg); - } - } - /* repeat until all expired timers have been called */ - }while(had_one); - } -} - -/** Set back the timestamp of the last call to sys_check_timeouts() - * This is necessary if sys_check_timeouts() hasn't been called for a long - * time (e.g. while saving energy) to prevent all timer functions of that - * period being called. - */ -void -sys_restart_timeouts(void) -{ - timeouts_last_time = sys_now(); -} - -#else /* NO_SYS */ - -/** - * Wait (forever) for a message to arrive in an mbox. - * While waiting, timeouts are processed. - * - * @param mbox the mbox to fetch the message from - * @param msg the place to store the message - */ -void -sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) -{ - u32_t time_needed; - struct sys_timeo *tmptimeout; - sys_timeout_handler handler; - void *arg; - - again: - if (!next_timeout) { - time_needed = sys_arch_mbox_fetch(mbox, msg, 0); - } else { - if (next_timeout->time > 0) { - time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time); - } else { - time_needed = SYS_ARCH_TIMEOUT; - } - - if (time_needed == SYS_ARCH_TIMEOUT) { - /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message - could be fetched. We should now call the timeout handler and - deallocate the memory allocated for the timeout. */ - tmptimeout = next_timeout; - next_timeout = tmptimeout->next; - handler = tmptimeout->h; - arg = tmptimeout->arg; -#if LWIP_DEBUG_TIMERNAMES - if (handler != NULL) { - LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n", - tmptimeout->handler_name, arg)); - } -#endif /* LWIP_DEBUG_TIMERNAMES */ - memp_free(MEMP_SYS_TIMEOUT, tmptimeout); - if (handler != NULL) { - /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the - timeout handler function. */ - LOCK_TCPIP_CORE(); - handler(arg); - UNLOCK_TCPIP_CORE(); - } - LWIP_TCPIP_THREAD_ALIVE(); - - /* We try again to fetch a message from the mbox. */ - goto again; - } else { - /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout - occured. The time variable is set to the number of - milliseconds we waited for the message. */ - if (time_needed < next_timeout->time) { - next_timeout->time -= time_needed; - } else { - next_timeout->time = 0; - } - } - } -} - -#endif /* NO_SYS */ - -#else /* LWIP_TIMERS */ -/* Satisfy the TCP code which calls this function */ -void -tcp_timer_needed(void) -{ -} -#endif /* LWIP_TIMERS */ diff --git a/external/badvpn_dns/lwip/src/core/udp.c b/external/badvpn_dns/lwip/src/core/udp.c deleted file mode 100644 index ac0e56d..0000000 --- a/external/badvpn_dns/lwip/src/core/udp.c +++ /dev/null @@ -1,1151 +0,0 @@ -/** - * @file - * User Datagram Protocol module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - - -/* udp.c - * - * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). - * - */ - -/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! - */ - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/icmp6.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "arch/perf.h" -#include "lwip/dhcp.h" - -#include <string.h> - -#ifndef UDP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define UDP_LOCAL_PORT_RANGE_START 0xc000 -#define UDP_LOCAL_PORT_RANGE_END 0xffff -#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START) -#endif - -/* last local UDP port */ -static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; - -/* The list of UDP PCBs */ -/* exported in udp.h (was static) */ -struct udp_pcb *udp_pcbs; - -/** - * Initialize this module. - */ -void -udp_init(void) -{ -#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) - udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ -} - -/** - * Allocate a new local UDP port. - * - * @return a new (free) local UDP port number - */ -static u16_t -udp_new_port(void) -{ - u16_t n = 0; - struct udp_pcb *pcb; - -again: - if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { - udp_port = UDP_LOCAL_PORT_RANGE_START; - } - /* Check all PCBs. */ - for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == udp_port) { - if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - return udp_port; -#if 0 - struct udp_pcb *ipcb = udp_pcbs; - while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { - if (ipcb->local_port == udp_port) { - /* port is already used by another udp_pcb */ - udp_port++; - /* restart scanning all udp pcbs */ - ipcb = udp_pcbs; - } else { - /* go on with next udp pcb */ - ipcb = ipcb->next; - } - } - if (ipcb != NULL) { - return 0; - } - return udp_port; -#endif -} - -/** - * Process an incoming UDP datagram. - * - * Given an incoming UDP datagram (as a chain of pbufs) this function - * finds a corresponding UDP PCB and hands over the pbuf to the pcbs - * recv function. If no pcb is found or the datagram is incorrect, the - * pbuf is freed. - * - * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header) - * @param inp network interface on which the datagram was received. - * - */ -void -udp_input(struct pbuf *p, struct netif *inp) -{ - struct udp_hdr *udphdr; - struct udp_pcb *pcb, *prev; - struct udp_pcb *uncon_pcb; - u16_t src, dest; - u8_t local_match; - u8_t broadcast; - u8_t for_us; - - PERF_START; - - UDP_STATS_INC(udp.recv); - - /* Check minimum length (UDP header) */ - if (p->len < UDP_HLEN) { - /* drop short packets */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); - UDP_STATS_INC(udp.lenerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; - } - - udphdr = (struct udp_hdr *)p->payload; - - /* is broadcast packet ? */ -#if LWIP_IPV6 - broadcast = !ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp); -#else /* LWIP_IPV6 */ - broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp); -#endif /* LWIP_IPV6 */ - - LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); - - /* convert src and dest ports to host byte order */ - src = ntohs(udphdr->src); - dest = ntohs(udphdr->dest); - - udp_debug_print(udphdr); - - /* print the UDP source and destination */ - LWIP_DEBUGF(UDP_DEBUG, ("udp (")); - ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_dest_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest))); - ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_src_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src))); - -#if LWIP_DHCP - pcb = NULL; - /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by - the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */ - if (dest == DHCP_CLIENT_PORT) { - /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */ - if (src == DHCP_SERVER_PORT) { - if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { - /* accept the packe if - (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! - - inp->dhcp->pcb->remote == ANY or iphdr->src - (no need to check for IPv6 since the dhcp struct always uses IPv4) */ - if (ipX_addr_isany(0, &inp->dhcp->pcb->remote_ip) || - ip_addr_cmp(ipX_2_ip(&(inp->dhcp->pcb->remote_ip)), ip_current_src_addr())) { - pcb = inp->dhcp->pcb; - } - } - } - } else -#endif /* LWIP_DHCP */ - { - prev = NULL; - local_match = 0; - uncon_pcb = NULL; - /* Iterate through the UDP pcb list for a matching pcb. - * 'Perfect match' pcbs (connected to the remote port & ip address) are - * preferred. If no perfect match is found, the first unconnected pcb that - * matches the local port and ip address gets the datagram. */ - for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - local_match = 0; - /* print the PCB local and remote address */ - LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); - - /* compare PCB local addr+port to UDP destination addr+port */ - if (pcb->local_port == dest) { - if ( -#if LWIP_IPV6 - ((PCB_ISIPV6(pcb) && (ip_current_is_v6()) && - (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip)) || -#if LWIP_IPV6_MLD - ip6_addr_ismulticast(ip6_current_dest_addr()) || -#endif /* LWIP_IPV6_MLD */ - ip6_addr_cmp(ipX_2_ip6(&pcb->local_ip), ip6_current_dest_addr()))) || - (!PCB_ISIPV6(pcb) && - (ip_current_header() != NULL) && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - ((!broadcast && ipX_addr_isany(0, &pcb->local_ip)) || - ip_addr_cmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr()) || -#if LWIP_IGMP - ip_addr_ismulticast(ip_current_dest_addr()) || -#endif /* LWIP_IGMP */ -#if IP_SOF_BROADCAST_RECV - (broadcast && ip_get_option(pcb, SOF_BROADCAST) && - (ipX_addr_isany(0, &pcb->local_ip) || - ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { -#else /* IP_SOF_BROADCAST_RECV */ - (broadcast && - (ipX_addr_isany(0, &pcb->local_ip) || - ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { -#endif /* IP_SOF_BROADCAST_RECV */ - local_match = 1; - if ((uncon_pcb == NULL) && - ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { - /* the first unconnected matching PCB */ - uncon_pcb = pcb; - } - } - } - /* compare PCB remote addr+port to UDP source addr+port */ - if ((local_match != 0) && - (pcb->remote_port == src) && IP_PCB_IPVER_INPUT_MATCH(pcb) && - (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->remote_ip) || - ipX_addr_cmp(PCB_ISIPV6(pcb), &pcb->remote_ip, ipX_current_src_addr()))) { - /* the first fully matching PCB */ - if (prev != NULL) { - /* move the pcb to the front of udp_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } else { - UDP_STATS_INC(udp.cachehit); - } - break; - } - prev = pcb; - } - /* no fully matching pcb found? then look for an unconnected pcb */ - if (pcb == NULL) { - pcb = uncon_pcb; - } - } - - /* Check checksum if this is a match or if it was directed at us. */ - if (pcb != NULL) { - for_us = 1; - } else { -#if LWIP_IPV6 - if (ip_current_is_v6()) { - for_us = netif_matches_ip6_addr(inp, ip6_current_dest_addr()); - } else -#endif /* LWIP_IPV6 */ - { - for_us = ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr()); - } - } - if (for_us) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); -#if CHECKSUM_CHECK_UDP -#if LWIP_UDPLITE - if (ip_current_header_proto() == IP_PROTO_UDPLITE) { - /* Do the UDP Lite checksum */ - u16_t chklen = ntohs(udphdr->len); - if (chklen < sizeof(struct udp_hdr)) { - if (chklen == 0) { - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet (See RFC 3828 chap. 3.1) */ - chklen = p->tot_len; - } else { - /* At least the UDP-Lite header must be covered by the - checksum! (Again, see RFC 3828 chap. 3.1) */ - goto chkerr; - } - } - if (ipX_chksum_pseudo_partial(ip_current_is_v6(), p, IP_PROTO_UDPLITE, - p->tot_len, chklen, - ipX_current_src_addr(), ipX_current_dest_addr()) != 0) { - goto chkerr; - } - } else -#endif /* LWIP_UDPLITE */ - { - if (udphdr->chksum != 0) { - if (ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_UDP, p->tot_len, - ipX_current_src_addr(), - ipX_current_dest_addr()) != 0) { - goto chkerr; - } - } - } -#endif /* CHECKSUM_CHECK_UDP */ - if(pbuf_header(p, -UDP_HLEN)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - goto end; - } - if (pcb != NULL) { - snmp_inc_udpindatagrams(); -#if SO_REUSE && SO_REUSE_RXTOALL - if ((broadcast || -#if LWIP_IPV6 - ip6_addr_ismulticast(ip6_current_dest_addr()) || -#endif /* LWIP_IPV6 */ - ip_addr_ismulticast(ip_current_dest_addr())) && - ip_get_option(pcb, SOF_REUSEADDR)) { - /* pass broadcast- or multicast packets to all multicast pcbs - if SOF_REUSEADDR is set on the first match */ - struct udp_pcb *mpcb; - u8_t p_header_changed = 0; - s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN); - for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { - if (mpcb != pcb) { - /* compare PCB local addr+port to UDP destination addr+port */ - if ((mpcb->local_port == dest) && -#if LWIP_IPV6 - ((PCB_ISIPV6(mpcb) && - (ip6_addr_ismulticast(ip6_current_dest_addr()) || - ip6_addr_cmp(ipX_2_ip6(&mpcb->local_ip), ip6_current_dest_addr()))) || - (!PCB_ISIPV6(mpcb) && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - ((!broadcast && ipX_addr_isany(0, &mpcb->local_ip)) || - ip_addr_cmp(ipX_2_ip(&mpcb->local_ip), ip_current_dest_addr()) || -#if LWIP_IGMP - ip_addr_ismulticast(ip_current_dest_addr()) || -#endif /* LWIP_IGMP */ -#if IP_SOF_BROADCAST_RECV - (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) { -#else /* IP_SOF_BROADCAST_RECV */ - (broadcast))))) { -#endif /* IP_SOF_BROADCAST_RECV */ - /* pass a copy of the packet to all local matches */ - if (mpcb->recv.ip4 != NULL) { - struct pbuf *q; - /* for that, move payload to IP header again */ - if (p_header_changed == 0) { - pbuf_header(p, hdrs_len); - p_header_changed = 1; - } - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if (q != NULL) { - err_t err = pbuf_copy(q, p); - if (err == ERR_OK) { - /* move payload to UDP data */ - pbuf_header(q, -hdrs_len); -#if LWIP_IPV6 - if (PCB_ISIPV6(mpcb)) { - mpcb->recv.ip6(mpcb->recv_arg, mpcb, q, ip6_current_src_addr(), src); - } - else -#endif /* LWIP_IPV6 */ - { - mpcb->recv.ip4(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); - } - } - } - } - } - } - } - if (p_header_changed) { - /* and move payload to UDP data again */ - pbuf_header(p, -hdrs_len); - } - } -#endif /* SO_REUSE && SO_REUSE_RXTOALL */ - /* callback */ - if (pcb->recv.ip4 != NULL) { - /* now the recv function is responsible for freeing p */ -#if LWIP_IPV6 - if (PCB_ISIPV6(pcb)) { - pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr(), src); - } - else -#endif /* LWIP_IPV6 */ - { - pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); - } - } else { - /* no recv function registered? then we have to free the pbuf! */ - pbuf_free(p); - goto end; - } - } else { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); - -#if LWIP_ICMP || LWIP_ICMP6 - /* No match was found, send ICMP destination port unreachable unless - destination address was broadcast/multicast. */ - if (!broadcast && -#if LWIP_IPV6 - !ip6_addr_ismulticast(ip6_current_dest_addr()) && -#endif /* LWIP_IPV6 */ - !ip_addr_ismulticast(ip_current_dest_addr())) { - /* move payload pointer back to ip header */ - pbuf_header(p, ip_current_header_tot_len() + UDP_HLEN); - icmp_port_unreach(ip_current_is_v6(), p); - } -#endif /* LWIP_ICMP || LWIP_ICMP6 */ - UDP_STATS_INC(udp.proterr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpnoports(); - pbuf_free(p); - } - } else { - pbuf_free(p); - } -end: - PERF_STOP("udp_input"); - return; -#if CHECKSUM_CHECK_UDP -chkerr: - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - snmp_inc_udpinerrors(); - pbuf_free(p); - PERF_STOP("udp_input"); -#endif /* CHECKSUM_CHECK_UDP */ -} - -/** - * Send data using UDP. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * - * The datagram will be sent to the current remote_ip & remote_port - * stored in pcb. If the pcb is not bound to a port, it will - * automatically be bound to a random port. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occured. - * - ERR_MEM. Out of memory. - * - ERR_RTE. Could not find route to destination address. - * - More errors could be returned by lower protocol layers. - * - * @see udp_disconnect() udp_sendto() - */ -err_t -udp_send(struct udp_pcb *pcb, struct pbuf *p) -{ - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port); -} - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -/** Same as udp_send() but with checksum - */ -err_t -udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum) -{ - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto_chksum(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port, - have_chksum, chksum); -} -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -/** - * Send data to a specified address using UDP. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * If the PCB already has a remote address association, it will - * be restored after the data is sent. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); -} - -/** Same as udp_sendto(), but with checksum */ -err_t -udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, - u16_t dst_port, u8_t have_chksum, u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct netif *netif; - ipX_addr_t *dst_ip_route = ip_2_ipX(dst_ip); - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); - -#if LWIP_IPV6 || LWIP_IGMP - if (ipX_addr_ismulticast(PCB_ISIPV6(pcb), dst_ip_route)) { - /* For multicast, find a netif based on source address. */ -#if LWIP_IPV6 - if (PCB_ISIPV6(pcb)) { - dst_ip_route = &pcb->local_ip; - } else -#endif /* LWIP_IPV6 */ - { -#if LWIP_IGMP - dst_ip_route = ip_2_ipX(&pcb->multicast_ip); -#endif /* LWIP_IGMP */ - } - } -#endif /* LWIP_IPV6 || LWIP_IGMP */ - - /* find the outgoing network interface for this packet */ - netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip_route); - - /* no outgoing network interface could be found? */ - if (netif == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ip_2_ipX(dst_ip)); - LWIP_DEBUGF(UDP_DEBUG, ("\n")); - UDP_STATS_INC(udp.rterr); - return ERR_RTE; - } -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); -#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -} - -/** - * Send data to a specified address using UDP. - * The netif used for sending can be specified. - * - * This function exists mainly for DHCP, to be able to send UDP packets - * on a netif that is still down. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * @param netif the netif used for sending. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); -} - -/** Same as udp_sendto_if(), but with checksum */ -err_t -udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, - u16_t dst_port, struct netif *netif, u8_t have_chksum, - u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct udp_hdr *udphdr; - ip_addr_t *src_ip; - err_t err; - struct pbuf *q; /* q will be sent down the stack */ - u8_t ip_proto; - -#if IP_SOF_BROADCAST - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && -#if LWIP_IPV6 - !PCB_ISIPV6(pcb) && -#endif /* LWIP_IPV6 */ - ip_addr_isbroadcast(dst_ip, netif) ) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - return ERR_VAL; - } -#endif /* IP_SOF_BROADCAST */ - - /* if the PCB is not yet bound to a port, bind it here */ - if (pcb->local_port == 0) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); - err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); - if (err != ERR_OK) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); - return err; - } - } - - /* not enough space to add an UDP header to first pbuf in given p chain? */ - if (pbuf_header(p, UDP_HLEN)) { - /* allocate header in a separate new pbuf */ - q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p (only if p contains data) */ - pbuf_chain(q, p); - } - /* first pbuf q points to header pbuf */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* adding space for header within p succeeded */ - /* first pbuf q equals given pbuf */ - q = p; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); - } - LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", - (q->len >= sizeof(struct udp_hdr))); - /* q now represents the packet to be sent */ - udphdr = (struct udp_hdr *)q->payload; - udphdr->src = htons(pcb->local_port); - udphdr->dest = htons(dst_port); - /* in UDP, 0 checksum means 'no checksum' */ - udphdr->chksum = 0x0000; - - /* Multicast Loop? */ -#if LWIP_IGMP - if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && -#if LWIP_IPV6 - ( -#if LWIP_IPV6_MLD - (PCB_ISIPV6(pcb) && - ip6_addr_ismulticast(ip_2_ip6(dst_ip))) || -#endif /* LWIP_IPV6_MLD */ - (!PCB_ISIPV6(pcb) && -#else /* LWIP_IPV6 */ - (( -#endif /* LWIP_IPV6 */ - ip_addr_ismulticast(dst_ip)))) { - q->flags |= PBUF_FLAG_MCASTLOOP; - } -#endif /* LWIP_IGMP */ - - - /* PCB local address is IP_ANY_ADDR? */ -#if LWIP_IPV6 - if (PCB_ISIPV6(pcb)) { - if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { - src_ip = ip6_2_ip(ip6_select_source_address(netif, ip_2_ip6(dst_ip))); - if (src_ip == NULL) { - /* No suitable source address was found. */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - /* p is still referenced by the caller, and will live on */ - } - return ERR_RTE; - } - } else { - /* use UDP PCB local IPv6 address as source address, if still valid. */ - if (netif_matches_ip6_addr(netif, ipX_2_ip6(&pcb->local_ip)) < 0) { - /* Address isn't valid anymore. */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - /* p is still referenced by the caller, and will live on */ - } - return ERR_RTE; - } - src_ip = ipX_2_ip(&pcb->local_ip); - } - } - else -#endif /* LWIP_IPV6 */ - if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { - /* use outgoing network interface IP address as source address */ - src_ip = &(netif->ip_addr); - } else { - /* check if UDP PCB local IP address is correct - * this could be an old address if netif->ip_addr has changed */ - if (!ip_addr_cmp(ipX_2_ip(&(pcb->local_ip)), &(netif->ip_addr))) { - /* local_ip doesn't match, drop the packet */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - q = NULL; - /* p is still referenced by the caller, and will live on */ - } - return ERR_VAL; - } - /* use UDP PCB local IP address as source address */ - src_ip = ipX_2_ip(&(pcb->local_ip)); - } - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); - -#if LWIP_UDPLITE - /* UDP Lite protocol? */ - if (pcb->flags & UDP_FLAGS_UDPLITE) { - u16_t chklen, chklen_hdr; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); - /* set UDP message length in UDP header */ - chklen_hdr = chklen = pcb->chksum_len_tx; - if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { - if (chklen != 0) { - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); - } - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet. (See RFC 3828 chap. 3.1) - At least the UDP-Lite header must be covered by the - checksum, therefore, if chksum_len has an illegal - value, we generate the checksum over the complete - packet to be safe. */ - chklen_hdr = 0; - chklen = q->tot_len; - } - udphdr->len = htons(chklen_hdr); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - chklen = UDP_HLEN; - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - udphdr->chksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDPLITE, - q->tot_len, chklen, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - acc = udphdr->chksum + (u16_t)~(chksum); - udphdr->chksum = FOLD_U32T(acc); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udphdr->chksum == 0x0000) { - udphdr->chksum = 0xffff; - } -#endif /* CHECKSUM_GEN_UDP */ - - ip_proto = IP_PROTO_UDPLITE; - } else -#endif /* LWIP_UDPLITE */ - { /* UDP */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); - udphdr->len = htons(q->tot_len); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP - /* Checksum is mandatory over IPv6. */ - if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { - u16_t udpchksum; -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - udpchksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, - q->tot_len, UDP_HLEN, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); - acc = udpchksum + (u16_t)~(chksum); - udpchksum = FOLD_U32T(acc); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - udpchksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, q->tot_len, - ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); - } - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udpchksum == 0x0000) { - udpchksum = 0xffff; - } - udphdr->chksum = udpchksum; - } -#endif /* CHECKSUM_GEN_UDP */ - ip_proto = IP_PROTO_UDP; - } - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); - /* output to IP */ - NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); - err = ipX_output_if(PCB_ISIPV6(pcb), q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - /* TODO: must this be increased even if error occured? */ - snmp_inc_udpoutdatagrams(); - - /* did we chain a separate header pbuf earlier? */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - q = NULL; - /* p is still referenced by the caller, and will live on */ - } - - UDP_STATS_INC(udp.xmit); - return err; -} - -/** - * Bind an UDP PCB. - * - * @param pcb UDP PCB to be bound with a local address ipaddr and port. - * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to - * bind to all local interfaces. - * @param port local UDP port to bind with. Use 0 to automatically bind - * to a random port between UDP_LOCAL_PORT_RANGE_START and - * UDP_LOCAL_PORT_RANGE_END. - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occured. - * - ERR_USE. The specified ipaddr and port are already bound to by - * another UDP PCB. - * - * @see udp_disconnect() - */ -err_t -udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - u8_t rebind; - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE, ip_2_ipX(ipaddr)); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); - - rebind = 0; - /* Check for double bind and rebind of the same pcb */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - /* is this UDP PCB already on active list? */ - if (pcb == ipcb) { - /* pcb may occur at most once in active list */ - LWIP_ASSERT("rebind == 0", rebind == 0); - /* pcb already in list, just rebind */ - rebind = 1; - } - - /* By default, we don't allow to bind to a port that any other udp - PCB is alread bound to, unless *all* PCBs with that port have tha - REUSEADDR flag set. */ -#if SO_REUSE - else if (!ip_get_option(pcb, SOF_REUSEADDR) && - !ip_get_option(ipcb, SOF_REUSEADDR)) { -#else /* SO_REUSE */ - /* port matches that of PCB in list and REUSEADDR not set -> reject */ - else { -#endif /* SO_REUSE */ - if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) && - /* IP address matches, or one is IP_ADDR_ANY? */ - (ipX_addr_isany(PCB_ISIPV6(ipcb), &(ipcb->local_ip)) || - ipX_addr_isany(PCB_ISIPV6(ipcb), ip_2_ipX(ipaddr)) || - ipX_addr_cmp(PCB_ISIPV6(ipcb), &(ipcb->local_ip), ip_2_ipX(ipaddr)))) { - /* other PCB already binds to this local IP and port */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); - return ERR_USE; - } - } - } - - ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->local_ip, ipaddr); - - /* no port specified? */ - if (port == 0) { - port = udp_new_port(); - if (port == 0) { - /* no more ports available in local range */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); - return ERR_USE; - } - } - pcb->local_port = port; - snmp_insert_udpidx_tree(pcb); - /* pcb not active yet? */ - if (rebind == 0) { - /* place the PCB on the active list if not already there */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); - return ERR_OK; -} - -/** - * Connect an UDP PCB. - * - * This will associate the UDP PCB with the remote address. - * - * @param pcb UDP PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * @param port remote UDP port to connect with. - * - * @return lwIP error code - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * The udp pcb is bound to a random local port if not already bound. - * - * @see udp_disconnect() - */ -err_t -udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - - if (pcb->local_port == 0) { - err_t err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); - if (err != ERR_OK) { - return err; - } - } - - ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->remote_ip, ipaddr); - pcb->remote_port = port; - pcb->flags |= UDP_FLAGS_CONNECTED; -/** TODO: this functionality belongs in upper layers */ -#ifdef LWIP_UDP_TODO -#if LWIP_IPV6 - if (!PCB_ISIPV6(pcb)) -#endif /* LWIP_IPV6 */ - { - /* Nail down local IP for netconn_addr()/getsockname() */ - if (ip_addr_isany(ipX_2_ip(&pcb->local_ip)) && !ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { - struct netif *netif; - - if ((netif = ip_route(ipX_2_ip(&pcb->remote_ip))) == NULL) { - LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", - ip4_addr_get_u32(ipX_2_ip(&pcb->remote_ip)))); - UDP_STATS_INC(udp.rterr); - return ERR_RTE; - } - /** TODO: this will bind the udp pcb locally, to the interface which - is used to route output packets to the remote address. However, we - might want to accept incoming packets on any interface! */ - ipX_addr_copy(0, pcb->local_ip, netif->ip_addr); - } else if (ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { - ipX_addr_set_any(0, &pcb->local_ip); - } - } -#endif - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); - ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - &pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); - - /* Insert UDP PCB into the list of active UDP PCBs. */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - if (pcb == ipcb) { - /* already on the list, just return */ - return ERR_OK; - } - } - /* PCB not yet on the list, add PCB now */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - return ERR_OK; -} - -/** - * Disconnect a UDP PCB - * - * @param pcb the udp pcb to disconnect. - */ -void -udp_disconnect(struct udp_pcb *pcb) -{ - /* reset remote address association */ - ipX_addr_set_any(PCB_ISIPV6(pcb), &pcb->remote_ip); - pcb->remote_port = 0; - /* mark PCB as unconnected */ - pcb->flags &= ~UDP_FLAGS_CONNECTED; -} - -/** - * Set a receive callback for a UDP PCB - * - * This callback will be called when receiving a datagram for the pcb. - * - * @param pcb the pcb for wich to set the recv callback - * @param recv function pointer of the callback function - * @param recv_arg additional argument to pass to the callback function - */ -void -udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) -{ - /* remember recv() callback and user data */ - pcb->recv.ip4 = recv; - pcb->recv_arg = recv_arg; -} - -/** - * Remove an UDP PCB. - * - * @param pcb UDP PCB to be removed. The PCB is removed from the list of - * UDP PCB's and the data structure is freed from memory. - * - * @see udp_new() - */ -void -udp_remove(struct udp_pcb *pcb) -{ - struct udp_pcb *pcb2; - - snmp_delete_udpidx_tree(pcb); - /* pcb to be removed is first in list? */ - if (udp_pcbs == pcb) { - /* make list start at 2nd pcb */ - udp_pcbs = udp_pcbs->next; - /* pcb not 1st in list */ - } else { - for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in udp_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - } - } - } - memp_free(MEMP_UDP_PCB, pcb); -} - -/** - * Create a UDP PCB. - * - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new(void) -{ - struct udp_pcb *pcb; - pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); - /* could allocate UDP PCB? */ - if (pcb != NULL) { - /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 - * which means checksum is generated over the whole datagram per default - * (recommended as default by RFC 3828). */ - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct udp_pcb)); - pcb->ttl = UDP_TTL; - } - return pcb; -} - -#if LWIP_IPV6 -/** - * Create a UDP PCB for IPv6. - * - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new_ip6(void) -{ - struct udp_pcb *pcb; - pcb = udp_new(); - ip_set_v6(pcb, 1); - return pcb; -} -#endif /* LWIP_IPV6 */ - -#if UDP_DEBUG -/** - * Print UDP header information for debug purposes. - * - * @param udphdr pointer to the udp header in memory. - */ -void -udp_debug_print(struct udp_hdr *udphdr) -{ - LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - ntohs(udphdr->src), ntohs(udphdr->dest))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", - ntohs(udphdr->len), ntohs(udphdr->chksum))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* UDP_DEBUG */ - -#endif /* LWIP_UDP */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/autoip.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/autoip.h deleted file mode 100644 index e62b72e..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/autoip.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file - * - * AutoIP Automatic LinkLocal IP Configuration - */ - -/* - * - * Copyright (c) 2007 Dominik Spies kontakt@dspies.de - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies kontakt@dspies.de - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - * - * Please coordinate changes and requests with Dominik Spies - * kontakt@dspies.de - */ - -#ifndef __LWIP_AUTOIP_H__ -#define __LWIP_AUTOIP_H__ - -#include "lwip/opt.h" - -#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" -#include "netif/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* AutoIP Timing */ -#define AUTOIP_TMR_INTERVAL 100 -#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) - -/* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ - -/* AutoIP client states */ -#define AUTOIP_STATE_OFF 0 -#define AUTOIP_STATE_PROBING 1 -#define AUTOIP_STATE_ANNOUNCING 2 -#define AUTOIP_STATE_BOUND 3 - -struct autoip -{ - ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ - u8_t state; /* current AutoIP state machine state */ - u8_t sent_num; /* sent number of probes or announces, dependent on state */ - u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ - u8_t lastconflict; /* ticks until a conflict can be solved by defending */ - u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ -}; - - -#define autoip_init() /* Compatibility define, no init needed. */ - -/** Set a struct autoip allocated by the application to work with */ -void autoip_set_struct(struct netif *netif, struct autoip *autoip); - -/** Start AutoIP client */ -err_t autoip_start(struct netif *netif); - -/** Stop AutoIP client */ -err_t autoip_stop(struct netif *netif); - -/** Handles every incoming ARP Packet, called by etharp_arp_input */ -void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); - -/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ -void autoip_tmr(void); - -/** Handle a possible change in the network configuration */ -void autoip_network_changed(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_AUTOIP */ - -#endif /* __LWIP_AUTOIP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/icmp.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/icmp.h deleted file mode 100644 index fa893b6..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/icmp.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_ICMP_H__ -#define __LWIP_ICMP_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -#if LWIP_IPV6 && LWIP_ICMP6 -#include "lwip/icmp6.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define ICMP_ER 0 /* echo reply */ -#define ICMP_DUR 3 /* destination unreachable */ -#define ICMP_SQ 4 /* source quench */ -#define ICMP_RD 5 /* redirect */ -#define ICMP_ECHO 8 /* echo */ -#define ICMP_TE 11 /* time exceeded */ -#define ICMP_PP 12 /* parameter problem */ -#define ICMP_TS 13 /* timestamp */ -#define ICMP_TSR 14 /* timestamp reply */ -#define ICMP_IRQ 15 /* information request */ -#define ICMP_IR 16 /* information reply */ - -enum icmp_dur_type { - ICMP_DUR_NET = 0, /* net unreachable */ - ICMP_DUR_HOST = 1, /* host unreachable */ - ICMP_DUR_PROTO = 2, /* protocol unreachable */ - ICMP_DUR_PORT = 3, /* port unreachable */ - ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ - ICMP_DUR_SR = 5 /* source route failed */ -}; - -enum icmp_te_type { - ICMP_TE_TTL = 0, /* time to live exceeded in transit */ - ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ -}; - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -/** This is the standard ICMP header only that the u32_t data - * is splitted to two u16_t like ICMP echo needs it. - * This header is also used for other ICMP types that do not - * use the data part. - */ -PACK_STRUCT_BEGIN -struct icmp_echo_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define ICMPH_TYPE(hdr) ((hdr)->type) -#define ICMPH_CODE(hdr) ((hdr)->code) - -/** Combines type and code to an u16_t */ -#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) -#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) - - -#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -void icmp_input(struct pbuf *p, struct netif *inp); -void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); -void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); - -#endif /* LWIP_ICMP */ - -#if (LWIP_IPV6 && LWIP_ICMP6) -#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ - icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ - icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) -#elif LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) -#else /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ -#define icmp_port_unreach(isipv6, pbuf) -#endif /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ICMP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/igmp.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/igmp.h deleted file mode 100644 index 8aabac2..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/igmp.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -#ifndef __LWIP_IGMP_H__ -#define __LWIP_IGMP_H__ - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - -#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* IGMP timer */ -#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ -#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) -#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) - -/* MAC Filter Actions, these are passed to a netif's - * igmp_mac_filter callback function. */ -#define IGMP_DEL_MAC_FILTER 0 -#define IGMP_ADD_MAC_FILTER 1 - - -/** - * igmp group structure - there is - * a list of groups for each interface - * these should really be linked from the interface, but - * if we keep them separate we will not affect the lwip original code - * too much - * - * There will be a group for the all systems group address but this - * will not run the state machine as it is used to kick off reports - * from all the other groups - */ -struct igmp_group { - /** next link */ - struct igmp_group *next; - /** interface on which the group is active */ - struct netif *netif; - /** multicast address */ - ip_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting, negative is OFF */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/* Prototypes */ -void igmp_init(void); -err_t igmp_start(struct netif *netif); -err_t igmp_stop(struct netif *netif); -void igmp_report_groups(struct netif *netif); -struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); -void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); -err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); -err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); -void igmp_tmr(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IGMP */ - -#endif /* __LWIP_IGMP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/inet.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/inet.h deleted file mode 100644 index 7bff49b..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/inet.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_INET_H__ -#define __LWIP_INET_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** For compatibility with BSD code */ -struct in_addr { - u32_t s_addr; -}; - -/** 255.255.255.255 */ -#define INADDR_NONE IPADDR_NONE -/** 127.0.0.1 */ -#define INADDR_LOOPBACK IPADDR_LOOPBACK -/** 0.0.0.0 */ -#define INADDR_ANY IPADDR_ANY -/** 255.255.255.255 */ -#define INADDR_BROADCAST IPADDR_BROADCAST - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IN_CLASSA(a) IP_CLASSA(a) -#define IN_CLASSA_NET IP_CLASSA_NET -#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT -#define IN_CLASSA_HOST IP_CLASSA_HOST -#define IN_CLASSA_MAX IP_CLASSA_MAX - -#define IN_CLASSB(b) IP_CLASSB(b) -#define IN_CLASSB_NET IP_CLASSB_NET -#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT -#define IN_CLASSB_HOST IP_CLASSB_HOST -#define IN_CLASSB_MAX IP_CLASSB_MAX - -#define IN_CLASSC(c) IP_CLASSC(c) -#define IN_CLASSC_NET IP_CLASSC_NET -#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT -#define IN_CLASSC_HOST IP_CLASSC_HOST -#define IN_CLASSC_MAX IP_CLASSC_MAX - -#define IN_CLASSD(d) IP_CLASSD(d) -#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ -#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ -#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ -#define IN_CLASSD_MAX IP_CLASSD_MAX - -#define IN_MULTICAST(a) IP_MULTICAST(a) - -#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) -#define IN_BADCLASS(a) IP_BADCLASS(a) - -#define IN_LOOPBACKNET IP_LOOPBACKNET - -#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) -#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) -/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ -#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) - -/* directly map this to the lwip internal functions */ -#define inet_addr(cp) ipaddr_addr(cp) -#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) -#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) -#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INET_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4.h deleted file mode 100644 index 04b5b8a..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_IP4_H__ -#define __LWIP_IP4_H__ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Currently, the function ip_output_if_opt() is only used with IGMP */ -#define IP_OPTIONS_SEND LWIP_IGMP - -#define IP_HLEN 20 - -#define IP_PROTO_ICMP 1 -#define IP_PROTO_IGMP 2 -#define IP_PROTO_UDP 17 -#define IP_PROTO_UDPLITE 136 -#define IP_PROTO_TCP 6 - - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_hdr { - /* version / header length */ - PACK_STRUCT_FIELD(u8_t _v_hl); - /* type of service */ - PACK_STRUCT_FIELD(u8_t _tos); - /* total length */ - PACK_STRUCT_FIELD(u16_t _len); - /* identification */ - PACK_STRUCT_FIELD(u16_t _id); - /* fragment offset field */ - PACK_STRUCT_FIELD(u16_t _offset); -#define IP_RF 0x8000U /* reserved fragment flag */ -#define IP_DF 0x4000U /* dont fragment flag */ -#define IP_MF 0x2000U /* more fragments flag */ -#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ - /* time to live */ - PACK_STRUCT_FIELD(u8_t _ttl); - /* protocol*/ - PACK_STRUCT_FIELD(u8_t _proto); - /* checksum */ - PACK_STRUCT_FIELD(u16_t _chksum); - /* source and destination IP addresses */ - PACK_STRUCT_FIELD(ip_addr_p_t src); - PACK_STRUCT_FIELD(ip_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IPH_V(hdr) ((hdr)->_v_hl >> 4) -#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) -#define IPH_TOS(hdr) ((hdr)->_tos) -#define IPH_LEN(hdr) ((hdr)->_len) -#define IPH_ID(hdr) ((hdr)->_id) -#define IPH_OFFSET(hdr) ((hdr)->_offset) -#define IPH_TTL(hdr) ((hdr)->_ttl) -#define IPH_PROTO(hdr) ((hdr)->_proto) -#define IPH_CHKSUM(hdr) ((hdr)->_chksum) - -#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) -#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) -#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) -#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) -#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) -#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) -#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) -#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) - - -#define ip_init() /* Compatibility define, no init needed. */ -struct netif *ip_route(ip_addr_t *dest); -err_t ip_input(struct pbuf *p, struct netif *inp); -err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto); -err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, - struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if IP_OPTIONS_SEND -err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -#endif /* IP_OPTIONS_SEND */ - -#define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) - -#if IP_DEBUG -void ip_debug_print(struct pbuf *p); -#else -#define ip_debug_print(p) -#endif /* IP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_H__ */ - - diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4_addr.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4_addr.h deleted file mode 100644 index b05ae53..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip4_addr.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_IP4_ADDR_H__ -#define __LWIP_IP4_ADDR_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is the aligned version of ip_addr_t, - used as local variable, on the stack, etc. */ -struct ip_addr { - u32_t addr; -}; - -/* This is the packed version of ip_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_addr_packed { - PACK_STRUCT_FIELD(u32_t addr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** ip_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip_addr_t as well as on ip_addr_p_t. */ -typedef struct ip_addr ip_addr_t; -typedef struct ip_addr_packed ip_addr_p_t; - -/* - * struct ipaddr2 is used in the definition of the ARP packet format in - * order to support compilers that don't have structure packing. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_addr2 { - PACK_STRUCT_FIELD(u16_t addrw[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Forward declaration to not include netif.h */ -struct netif; - -extern const ip_addr_t ip_addr_any; -extern const ip_addr_t ip_addr_broadcast; - -/** IP_ADDR_ can be used as a fixed IP address - * for the wildcard and the broadcast address - */ -#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) -#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) - -/** 255.255.255.255 */ -#define IPADDR_NONE ((u32_t)0xffffffffUL) -/** 127.0.0.1 */ -#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) -/** 0.0.0.0 */ -#define IPADDR_ANY ((u32_t)0x00000000UL) -/** 255.255.255.255 */ -#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) -#define IP_CLASSA_NET 0xff000000 -#define IP_CLASSA_NSHIFT 24 -#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) -#define IP_CLASSA_MAX 128 - -#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) -#define IP_CLASSB_NET 0xffff0000 -#define IP_CLASSB_NSHIFT 16 -#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) -#define IP_CLASSB_MAX 65536 - -#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) -#define IP_CLASSC_NET 0xffffff00 -#define IP_CLASSC_NSHIFT 8 -#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) - -#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) -#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ -#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ -#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ -#define IP_MULTICAST(a) IP_CLASSD(a) - -#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) -#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) - -#define IP_LOOPBACKNET 127 /* official! */ - - -#if BYTE_ORDER == BIG_ENDIAN -/** Set an IP address given by the four byte-parts */ -#define IP4_ADDR(ipaddr, a,b,c,d) \ - (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff) -#else -/** Set an IP address given by the four byte-parts. - Little-endian version that prevents the use of htonl. */ -#define IP4_ADDR(ipaddr, a,b,c,d) \ - (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ - ((u32_t)((c) & 0xff) << 16) | \ - ((u32_t)((b) & 0xff) << 8) | \ - (u32_t)((a) & 0xff) -#endif - -/** MEMCPY-like copying of IP addresses where addresses are known to be - * 16-bit-aligned if the port is correctly configured (so a port could define - * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ -#ifndef IPADDR2_COPY -#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) -#endif - -/** Copy IP address - faster than ip_addr_set: no NULL check */ -#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) -/** Safely copy one IP address to another (src may be NULL) */ -#define ip_addr_set(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0 : \ - (src)->addr)) -/** Set complete address to zero */ -#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) -/** Set address to IPADDR_ANY (no need for htonl()) */ -#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) -/** Set address to loopback address */ -#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) -/** Safely copy one IP address to another and change byte order - * from host- to network-order. */ -#define ip_addr_set_hton(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0:\ - htonl((src)->addr))) -/** IPv4 only: set the IP address given as an u32_t */ -#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) -/** IPv4 only: get the IP address as an u32_t */ -#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) - -/** Get the network address by combining host address with netmask */ -#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) - -/** - * Determine if two address are on the same network. - * - * @arg addr1 IP address 1 - * @arg addr2 IP address 2 - * @arg mask network identifier mask - * @return !0 if the network identifiers of both address match - */ -#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ - (mask)->addr) == \ - ((addr2)->addr & \ - (mask)->addr)) -#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) - -#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) - -#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) -u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); - -#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) -u8_t ip4_addr_netmask_valid(u32_t netmask); - -#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) - -#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) - -#define ip_addr_debug_print(debug, ipaddr) \ - LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ - ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) - -/* Get one byte from the 4-byte address */ -#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) -#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) -#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) -#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) - -/** For backwards compatibility */ -#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) - -u32_t ipaddr_addr(const char *cp); -int ipaddr_aton(const char *cp, ip_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ipaddr_ntoa(const ip_addr_t *addr); -char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip_frag.h b/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip_frag.h deleted file mode 100644 index 47eca9f..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv4/lwip/ip_frag.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses jani@iv.ro - * - */ - -#ifndef __LWIP_IP_FRAG_H__ -#define __LWIP_IP_FRAG_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if IP_REASSEMBLY -/* The IP reassembly timer interval in milliseconds. */ -#define IP_TMR_INTERVAL 1000 - -/* IP reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip_reassdata { - struct ip_reassdata *next; - struct pbuf *p; - struct ip_hdr iphdr; - u16_t datagram_len; - u8_t flags; - u8_t timer; -}; - -void ip_reass_init(void); -void ip_reass_tmr(void); -struct pbuf * ip_reass(struct pbuf *p); -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -#ifndef __LWIP_PBUF_CUSTOM_REF__ -#define __LWIP_PBUF_CUSTOM_REF__ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* __LWIP_PBUF_CUSTOM_REF__ */ -#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ - -err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); -#endif /* IP_FRAG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_FRAG_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/dhcp6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/dhcp6.h deleted file mode 100644 index 4b905c5..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/dhcp6.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file - * - * IPv6 address autoconfiguration as per RFC 4862. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * IPv6 address autoconfiguration as per RFC 4862. - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#ifndef __LWIP_IP6_DHCP6_H__ -#define __LWIP_IP6_DHCP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - - -struct dhcp6 -{ - /*TODO: implement DHCP6*/ -}; - -#endif /* LWIP_IPV6_DHCP6 */ - -#endif /* __LWIP_IP6_DHCP6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ethip6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/ethip6.h deleted file mode 100644 index e7f412b..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ethip6.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#ifndef __LWIP_ETHIP6_H__ -#define __LWIP_ETHIP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -err_t ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ - -#endif /* __LWIP_ETHIP6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/icmp6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/icmp6.h deleted file mode 100644 index 74bfdbe..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/icmp6.h +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ -#ifndef __LWIP_ICMP6_H__ -#define __LWIP_ICMP6_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -enum icmp6_type { - ICMP6_TYPE_DUR = 1, /* Destination unreachable */ - ICMP6_TYPE_PTB = 2, /* Packet too big */ - ICMP6_TYPE_TE = 3, /* Time exceeded */ - ICMP6_TYPE_PP = 4, /* Parameter problem */ - ICMP6_TYPE_PE1 = 100, /* Private experimentation */ - ICMP6_TYPE_PE2 = 101, /* Private experimentation */ - ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */ - - ICMP6_TYPE_EREQ = 128, /* Echo request */ - ICMP6_TYPE_EREP = 129, /* Echo reply */ - ICMP6_TYPE_MLQ = 130, /* Multicast listener query */ - ICMP6_TYPE_MLR = 131, /* Multicast listener report */ - ICMP6_TYPE_MLD = 132, /* Multicast listener done */ - ICMP6_TYPE_RS = 133, /* Router solicitation */ - ICMP6_TYPE_RA = 134, /* Router advertisement */ - ICMP6_TYPE_NS = 135, /* Neighbor solicitation */ - ICMP6_TYPE_NA = 136, /* Neighbor advertisement */ - ICMP6_TYPE_RD = 137, /* Redirect */ - ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */ - ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */ - ICMP6_TYPE_MRT = 153, /* Multicast router termination */ - ICMP6_TYPE_PE3 = 200, /* Private experimentation */ - ICMP6_TYPE_PE4 = 201, /* Private experimentation */ - ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */ -}; - -enum icmp6_dur_code { - ICMP6_DUR_NO_ROUTE = 0, /* No route to destination */ - ICMP6_DUR_PROHIBITED = 1, /* Communication with destination administratively prohibited */ - ICMP6_DUR_SCOPE = 2, /* Beyond scope of source address */ - ICMP6_DUR_ADDRESS = 3, /* Address unreachable */ - ICMP6_DUR_PORT = 4, /* Port unreachable */ - ICMP6_DUR_POLICY = 5, /* Source address failed ingress/egress policy */ - ICMP6_DUR_REJECT_ROUTE = 6 /* Reject route to destination */ -}; - -enum icmp6_te_code { - ICMP6_TE_HL = 0, /* Hop limit exceeded in transit */ - ICMP6_TE_FRAG = 1 /* Fragment reassembly time exceeded */ -}; - -enum icmp6_pp_code { - ICMP6_PP_FIELD = 0, /* Erroneous header field encountered */ - ICMP6_PP_HEADER = 1, /* Unrecognized next header type encountered */ - ICMP6_PP_OPTION = 2 /* Unrecognized IPv6 option encountered */ -}; - -/** This is the standard ICMP6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t data); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** This is the ICMP6 header adapted for echo req/resp. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_echo_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -void icmp6_input(struct pbuf *p, struct netif *inp); -void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); -void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); -void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); -void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* __LWIP_ICMP6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/inet6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/inet6.h deleted file mode 100644 index dbf98df..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/inet6.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file - * - * INET v6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ -#ifndef __LWIP_INET6_H__ -#define __LWIP_INET6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** For compatibility with BSD code */ -struct in6_addr { - union { - u8_t u8_addr[16]; - u32_t u32_addr[4]; - } un; -#define s6_addr un.u32_addr -}; - -#define IN6ADDR_ANY_INIT {0,0,0,0} -#define IN6ADDR_LOOPBACK_INIT {0,0,0,PP_HTONL(1)} - - -#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ - (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ - (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ - (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} -#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ - (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ - (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ - (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];} -/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */ -#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr)) - -/* directly map this to the lwip internal functions */ -#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) -#define inet6_ntoa(addr) ip6addr_ntoa((ip6_addr_t*)&(addr)) -#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((ip6_addr_t*)&(addr), buf, buflen) - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_INET6_H__ */ - diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6.h deleted file mode 100644 index b199c95..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6.h +++ /dev/null @@ -1,197 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ -#ifndef __LWIP_IP6_H__ -#define __LWIP_IP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define IP6_HLEN 40 - -#define IP6_NEXTH_HOPBYHOP 0 -#define IP6_NEXTH_TCP 6 -#define IP6_NEXTH_UDP 17 -#define IP6_NEXTH_ENCAPS 41 -#define IP6_NEXTH_ROUTING 43 -#define IP6_NEXTH_FRAGMENT 44 -#define IP6_NEXTH_ICMP6 58 -#define IP6_NEXTH_NONE 59 -#define IP6_NEXTH_DESTOPTS 60 -#define IP6_NEXTH_UDPLITE 136 - - -/* The IPv6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hdr { - /* version / traffic class / flow label */ - PACK_STRUCT_FIELD(u32_t _v_tc_fl); - /* payload length */ - PACK_STRUCT_FIELD(u16_t _plen); - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* hop limit */ - PACK_STRUCT_FIELD(u8_t _hoplim); - /* source and destination IP addresses */ - PACK_STRUCT_FIELD(ip6_addr_p_t src); - PACK_STRUCT_FIELD(ip6_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Hop-by-hop router alert option. */ -#define IP6_HBH_HLEN 8 -#define IP6_PAD1_OPTION 0 -#define IP6_PADN_ALERT_OPTION 1 -#define IP6_ROUTER_ALERT_OPTION 5 -#define IP6_ROUTER_ALERT_VALUE_MLD 0 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hbh_hdr { - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* header length */ - PACK_STRUCT_FIELD(u8_t _hlen); - /* router alert option type */ - PACK_STRUCT_FIELD(u8_t _ra_opt_type); - /* router alert option data len */ - PACK_STRUCT_FIELD(u8_t _ra_opt_dlen); - /* router alert option data */ - PACK_STRUCT_FIELD(u16_t _ra_opt_data); - /* PadN option type */ - PACK_STRUCT_FIELD(u8_t _padn_opt_type); - /* PadN option data len */ - PACK_STRUCT_FIELD(u8_t _padn_opt_dlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Fragment header. */ -#define IP6_FRAG_HLEN 8 -#define IP6_FRAG_OFFSET_MASK 0xfff8 -#define IP6_FRAG_MORE_FLAG 0x0001 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_frag_hdr { - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* reserved */ - PACK_STRUCT_FIELD(u8_t reserved); - /* fragment offset */ - PACK_STRUCT_FIELD(u16_t _fragment_offset); - /* fragmented packet identification */ - PACK_STRUCT_FIELD(u32_t _identification); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP6H_V(hdr) ((ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) -#define IP6H_TC(hdr) ((ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) -#define IP6H_FL(hdr) (ntohl((hdr)->_v_tc_fl) & 0x000fffff) -#define IP6H_PLEN(hdr) (ntohs((hdr)->_plen)) -#define IP6H_NEXTH(hdr) ((hdr)->_nexth) -#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) -#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) - -#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (htonl(((v) << 28) | ((tc) << 20) | (fl))) -#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = htons(plen) -#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) -#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) - - -#define ip6_init() /* TODO should we init current addresses and header pointer? */ -struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest); -ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest); -err_t ip6_input(struct pbuf *p, struct netif *inp); -err_t ip6_output(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, - u8_t hl, u8_t tc, u8_t nexth); -err_t ip6_output_if(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if LWIP_IPV6_MLD -err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); -#endif /* LWIP_IPV6_MLD */ - -#define ip6_netif_get_local_ipX(netif, dest) (((netif) != NULL) ? \ - ip6_2_ipX(ip6_select_source_address(netif, dest)) : NULL) - -#if IP6_DEBUG -void ip6_debug_print(struct pbuf *p); -#else -#define ip6_debug_print(p) -#endif /* IP6_DEBUG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_addr.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_addr.h deleted file mode 100644 index 89b5b81..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_addr.h +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * Structs and macros for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ -#ifndef __LWIP_IP6_ADDR_H__ -#define __LWIP_IP6_ADDR_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* This is the aligned version of ip6_addr_t, - used as local variable, on the stack, etc. */ -struct ip6_addr { - u32_t addr[4]; -}; - -/* This is the packed version of ip6_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_addr_packed { - PACK_STRUCT_FIELD(u32_t addr[4]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** ip6_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip6_addr_t as well as on ip6_addr_p_t. */ -typedef struct ip6_addr ip6_addr_t; -typedef struct ip6_addr_packed ip6_addr_p_t; - - -/** IP6_ADDR_ANY can be used as a fixed IPv6 address - * for the wildcard - */ -extern const ip6_addr_t ip6_addr_any; -#define IP6_ADDR_ANY ((ip6_addr_t *)&ip6_addr_any) - - - - -#if BYTE_ORDER == BIG_ENDIAN -/** Set an IPv6 partial address given by byte-parts. */ -#define IP6_ADDR(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = ((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff) -#else -/** Set an IPv6 partial address given by byte-parts. -Little-endian version, stored in network order (no htonl). */ -#define IP6_ADDR(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = ((u32_t)((d) & 0xff) << 24) | \ - ((u32_t)((c) & 0xff) << 16) | \ - ((u32_t)((b) & 0xff) << 8) | \ - (u32_t)((a) & 0xff) -#endif - -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0])) & 0xffff) -#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1])) & 0xffff) -#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2])) & 0xffff) -#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3])) & 0xffff) - -/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ -#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3];}while(0) -/** Safely copy one IPv6 address to another (src may be NULL) */ -#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ - (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ - (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ - (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) - -/** Set complete address to zero */ -#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = 0;}while(0) - -/** Set address to ipv6 'any' (no need for htonl()) */ -#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) -/** Set address to ipv6 loopback address */ -#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) -/** Safely copy one IPv6 address to another and change byte order - * from host- to network-order. */ -#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ - (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ - (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ - (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0) - - - -/** - * Determine if two IPv6 address are on the same network. - * - * @arg addr1 IPv6 address 1 - * @arg addr2 IPv6 address 2 - * @return !0 if the network identifiers of both address match - */ -#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1])) - -#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1]) && \ - ((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) - -#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL) - -#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || \ - (((ip6addr)->addr[0] == 0) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == 0) && \ - ((ip6addr)->addr[3] == 0))) - - -#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) - -#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) - -#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) - -#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) - -#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) -#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) -#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) -#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) -#define ip6_addr_multicast_scope(ip6addr) ((htonl((ip6addr)->addr[0]) >> 16) & 0xf) -#define IP6_MULTICAST_SCOPE_RESERVED 0x0 -#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 -#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 -#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 -#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 -#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 -#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 -#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 -#define IP6_MULTICAST_SCOPE_GLOBAL 0xe -#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf -#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff010000UL)) -#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff020000UL)) -#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff040000UL)) -#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff050000UL)) -#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff080000UL)) -#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff0e0000UL)) - -/* TODO define get/set for well-know multicast addresses, e.g. ff02::1 */ -#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) - -#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) -#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) - -#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) - -#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ - (ip6addr)->addr[3] = htonl(0xff000000UL | (htonl(if_id) & 0x00ffffffUL));}while(0) - -#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - ((ip6addr)->addr[3] == htonl(0xff000000UL | (htonl((sn_addr)->addr[3]) & 0x00ffffffUL)))) - -/* IPv6 address states. */ -#define IP6_ADDR_INVALID 0x00 -#define IP6_ADDR_TENTATIVE 0x08 -#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ -#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ -#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ -#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ -#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ -#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ -#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ -#define IP6_ADDR_VALID 0x10 -#define IP6_ADDR_PREFERRED 0x30 -#define IP6_ADDR_DEPRECATED 0x50 - -#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) -#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) -#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ -#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) -#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) - -#define ip6_addr_debug_print(debug, ipaddr) \ - LWIP_DEBUGF(debug, ("%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F, \ - ipaddr != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) - -int ip6addr_aton(const char *cp, ip6_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip6addr_ntoa(const ip6_addr_t *addr); -char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); - - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_ADDR_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_frag.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_frag.h deleted file mode 100644 index 75898b8..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/ip6_frag.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ -#ifndef __LWIP_IP6_FRAG_H__ -#define __LWIP_IP6_FRAG_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - -/* The IPv6 reassembly timer interval in milliseconds. */ -#define IP6_REASS_TMR_INTERVAL 1000 - -/* IPv6 reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip6_reassdata { - struct ip6_reassdata *next; - struct pbuf *p; - struct ip6_hdr * iphdr; - u32_t identification; - u16_t datagram_len; - u8_t nexth; - u8_t timer; -}; - -#define ip6_reass_init() /* Compatibility define */ -void ip6_reass_tmr(void); -struct pbuf * ip6_reass(struct pbuf *p); - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ - -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -#ifndef __LWIP_PBUF_CUSTOM_REF__ -#define __LWIP_PBUF_CUSTOM_REF__ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* __LWIP_PBUF_CUSTOM_REF__ */ - -err_t ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest); - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP6_FRAG_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/mld6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/mld6.h deleted file mode 100644 index abd86e5..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/mld6.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file - * - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#ifndef __LWIP_MLD6_H__ -#define __LWIP_MLD6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6_MLD && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -struct mld_group { - /** next link */ - struct mld_group *next; - /** interface on which the group is active */ - struct netif *netif; - /** multicast address */ - ip6_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/** Multicast listener report/query/done message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mld_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t max_resp_delay); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t multicast_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ - -/* MAC Filter Actions, these are passed to a netif's - * mld_mac_filter callback function. */ -#define MLD6_DEL_MAC_FILTER 0 -#define MLD6_ADD_MAC_FILTER 1 - - -#define mld6_init() /* TODO should we init tables? */ -err_t mld6_stop(struct netif *netif); -void mld6_report_groups(struct netif *netif); -void mld6_tmr(void); -struct mld_group *mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr); -void mld6_input(struct pbuf *p, struct netif *inp); -err_t mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); -err_t mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */ - -#endif /* __LWIP_MLD6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/ipv6/lwip/nd6.h b/external/badvpn_dns/lwip/src/include/ipv6/lwip/nd6.h deleted file mode 100644 index 28636e8..0000000 --- a/external/badvpn_dns/lwip/src/include/ipv6/lwip/nd6.h +++ /dev/null @@ -1,369 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer delamer@inicotech.com - * - * - * Please coordinate changes and requests with Ivan Delamer - * delamer@inicotech.com - */ - -#ifndef __LWIP_ND6_H__ -#define __LWIP_ND6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Struct for tables. */ -struct nd6_neighbor_cache_entry { - ip6_addr_t next_hop_address; - struct netif * netif; - u8_t lladdr[NETIF_MAX_HWADDR_LEN]; - /*u32_t pmtu;*/ -#if LWIP_ND6_QUEUEING - /** Pointer to queue of pending outgoing packets on this entry. */ - struct nd6_q_entry *q; -#else /* LWIP_ND6_QUEUEING */ - /** Pointer to a single pending outgoing packet on this entry. */ - struct pbuf *q; -#endif /* LWIP_ND6_QUEUEING */ - u8_t state; - u8_t isrouter; - union { - u32_t reachable_time; - u32_t delay_time; - u32_t probes_sent; - u32_t stale_time; - } counter; -}; - -struct nd6_destination_cache_entry { - ip6_addr_t destination_addr; - ip6_addr_t next_hop_addr; - u32_t pmtu; - u32_t age; -}; - -struct nd6_prefix_list_entry { - ip6_addr_t prefix; - struct netif * netif; - u32_t invalidation_timer; -#if LWIP_IPV6_AUTOCONFIG - u8_t flags; -#define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01 -#define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02 -#define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04 -#endif /* LWIP_IPV6_AUTOCONFIG */ -}; - -struct nd6_router_list_entry { - struct nd6_neighbor_cache_entry * neighbor_entry; - u32_t invalidation_timer; - u8_t flags; -}; - - -enum nd6_neighbor_cache_entry_state { - ND6_NO_ENTRY = 0, - ND6_INCOMPLETE, - ND6_REACHABLE, - ND6_STALE, - ND6_DELAY, - ND6_PROBE -}; - -#if LWIP_ND6_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct nd6_q_entry { - struct nd6_q_entry *next; - struct pbuf *p; -}; -#endif /* LWIP_ND6_QUEUEING */ - -/** Neighbor solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ns_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Neighbor advertisement message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct na_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u8_t reserved[3]); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define ND6_FLAG_ROUTER (0x80) -#define ND6_FLAG_SOLICITED (0x40) -#define ND6_FLAG_OVERRIDE (0x20) - -/** Router solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rs_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Router advertisement message header. */ -#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) -#define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40) -#define ND6_RA_FLAG_HOME_AGENT (0x20) -#define ND6_RA_PREFERENCE_MASK (0x18) -#define ND6_RA_PREFERENCE_HIGH (0x08) -#define ND6_RA_PREFERENCE_MEDIUM (0x00) -#define ND6_RA_PREFERENCE_LOW (0x18) -#define ND6_RA_PREFERENCE_DISABLED (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ra_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u8_t current_hop_limit); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u16_t router_lifetime); - PACK_STRUCT_FIELD(u32_t reachable_time); - PACK_STRUCT_FIELD(u32_t retrans_timer); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirect message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirect_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - PACK_STRUCT_FIELD(ip6_addr_p_t destination_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Link-layer address option. */ -#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) -#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct lladdr_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t addr[NETIF_MAX_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Prefix information option. */ -#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) -#define ND6_PREFIX_FLAG_ON_LINK (0x80) -#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) -#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) -#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct prefix_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t prefix_length); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u32_t valid_lifetime); - PACK_STRUCT_FIELD(u32_t preferred_lifetime); - PACK_STRUCT_FIELD(u8_t reserved2[3]); - PACK_STRUCT_FIELD(u8_t site_prefix_length); - PACK_STRUCT_FIELD(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirected header option. */ -#define ND6_OPTION_TYPE_REDIR_HDR (0x04) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirected_header_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t reserved[6]); - /* Portion of redirected packet follows. */ - /* PACK_STRUCT_FIELD(u8_t redirected[8]); */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** MTU option. */ -#define ND6_OPTION_TYPE_MTU (0x05) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mtu_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t mtu); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Route information option. */ -#define ND6_OPTION_TYPE_ROUTE_INFO (24) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct route_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t prefix_length); - PACK_STRUCT_FIELD(u8_t preference); - PACK_STRUCT_FIELD(u32_t route_lifetime); - PACK_STRUCT_FIELD(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* the possible states of an IP address */ -#define IP6_ADDRESS_STATE_INVALID (0) -#define IP6_ADDRESS_STATE_VALID (0x4) -#define IP6_ADDRESS_STATE_PREFERRED (0x5) /* includes valid */ -#define IP6_ADDRESS_STATE_DEPRECATED (0x6) /* includes valid */ -#define IP6_ADDRESS_STATE_TENTATIV (0x8) - -/** 1 second period */ -#define ND6_TMR_INTERVAL 1000 - -/* Router tables. */ -/* TODO make these static? and entries accessible through API? */ -extern struct nd6_neighbor_cache_entry neighbor_cache[]; -extern struct nd6_destination_cache_entry destination_cache[]; -extern struct nd6_prefix_list_entry prefix_list[]; -extern struct nd6_router_list_entry default_router_list[]; - -/* Default values, can be updated by a RA message. */ -extern u32_t reachable_time; -extern u32_t retrans_timer; - -#define nd6_init() /* TODO should we init tables? */ -void nd6_tmr(void); -void nd6_input(struct pbuf *p, struct netif *inp); -s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif); -s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif); -u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif); -err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p); -#if LWIP_ND6_TCP_REACHABILITY_HINTS -void nd6_reachability_hint(ip6_addr_t * ip6addr); -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_ND6_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/api.h b/external/badvpn_dns/lwip/src/include/lwip/api.h deleted file mode 100644 index ac58eeb..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/api.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_API_H__ -#define __LWIP_API_H__ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include <stddef.h> /* for size_t */ - -#include "lwip/netbuf.h" -#include "lwip/sys.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ - -/* Flags for netconn_write (u8_t) */ -#define NETCONN_NOFLAG 0x00 -#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ -#define NETCONN_COPY 0x01 -#define NETCONN_MORE 0x02 -#define NETCONN_DONTBLOCK 0x04 - -/* Flags for struct netconn.flags (u8_t) */ -/** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores whether to wake up the original application task - if data couldn't be sent in the first try. */ -#define NETCONN_FLAG_WRITE_DELAYED 0x01 -/** Should this netconn avoid blocking? */ -#define NETCONN_FLAG_NON_BLOCKING 0x02 -/** Was the last connect action a non-blocking one? */ -#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 -/** If this is set, a TCP netconn must call netconn_recved() to update - the TCP receive window (done automatically if not set). */ -#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 -/** If a nonblocking write has been rejected before, poll_tcp needs to - check if the netconn is writable again */ -#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 -#if LWIP_IPV6 -/** If this flag is set then only IPv6 communication is allowed on the - netconn. As per RFC#3493 this features defaults to OFF allowing - dual-stack usage by default. */ -#define NETCONN_FLAG_IPV6_V6ONLY 0x20 -#endif /* LWIP_IPV6 */ - - -/* Helpers to process several netconn_types by the same code */ -#define NETCONNTYPE_GROUP(t) ((t)&0xF0) -#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) -#if LWIP_IPV6 -#define NETCONN_TYPE_IPV6 0x08 -#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) -#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF7) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF7) == NETCONN_UDPNOCHKSUM) -#else /* LWIP_IPV6 */ -#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) -#endif /* LWIP_IPV6 */ - -/** Protocol family and type of the netconn */ -enum netconn_type { - NETCONN_INVALID = 0, - /* NETCONN_TCP Group */ - NETCONN_TCP = 0x10, -#if LWIP_IPV6 - NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, -#endif /* LWIP_IPV6 */ - /* NETCONN_UDP Group */ - NETCONN_UDP = 0x20, - NETCONN_UDPLITE = 0x21, - NETCONN_UDPNOCHKSUM = 0x22, -#if LWIP_IPV6 - NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, - NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, - NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, -#endif /* LWIP_IPV6 */ - /* NETCONN_RAW Group */ - NETCONN_RAW = 0x40 -#if LWIP_IPV6 - , - NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ -#endif /* LWIP_IPV6 */ -}; - -/** Current state of the netconn. Non-TCP netconns are always - * in state NETCONN_NONE! */ -enum netconn_state { - NETCONN_NONE, - NETCONN_WRITE, - NETCONN_LISTEN, - NETCONN_CONNECT, - NETCONN_CLOSE -}; - -/** Use to inform the callback function about changes */ -enum netconn_evt { - NETCONN_EVT_RCVPLUS, - NETCONN_EVT_RCVMINUS, - NETCONN_EVT_SENDPLUS, - NETCONN_EVT_SENDMINUS, - NETCONN_EVT_ERROR -}; - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** Used for netconn_join_leave_group() */ -enum netconn_igmp { - NETCONN_JOIN, - NETCONN_LEAVE -}; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -/* forward-declare some structs to avoid to include their headers */ -struct ip_pcb; -struct tcp_pcb; -struct udp_pcb; -struct raw_pcb; -struct netconn; -struct api_msg_msg; - -/** A callback prototype to inform about events for a netconn */ -typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); - -/** A netconn descriptor */ -struct netconn { - /** type of the netconn (TCP, UDP or RAW) */ - enum netconn_type type; - /** current state of the netconn */ - enum netconn_state state; - /** the lwIP internal protocol control block */ - union { - struct ip_pcb *ip; - struct tcp_pcb *tcp; - struct udp_pcb *udp; - struct raw_pcb *raw; - } pcb; - /** the last error this netconn had */ - err_t last_err; - /** sem that is used to synchroneously execute functions in the core context */ - sys_sem_t op_completed; - /** mbox where received packets are stored until they are fetched - by the netconn application thread (can grow quite big) */ - sys_mbox_t recvmbox; -#if LWIP_TCP - /** mbox where new connections are stored until processed - by the application thread */ - sys_mbox_t acceptmbox; -#endif /* LWIP_TCP */ - /** only used for socket layer */ -#if LWIP_SOCKET - int socket; -#endif /* LWIP_SOCKET */ -#if LWIP_SO_SNDTIMEO - /** timeout to wait for sending data (which means enqueueing data for sending - in internal buffers) */ - s32_t send_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVTIMEO - /** timeout to wait for new data to be received - (or connections to arrive for listening netconns) */ - int recv_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - /** maximum amount of bytes queued in recvmbox - not used for TCP: adjust TCP_WND instead! */ - int recv_bufsize; - /** number of bytes currently in recvmbox to be received, - tested against recv_bufsize to limit bytes on recvmbox - for UDP and RAW, used for FIONREAD */ - s16_t recv_avail; -#endif /* LWIP_SO_RCVBUF */ - /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ - u8_t flags; -#if LWIP_TCP - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores how much is already sent. */ - size_t write_offset; - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores the message. - Also used during connect and close. */ - struct api_msg_msg *current_msg; -#endif /* LWIP_TCP */ - /** A callback function that is informed about events for this netconn */ - netconn_callback callback; -}; - -/** Register an Network connection event */ -#define API_EVENT(c,e,l) if (c->callback) { \ - (*c->callback)(c, e, l); \ - } - -/** Set conn->last_err to err but don't overwrite fatal errors */ -#define NETCONN_SET_SAFE_ERR(conn, err) do { \ - SYS_ARCH_DECL_PROTECT(lev); \ - SYS_ARCH_PROTECT(lev); \ - if (!ERR_IS_FATAL((conn)->last_err)) { \ - (conn)->last_err = err; \ - } \ - SYS_ARCH_UNPROTECT(lev); \ -} while(0); - -/* Network connection functions: */ -#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) -#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) -struct -netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - netconn_callback callback); -err_t netconn_delete(struct netconn *conn); -/** Get the type of a netconn (as enum netconn_type). */ -#define netconn_type(conn) (conn->type) - -err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, - u16_t *port, u8_t local); -#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) -#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) - -err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); -err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); -err_t netconn_disconnect (struct netconn *conn); -err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); -#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) -err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); -err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); -err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); -void netconn_recved(struct netconn *conn, u32_t length); -err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, - ip_addr_t *addr, u16_t port); -err_t netconn_send(struct netconn *conn, struct netbuf *buf); -err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written); -#define netconn_write(conn, dataptr, size, apiflags) \ - netconn_write_partly(conn, dataptr, size, apiflags, NULL) -err_t netconn_close(struct netconn *conn); -err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, - ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if LWIP_DNS -err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); -#endif /* LWIP_DNS */ -#if LWIP_IPV6 - -#define netconn_bind_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_bind(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) -#define netconn_connect_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_connect(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) -#define netconn_sendto_ip6(conn, buf, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_sendto(conn, buf, ip6_2_ip(ip6addr), port) : ERR_VAL) -#if LWIP_IPV6_MLD -#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_join_leave_group(conn, ip6_2_ip(multiaddr), ip6_2_ip(srcaddr), join_or_leave) :\ - ERR_VAL) -#endif /* LWIP_IPV6_MLD*/ -#endif /* LWIP_IPV6 */ - -#define netconn_err(conn) ((conn)->last_err) -#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) - -/** Set the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_set_nonblocking(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) -/** Get the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) - -/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ -#define netconn_set_noautorecved(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) -/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ -#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) - -#if LWIP_SO_SNDTIMEO -/** Set the send timeout in milliseconds */ -#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) -/** Get the send timeout in milliseconds */ -#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO -/** Set the receive timeout in milliseconds */ -#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) -/** Get the receive timeout in milliseconds */ -#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF -/** Set the receive buffer in bytes */ -#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) -/** Get the receive buffer in bytes */ -#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) -#endif /* LWIP_SO_RCVBUF*/ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN */ - -#endif /* __LWIP_API_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/api_msg.h b/external/badvpn_dns/lwip/src/include/lwip/api_msg.h deleted file mode 100644 index 8268036..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/api_msg.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_API_MSG_H__ -#define __LWIP_API_MSG_H__ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include <stddef.h> /* for size_t */ - -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* For the netconn API, these values are use as a bitmask! */ -#define NETCONN_SHUT_RD 1 -#define NETCONN_SHUT_WR 2 -#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) - -/* IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ -/** This struct includes everything that is necessary to execute a function - for a netconn in another thread context (mainly used to process netconns - in the tcpip_thread context to be thread safe). */ -struct api_msg_msg { - /** The netconn which to process - always needed: it includes the semaphore - which is used to block the application thread until the function finished. */ - struct netconn *conn; - /** The return value of the function executed in tcpip_thread. */ - err_t err; - /** Depending on the executed function, one of these union members is used */ - union { - /** used for lwip_netconn_do_send */ - struct netbuf *b; - /** used for lwip_netconn_do_newconn */ - struct { - u8_t proto; - } n; - /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ - struct { - ip_addr_t *ipaddr; - u16_t port; - } bc; - /** used for lwip_netconn_do_getaddr */ - struct { - ipX_addr_t *ipaddr; - u16_t *port; - u8_t local; - } ad; - /** used for lwip_netconn_do_write */ - struct { - const void *dataptr; - size_t len; - u8_t apiflags; -#if LWIP_SO_SNDTIMEO - u32_t time_started; -#endif /* LWIP_SO_SNDTIMEO */ - } w; - /** used for lwip_netconn_do_recv */ - struct { - u32_t len; - } r; - /** used for lwip_netconn_do_close (/shutdown) */ - struct { - u8_t shut; - } sd; -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) - /** used for lwip_netconn_do_join_leave_group */ - struct { - ipX_addr_t *multiaddr; - ipX_addr_t *netif_addr; - enum netconn_igmp join_or_leave; - } jl; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if TCP_LISTEN_BACKLOG - struct { - u8_t backlog; - } lb; -#endif /* TCP_LISTEN_BACKLOG */ - } msg; -}; - -/** This struct contains a function to execute in another thread context and - a struct api_msg_msg that serves as an argument for this function. - This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ -struct api_msg { - /** function to execute in tcpip_thread context */ - void (* function)(struct api_msg_msg *msg); - /** arguments for this function */ - struct api_msg_msg msg; -}; - -#if LWIP_DNS -/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, - it has its own struct (to avoid struct api_msg getting bigger than necessary). - lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg - (see netconn_gethostbyname). */ -struct dns_api_msg { - /** Hostname to query or dotted IP address string */ - const char *name; - /** Rhe resolved address is stored here */ - ip_addr_t *addr; - /** This semaphore is posted when the name is resolved, the application thread - should wait on it. */ - sys_sem_t *sem; - /** Errors are given back here */ - err_t *err; -}; -#endif /* LWIP_DNS */ - -void lwip_netconn_do_newconn ( struct api_msg_msg *msg); -void lwip_netconn_do_delconn ( struct api_msg_msg *msg); -void lwip_netconn_do_bind ( struct api_msg_msg *msg); -void lwip_netconn_do_connect ( struct api_msg_msg *msg); -void lwip_netconn_do_disconnect ( struct api_msg_msg *msg); -void lwip_netconn_do_listen ( struct api_msg_msg *msg); -void lwip_netconn_do_send ( struct api_msg_msg *msg); -void lwip_netconn_do_recv ( struct api_msg_msg *msg); -void lwip_netconn_do_write ( struct api_msg_msg *msg); -void lwip_netconn_do_getaddr ( struct api_msg_msg *msg); -void lwip_netconn_do_close ( struct api_msg_msg *msg); -void lwip_netconn_do_shutdown ( struct api_msg_msg *msg); -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -void lwip_netconn_do_join_leave_group( struct api_msg_msg *msg); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -void lwip_netconn_do_gethostbyname(void *arg); -#endif /* LWIP_DNS */ - -struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); -void netconn_free(struct netconn *conn); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN */ - -#endif /* __LWIP_API_MSG_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/arch.h b/external/badvpn_dns/lwip/src/include/lwip/arch.h deleted file mode 100644 index 4d6df77..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/arch.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_ARCH_H__ -#define __LWIP_ARCH_H__ - -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#include "arch/cc.h" - -/** Temporary: define format string for size_t if not defined in cc.h */ -#ifndef SZT_F -#define SZT_F U32_F -#endif /* SZT_F */ -/** Temporary upgrade helper: define format string for u8_t as hex if not - defined in cc.h */ -#ifndef X8_F -#define X8_F "02x" -#endif /* X8_F */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef PACK_STRUCT_BEGIN -#define PACK_STRUCT_BEGIN -#endif /* PACK_STRUCT_BEGIN */ - -#ifndef PACK_STRUCT_END -#define PACK_STRUCT_END -#endif /* PACK_STRUCT_END */ - -#ifndef PACK_STRUCT_FIELD -#define PACK_STRUCT_FIELD(x) x -#endif /* PACK_STRUCT_FIELD */ - - -#ifndef LWIP_UNUSED_ARG -#define LWIP_UNUSED_ARG(x) (void)x -#endif /* LWIP_UNUSED_ARG */ - - -#ifdef LWIP_PROVIDE_ERRNO - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ - -#ifndef errno -extern int errno; -#endif - -#endif /* LWIP_PROVIDE_ERRNO */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ARCH_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/debug.h b/external/badvpn_dns/lwip/src/include/lwip/debug.h deleted file mode 100644 index 0fe0413..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/debug.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_DEBUG_H__ -#define __LWIP_DEBUG_H__ - -#include "lwip/arch.h" -#include "lwip/opt.h" - -/** lower two bits indicate debug level - * - 0 all - * - 1 warning - * - 2 serious - * - 3 severe - */ -#define LWIP_DBG_LEVEL_ALL 0x00 -#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ -#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ -#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ -#define LWIP_DBG_LEVEL_SEVERE 0x03 -#define LWIP_DBG_MASK_LEVEL 0x03 - -/** flag for LWIP_DEBUGF to enable that debug message */ -#define LWIP_DBG_ON 0x80U -/** flag for LWIP_DEBUGF to disable that debug message */ -#define LWIP_DBG_OFF 0x00U - -/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ -#define LWIP_DBG_TRACE 0x40U -/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ -#define LWIP_DBG_STATE 0x20U -/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ -#define LWIP_DBG_FRESH 0x10U -/** flag for LWIP_DEBUGF to halt after printing this debug message */ -#define LWIP_DBG_HALT 0x08U - -#ifndef LWIP_NOASSERT -#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ - LWIP_PLATFORM_ASSERT(message); } while(0) -#else /* LWIP_NOASSERT */ -#define LWIP_ASSERT(message, assertion) -#endif /* LWIP_NOASSERT */ - -/** if "expression" isn't true, then print "message" and execute "handler" expression */ -#ifndef LWIP_ERROR -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - LWIP_PLATFORM_ASSERT(message); handler;}} while(0) -#endif /* LWIP_ERROR */ - -#ifdef LWIP_DEBUG -/** print debug message only if debug message type is enabled... - * AND is of correct type AND is at least LWIP_DBG_LEVEL - */ -#define LWIP_DEBUGF(debug, message) do { \ - if ( \ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ - LWIP_PLATFORM_DIAG(message); \ - if ((debug) & LWIP_DBG_HALT) { \ - while(1); \ - } \ - } \ - } while(0) - -#else /* LWIP_DEBUG */ -#define LWIP_DEBUGF(debug, message) -#endif /* LWIP_DEBUG */ - -#endif /* __LWIP_DEBUG_H__ */ - diff --git a/external/badvpn_dns/lwip/src/include/lwip/def.h b/external/badvpn_dns/lwip/src/include/lwip/def.h deleted file mode 100644 index 73a1b56..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/def.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_DEF_H__ -#define __LWIP_DEF_H__ - -/* arch.h might define NULL already */ -#include "lwip/arch.h" -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) -#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) - -#ifndef NULL -#define NULL ((void *)0) -#endif - -/* Endianess-optimized shifting of two u8_t to create one u16_t */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define LWIP_MAKE_U16(a, b) ((a << 8) | b) -#else -#define LWIP_MAKE_U16(a, b) ((b << 8) | a) -#endif - -#ifndef LWIP_PLATFORM_BYTESWAP -#define LWIP_PLATFORM_BYTESWAP 0 -#endif - -#ifndef LWIP_PREFIX_BYTEORDER_FUNCS -/* workaround for naming collisions on some platforms */ - -#ifdef htons -#undef htons -#endif /* htons */ -#ifdef htonl -#undef htonl -#endif /* htonl */ -#ifdef ntohs -#undef ntohs -#endif /* ntohs */ -#ifdef ntohl -#undef ntohl -#endif /* ntohl */ - -#define htons(x) lwip_htons(x) -#define ntohs(x) lwip_ntohs(x) -#define htonl(x) lwip_htonl(x) -#define ntohl(x) lwip_ntohl(x) -#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ - -#if BYTE_ORDER == BIG_ENDIAN -#define lwip_htons(x) (x) -#define lwip_ntohs(x) (x) -#define lwip_htonl(x) (x) -#define lwip_ntohl(x) (x) -#define PP_HTONS(x) (x) -#define PP_NTOHS(x) (x) -#define PP_HTONL(x) (x) -#define PP_NTOHL(x) (x) -#else /* BYTE_ORDER != BIG_ENDIAN */ -#if LWIP_PLATFORM_BYTESWAP -#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) -#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) -#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) -#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) -#else /* LWIP_PLATFORM_BYTESWAP */ -u16_t lwip_htons(u16_t x); -u16_t lwip_ntohs(u16_t x); -u32_t lwip_htonl(u32_t x); -u32_t lwip_ntohl(u32_t x); -#endif /* LWIP_PLATFORM_BYTESWAP */ - -/* These macros should be calculated by the preprocessor and are used - with compile-time constants only (so that there is no little-endian - overhead at runtime). */ -#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) -#define PP_NTOHS(x) PP_HTONS(x) -#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ - (((x) & 0xff00) << 8) | \ - (((x) & 0xff0000UL) >> 8) | \ - (((x) & 0xff000000UL) >> 24)) -#define PP_NTOHL(x) PP_HTONL(x) - -#endif /* BYTE_ORDER == BIG_ENDIAN */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_DEF_H__ */ - diff --git a/external/badvpn_dns/lwip/src/include/lwip/dhcp.h b/external/badvpn_dns/lwip/src/include/lwip/dhcp.h deleted file mode 100644 index 32d9338..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/dhcp.h +++ /dev/null @@ -1,242 +0,0 @@ -/** @file - */ - -#ifndef __LWIP_DHCP_H__ -#define __LWIP_DHCP_H__ - -#include "lwip/opt.h" - -#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** period (in seconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_SECS 60 -/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) -/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ -#define DHCP_FINE_TIMER_MSECS 500 - -#define DHCP_CHADDR_LEN 16U -#define DHCP_SNAME_LEN 64U -#define DHCP_FILE_LEN 128U - -struct dhcp -{ - /** transaction identifier of last sent request */ - u32_t xid; - /** our connection to the DHCP server */ - struct udp_pcb *pcb; - /** incoming msg */ - struct dhcp_msg *msg_in; - /** current DHCP state machine state */ - u8_t state; - /** retries of current request */ - u8_t tries; -#if LWIP_DHCP_AUTOIP_COOP - u8_t autoip_coop_state; -#endif - u8_t subnet_mask_given; - - struct pbuf *p_out; /* pbuf of outcoming msg */ - struct dhcp_msg *msg_out; /* outgoing msg */ - u16_t options_out_len; /* outgoing msg options length */ - u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ - u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ - u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ - ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ - ip_addr_t offered_ip_addr; - ip_addr_t offered_sn_mask; - ip_addr_t offered_gw_addr; - - u32_t offered_t0_lease; /* lease period (in seconds) */ - u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ - u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ - /* @todo: LWIP_DHCP_BOOTP_FILE configuration option? - integrate with possible TFTP-client for booting? */ -#if LWIP_DHCP_BOOTP_FILE - ip_addr_t offered_si_addr; - char boot_file_name[DHCP_FILE_LEN]; -#endif /* LWIP_DHCP_BOOTPFILE */ -}; - -/* MUST be compiled with "pack structs" or equivalent! */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** minimum set of fields of any DHCP message */ -struct dhcp_msg -{ - PACK_STRUCT_FIELD(u8_t op); - PACK_STRUCT_FIELD(u8_t htype); - PACK_STRUCT_FIELD(u8_t hlen); - PACK_STRUCT_FIELD(u8_t hops); - PACK_STRUCT_FIELD(u32_t xid); - PACK_STRUCT_FIELD(u16_t secs); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); - PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); - PACK_STRUCT_FIELD(ip_addr_p_t siaddr); - PACK_STRUCT_FIELD(ip_addr_p_t giaddr); - PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); - PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); - PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); - PACK_STRUCT_FIELD(u32_t cookie); -#define DHCP_MIN_OPTIONS_LEN 68U -/** make sure user does not configure this too small */ -#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) -# undef DHCP_OPTIONS_LEN -#endif -/** allow this to be configured in lwipopts.h, but not too small */ -#if (!defined(DHCP_OPTIONS_LEN)) -/** set this to be sufficient for your options in outgoing DHCP msgs */ -# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN -#endif - PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); -/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ -#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) -void dhcp_cleanup(struct netif *netif); -/** start DHCP configuration */ -err_t dhcp_start(struct netif *netif); -/** enforce early lease renewal (not needed normally)*/ -err_t dhcp_renew(struct netif *netif); -/** release the DHCP lease, usually called before dhcp_stop()*/ -err_t dhcp_release(struct netif *netif); -/** stop DHCP configuration */ -void dhcp_stop(struct netif *netif); -/** inform server of our manual IP address */ -void dhcp_inform(struct netif *netif); -/** Handle a possible change in the network configuration */ -void dhcp_network_changed(struct netif *netif); - -/** if enabled, check whether the offered IP address is not in use, using ARP */ -#if DHCP_DOES_ARP_CHECK -void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); -#endif - -/** to be called every minute */ -void dhcp_coarse_tmr(void); -/** to be called every half second */ -void dhcp_fine_tmr(void); - -/** DHCP message item offsets and length */ -#define DHCP_OP_OFS 0 -#define DHCP_HTYPE_OFS 1 -#define DHCP_HLEN_OFS 2 -#define DHCP_HOPS_OFS 3 -#define DHCP_XID_OFS 4 -#define DHCP_SECS_OFS 8 -#define DHCP_FLAGS_OFS 10 -#define DHCP_CIADDR_OFS 12 -#define DHCP_YIADDR_OFS 16 -#define DHCP_SIADDR_OFS 20 -#define DHCP_GIADDR_OFS 24 -#define DHCP_CHADDR_OFS 28 -#define DHCP_SNAME_OFS 44 -#define DHCP_FILE_OFS 108 -#define DHCP_MSG_LEN 236 - -#define DHCP_COOKIE_OFS DHCP_MSG_LEN -#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) - -#define DHCP_CLIENT_PORT 68 -#define DHCP_SERVER_PORT 67 - -/** DHCP client states */ -#define DHCP_OFF 0 -#define DHCP_REQUESTING 1 -#define DHCP_INIT 2 -#define DHCP_REBOOTING 3 -#define DHCP_REBINDING 4 -#define DHCP_RENEWING 5 -#define DHCP_SELECTING 6 -#define DHCP_INFORMING 7 -#define DHCP_CHECKING 8 -#define DHCP_PERMANENT 9 -#define DHCP_BOUND 10 -/** not yet implemented #define DHCP_RELEASING 11 */ -#define DHCP_BACKING_OFF 12 - -/** AUTOIP cooperatation flags */ -#define DHCP_AUTOIP_COOP_STATE_OFF 0 -#define DHCP_AUTOIP_COOP_STATE_ON 1 - -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 - -/** DHCP message types */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 - -/** DHCP hardware type, currently only ethernet is supported */ -#define DHCP_HTYPE_ETH 1 - -#define DHCP_MAGIC_COOKIE 0x63825363UL - -/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ - -/** BootP options */ -#define DHCP_OPTION_PAD 0 -#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_HOSTNAME 12 -#define DHCP_OPTION_IP_TTL 23 -#define DHCP_OPTION_MTU 26 -#define DHCP_OPTION_BROADCAST 28 -#define DHCP_OPTION_TCP_TTL 37 -#define DHCP_OPTION_END 255 - -/** DHCP options */ -#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ -#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ -#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ - -#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ -#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 - -#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ -#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ - -#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ -#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 - -#define DHCP_OPTION_T1 58 /* T1 renewal time */ -#define DHCP_OPTION_T2 59 /* T2 rebinding time */ -#define DHCP_OPTION_US 60 -#define DHCP_OPTION_CLIENT_ID 61 -#define DHCP_OPTION_TFTP_SERVERNAME 66 -#define DHCP_OPTION_BOOTFILE 67 - -/** possible combinations of overloading the file and sname fields with options */ -#define DHCP_OVERLOAD_NONE 0 -#define DHCP_OVERLOAD_FILE 1 -#define DHCP_OVERLOAD_SNAME 2 -#define DHCP_OVERLOAD_SNAME_FILE 3 - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DHCP */ - -#endif /*__LWIP_DHCP_H__*/ diff --git a/external/badvpn_dns/lwip/src/include/lwip/dns.h b/external/badvpn_dns/lwip/src/include/lwip/dns.h deleted file mode 100644 index 6c7d9b0..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/dns.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * lwip DNS resolver header file. - - * Author: Jim Pettinato - * April 2007 - - * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __LWIP_DNS_H__ -#define __LWIP_DNS_H__ - -#include "lwip/opt.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS timer period */ -#define DNS_TMR_INTERVAL 1000 - -/** DNS field TYPE used for "Resource Records" */ -#define DNS_RRTYPE_A 1 /* a host address */ -#define DNS_RRTYPE_NS 2 /* an authoritative name server */ -#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ -#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ -#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ -#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ -#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ -#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ -#define DNS_RRTYPE_WKS 11 /* a well known service description */ -#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ -#define DNS_RRTYPE_HINFO 13 /* host information */ -#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ -#define DNS_RRTYPE_MX 15 /* mail exchange */ -#define DNS_RRTYPE_TXT 16 /* text strings */ - -/** DNS field CLASS used for "Resource Records" */ -#define DNS_RRCLASS_IN 1 /* the Internet */ -#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ -#define DNS_RRCLASS_CH 3 /* the CHAOS class */ -#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ -#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ - -/* The size used for the next line is rather a hack, but it prevents including socket.h in all files - that include memp.h, and that would possibly break portability (since socket.h defines some types - and constants possibly already define by the OS). - Calculation rule: - sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */ -#define NETDB_ELEM_SIZE (32 + 16 + DNS_MAX_NAME_LENGTH + 1) - -#if DNS_LOCAL_HOSTLIST -/** struct used for local host-list */ -struct local_hostlist_entry { - /** static hostname */ - const char *name; - /** static host address in network byteorder */ - ip_addr_t addr; - struct local_hostlist_entry *next; -}; -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN -#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH -#endif -#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** Callback which is invoked when a hostname is found. - * A function of this type must be implemented by the application using the DNS resolver. - * @param name pointer to the name that was looked up. - * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, - * or NULL if the name could not be found (or on any other error). - * @param callback_arg a user-specified callback argument passed to dns_gethostbyname -*/ -typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); - -void dns_init(void); -void dns_tmr(void); -void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); -ip_addr_t dns_getserver(u8_t numdns); -err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, - dns_found_callback found, void *callback_arg); - -#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -int dns_local_removehost(const char *hostname, const ip_addr_t *addr); -err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); -#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS */ - -#endif /* __LWIP_DNS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/err.h b/external/badvpn_dns/lwip/src/include/lwip/err.h deleted file mode 100644 index ac90772..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/err.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_ERR_H__ -#define __LWIP_ERR_H__ - -#include "lwip/opt.h" -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Define LWIP_ERR_T in cc.h if you want to use - * a different type for your platform (must be signed). */ -#ifdef LWIP_ERR_T -typedef LWIP_ERR_T err_t; -#else /* LWIP_ERR_T */ -typedef s8_t err_t; -#endif /* LWIP_ERR_T*/ - -/* Definitions for error constants. */ - -#define ERR_OK 0 /* No error, everything OK. */ -#define ERR_MEM -1 /* Out of memory error. */ -#define ERR_BUF -2 /* Buffer error. */ -#define ERR_TIMEOUT -3 /* Timeout. */ -#define ERR_RTE -4 /* Routing problem. */ -#define ERR_INPROGRESS -5 /* Operation in progress */ -#define ERR_VAL -6 /* Illegal value. */ -#define ERR_WOULDBLOCK -7 /* Operation would block. */ -#define ERR_USE -8 /* Address in use. */ -#define ERR_ISCONN -9 /* Already connected. */ - -#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) - -#define ERR_ABRT -10 /* Connection aborted. */ -#define ERR_RST -11 /* Connection reset. */ -#define ERR_CLSD -12 /* Connection closed. */ -#define ERR_CONN -13 /* Not connected. */ - -#define ERR_ARG -14 /* Illegal argument. */ - -#define ERR_IF -15 /* Low-level netif error */ - - -#ifdef LWIP_DEBUG -extern const char *lwip_strerr(err_t err); -#else -#define lwip_strerr(x) "" -#endif /* LWIP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ERR_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/inet_chksum.h b/external/badvpn_dns/lwip/src/include/lwip/inet_chksum.h deleted file mode 100644 index e168788..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/inet_chksum.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_INET_CHKSUM_H__ -#define __LWIP_INET_CHKSUM_H__ - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -/** Swap the bytes in an u16_t: much like htons() for little-endian */ -#ifndef SWAP_BYTES_IN_WORD -#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) -/* little endian and PLATFORM_BYTESWAP defined */ -#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) -#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ -/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ -#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) -#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ -#endif /* SWAP_BYTES_IN_WORD */ - -/** Split an u32_t in two u16_ts and add them up */ -#ifndef FOLD_U32T -#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) -#endif - -#if LWIP_CHECKSUM_ON_COPY -/** Function-like macro: same as MEMCPY but returns the checksum of copied data - as u16_t */ -#ifndef LWIP_CHKSUM_COPY -#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) -#ifndef LWIP_CHKSUM_COPY_ALGORITHM -#define LWIP_CHKSUM_COPY_ALGORITHM 1 -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ -#endif /* LWIP_CHKSUM_COPY */ -#else /* LWIP_CHECKSUM_ON_COPY */ -#define LWIP_CHKSUM_COPY_ALGORITHM 0 -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -extern "C" { -#endif - -u16_t inet_chksum(void *dataptr, u16_t len); -u16_t inet_chksum_pbuf(struct pbuf *p); -u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip_addr_t *src, ip_addr_t *dest); -u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, - u16_t proto_len, u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest); -#if LWIP_CHKSUM_COPY_ALGORITHM -u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ - -#if LWIP_IPV6 -u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip6_addr_t *src, ip6_addr_t *dest); -u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest); - -#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ - ((isipv6) ? \ - ip6_chksum_pseudo(p, proto, proto_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ - inet_chksum_pseudo(p, proto, proto_len, ipX_2_ip(src), ipX_2_ip(dest))) -#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ - ((isipv6) ? \ - ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ - inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip(src), ipX_2_ip(dest))) - -#else /* LWIP_IPV6 */ - -#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ - inet_chksum_pseudo(p, proto, proto_len, src, dest) -#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ - inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, src, dest) - -#endif /* LWIP_IPV6 */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INET_H__ */ - diff --git a/external/badvpn_dns/lwip/src/include/lwip/init.h b/external/badvpn_dns/lwip/src/include/lwip/init.h deleted file mode 100644 index 4e2e285..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/init.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_INIT_H__ -#define __LWIP_INIT_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** X.x.x: Major version of the stack */ -#define LWIP_VERSION_MAJOR 1U -/** x.X.x: Minor version of the stack */ -#define LWIP_VERSION_MINOR 4U -/** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 1U -/** For release candidates, this is set to 1..254 - * For official releases, this is set to 255 (LWIP_RC_RELEASE) - * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC 0U - -/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ -#define LWIP_RC_RELEASE 255U -/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ -#define LWIP_RC_DEVELOPMENT 0U - -#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) -#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) -#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) - -/** Provides the version of the stack */ -#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ - LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) - -/* Modules initialization */ -void lwip_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INIT_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/ip.h b/external/badvpn_dns/lwip/src/include/lwip/ip.h deleted file mode 100644 index a0cd1d4..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/ip.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_IP_H__ -#define __LWIP_IP_H__ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is passed as the destination address to ip_output_if (not - to ip_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#ifdef IP_HDRINCL -#undef IP_HDRINCL -#endif /* IP_HDRINCL */ -#define IP_HDRINCL NULL - -#if LWIP_NETIF_HWADDRHINT -#define IP_PCB_ADDRHINT ;u8_t addr_hint -#else -#define IP_PCB_ADDRHINT -#endif /* LWIP_NETIF_HWADDRHINT */ - -#if LWIP_IPV6 -#define IP_PCB_ISIPV6_MEMBER u8_t isipv6; -#define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) -#define IP_PCB_IPVER_INPUT_MATCH(pcb) (ip_current_is_v6() ? \ - ((pcb)->isipv6 != 0) : \ - ((pcb)->isipv6 == 0)) -#define PCB_ISIPV6(pcb) ((pcb)->isipv6) -#else -#define IP_PCB_ISIPV6_MEMBER -#define IP_PCB_IPVER_EQ(pcb1, pcb2) 1 -#define IP_PCB_IPVER_INPUT_MATCH(pcb) 1 -#define PCB_ISIPV6(pcb) 0 -#endif /* LWIP_IPV6 */ - -/* This is the common part of all PCB types. It needs to be at the - beginning of a PCB type definition. It is located here so that - changes to this common part are made in one location instead of - having to change all PCB structs. */ -#define IP_PCB \ - IP_PCB_ISIPV6_MEMBER \ - /* ip addresses in network byte order */ \ - ipX_addr_t local_ip; \ - ipX_addr_t remote_ip; \ - /* Socket options */ \ - u8_t so_options; \ - /* Type Of Service */ \ - u8_t tos; \ - /* Time To Live */ \ - u8_t ttl \ - /* link layer address resolution hint */ \ - IP_PCB_ADDRHINT - -struct ip_pcb { -/* Common members of all PCB types */ - IP_PCB; -}; - -/* - * Option flags per-socket. These are the same like SO_XXX. - */ -/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ -#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ -#define SOF_REUSEADDR 0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE 0x08U /* keep connections alive */ -/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ -#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ -#define SOF_LINGER 0x80U /* linger on close if data present */ -/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ -/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ - -/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ -#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) - -/* Global variables of this module, kept in a struct for efficient access using base+index. */ -struct ip_globals -{ - /** The interface that provided the packet for the current callback invocation. */ - struct netif *current_netif; - /** Header of the input packet currently being processed. */ - const struct ip_hdr *current_ip4_header; -#if LWIP_IPV6 - /** Header of the input IPv6 packet currently being processed. */ - const struct ip6_hdr *current_ip6_header; -#endif /* LWIP_IPV6 */ - /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ - u16_t current_ip_header_tot_len; - /** Source IP address of current_header */ - ipX_addr_t current_iphdr_src; - /** Destination IP address of current_header */ - ipX_addr_t current_iphdr_dest; -}; -extern struct ip_globals ip_data; - - -/** Get the interface that received the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_netif() (ip_data.current_netif) -/** Get the IP header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_header() (ip_data.current_ip4_header) -/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ -#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) -/** Source IP address of current_header */ -#define ipX_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP address of current_header */ -#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) - -#if LWIP_IPV6 -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() (ip_data.current_ip6_header) -/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ -#define ip_current_is_v6() (ip6_current_header() != NULL) -/** Source IPv6 address of current_header */ -#define ip6_current_src_addr() (ipX_2_ip6(&ip_data.current_iphdr_src)) -/** Destination IPv6 address of current_header */ -#define ip6_current_dest_addr() (ipX_2_ip6(&ip_data.current_iphdr_dest)) -/** Get the transport layer protocol */ -#define ip_current_header_proto() (ip_current_is_v6() ? \ - IP6H_NEXTH(ip6_current_header()) :\ - IPH_PROTO(ip_current_header())) -/** Get the transport layer header */ -#define ipX_next_header_ptr() ((void*)((ip_current_is_v6() ? \ - (u8_t*)ip6_current_header() : (u8_t*)ip_current_header()) + ip_current_header_tot_len())) - -/** Set an IP_PCB to IPv6 (IPv4 is the default) */ -#define ip_set_v6(pcb, val) do{if(pcb != NULL) { pcb->isipv6 = val; }}while(0) - -/** Source IP4 address of current_header */ -#define ip_current_src_addr() (ipX_2_ip(&ip_data.current_iphdr_src)) -/** Destination IP4 address of current_header */ -#define ip_current_dest_addr() (ipX_2_ip(&ip_data.current_iphdr_dest)) - -#else /* LWIP_IPV6 */ - -/** Always returns FALSE when only supporting IPv4 */ -#define ip_current_is_v6() 0 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IPH_PROTO(ip_current_header()) -/** Get the transport layer header */ -#define ipX_next_header_ptr() ((void*)((u8_t*)ip_current_header() + ip_current_header_tot_len())) -/** Source IP4 address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP4 address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -#endif /* LWIP_IPV6 */ - -/** Union source address of current_header */ -#define ipX_current_src_addr() (&ip_data.current_iphdr_src) -/** Union destination address of current_header */ -#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) - -/** Gets an IP pcb option (SOF_* flags) */ -#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) -/** Sets an IP pcb option (SOF_* flags) */ -#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) -/** Resets an IP pcb option (SOF_* flags) */ -#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) - -#if LWIP_IPV6 -#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ - ((isipv6) ? \ - ip6_output(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto) : \ - ip_output(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto)) -#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ - ((isipv6) ? \ - ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip_output_if(p, (src), (dest), ttl, tos, proto, netif)) -#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ - ((isipv6) ? \ - ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ - ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) -#define ipX_route(isipv6, src, dest) \ - ((isipv6) ? \ - ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \ - ip_route(ipX_2_ip(dest))) -#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ - ((isipv6) ? \ - ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \ - ip_netif_get_local_ipX(netif)) -#define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) -#else /* LWIP_IPV6 */ -#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ - ip_output(p, src, dest, ttl, tos, proto) -#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ - ip_output_if(p, src, dest, ttl, tos, proto, netif) -#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ - ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) -#define ipX_route(isipv6, src, dest) \ - ip_route(ipX_2_ip(dest)) -#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ - ip_netif_get_local_ipX(netif) -#define ipX_debug_print(is_ipv6, p) ip_debug_print(p) -#endif /* LWIP_IPV6 */ - -#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \ - (netif) = ipX_route(isipv6, src, dest); \ - (ipXaddr) = ipX_netif_get_local_ipX(isipv6, netif, dest); \ -}while(0) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_H__ */ - - diff --git a/external/badvpn_dns/lwip/src/include/lwip/ip_addr.h b/external/badvpn_dns/lwip/src/include/lwip/ip_addr.h deleted file mode 100644 index 7bd03cb..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/ip_addr.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_IP_ADDR_H__ -#define __LWIP_IP_ADDR_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include "lwip/ip4_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_IPV6 -/* A union struct for both IP version's addresses. */ -typedef union { - ip_addr_t ip4; - ip6_addr_t ip6; -} ipX_addr_t; - -/** These functions only exist for type-safe conversion from ip_addr_t to - ip6_addr_t and back */ -#ifdef LWIP_ALLOW_STATIC_FN_IN_HEADER -static ip6_addr_t* ip_2_ip6(ip_addr_t *ipaddr) -{ return (ip6_addr_t*)ipaddr;} -static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) -{ return (ip_addr_t*)ip6addr; } -static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) -{ return (ipX_addr_t*)ipaddr; } -static ipX_addr_t* ip6_2_ipX(ip6_addr_t *ip6addr) -{ return (ipX_addr_t*)ip6addr; } -#else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ -#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) -#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) -#define ip_2_ipX(ipaddr) ((ipX_addr_t*)ipaddr) -#define ip6_2_ipX(ip6addr) ((ipX_addr_t*)ip6addr) -#endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ -#define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) -#define ipX_2_ip(ipaddr) (&((ipaddr)->ip4)) - -#define ipX_addr_copy(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_copy((dest).ip6, (src).ip6); }else{ \ - ip_addr_copy((dest).ip4, (src).ip4); }}while(0) -#define ipX_addr_set(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set(ipX_2_ip6(dest), ipX_2_ip6(src)); }else{ \ - ip_addr_set(ipX_2_ip(dest), ipX_2_ip(src)); }}while(0) -#define ipX_addr_set_ipaddr(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set(ipX_2_ip6(dest), ip_2_ip6(src)); }else{ \ - ip_addr_set(ipX_2_ip(dest), src); }}while(0) -#define ipX_addr_set_zero(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_zero(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_zero(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_any(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_any(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_loopback(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_loopback(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_hton(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set_hton(ipX_2_ip6(ipaddr), (src)) ;}else{ \ - ip_addr_set_hton(ipX_2_ip(ipaddr), (src));}}while(0) -#define ipX_addr_cmp(is_ipv6, addr1, addr2) ((is_ipv6) ? \ - ip6_addr_cmp(ipX_2_ip6(addr1), ipX_2_ip6(addr2)) : \ - ip_addr_cmp(ipX_2_ip(addr1), ipX_2_ip(addr2))) -#define ipX_addr_isany(is_ipv6, ipaddr) ((is_ipv6) ? \ - ip6_addr_isany(ipX_2_ip6(ipaddr)) : \ - ip_addr_isany(ipX_2_ip(ipaddr))) -#define ipX_addr_ismulticast(is_ipv6, ipaddr) ((is_ipv6) ? \ - ip6_addr_ismulticast(ipX_2_ip6(ipaddr)) : \ - ip_addr_ismulticast(ipX_2_ip(ipaddr))) -#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) do { if(is_ipv6) { \ - ip6_addr_debug_print(debug, ipX_2_ip6(ipaddr)); } else { \ - ip_addr_debug_print(debug, ipX_2_ip(ipaddr)); }}while(0) - -#else /* LWIP_IPV6 */ - -typedef ip_addr_t ipX_addr_t; -#define ipX_2_ip(ipaddr) (ipaddr) -#define ip_2_ipX(ipaddr) (ipaddr) - -#define ipX_addr_copy(is_ipv6, dest, src) ip_addr_copy(dest, src) -#define ipX_addr_set(is_ipv6, dest, src) ip_addr_set(dest, src) -#define ipX_addr_set_ipaddr(is_ipv6, dest, src) ip_addr_set(dest, src) -#define ipX_addr_set_zero(is_ipv6, ipaddr) ip_addr_set_zero(ipaddr) -#define ipX_addr_set_any(is_ipv6, ipaddr) ip_addr_set_any(ipaddr) -#define ipX_addr_set_loopback(is_ipv6, ipaddr) ip_addr_set_loopback(ipaddr) -#define ipX_addr_set_hton(is_ipv6, dest, src) ip_addr_set_hton(dest, src) -#define ipX_addr_cmp(is_ipv6, addr1, addr2) ip_addr_cmp(addr1, addr2) -#define ipX_addr_isany(is_ipv6, ipaddr) ip_addr_isany(ipaddr) -#define ipX_addr_ismulticast(is_ipv6, ipaddr) ip_addr_ismulticast(ipaddr) -#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) ip_addr_debug_print(debug, ipaddr) - -#endif /* LWIP_IPV6 */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/mem.h b/external/badvpn_dns/lwip/src/include/lwip/mem.h deleted file mode 100644 index 5bb906b..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/mem.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_MEM_H__ -#define __LWIP_MEM_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if MEM_LIBC_MALLOC - -#include <stddef.h> /* for size_t */ - -typedef size_t mem_size_t; -#define MEM_SIZE_F SZT_F - -/* aliases for C library malloc() */ -#define mem_init() -/* in case C library malloc() needs extra protection, - * allow these defines to be overridden. - */ -#ifndef mem_free -#define mem_free free -#endif -#ifndef mem_malloc -#define mem_malloc malloc -#endif -#ifndef mem_calloc -#define mem_calloc calloc -#endif -/* Since there is no C library allocation function to shrink memory without - moving it, define this to nothing. */ -#ifndef mem_trim -#define mem_trim(mem, size) (mem) -#endif -#else /* MEM_LIBC_MALLOC */ - -/* MEM_SIZE would have to be aligned, but using 64000 here instead of - * 65535 leaves some room for alignment... - */ -#if MEM_SIZE > 64000L -typedef u32_t mem_size_t; -#define MEM_SIZE_F U32_F -#else -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F -#endif /* MEM_SIZE > 64000 */ - -#if MEM_USE_POOLS -/** mem_init is not used when using pools instead of a heap */ -#define mem_init() -/** mem_trim is not used when using pools instead of a heap: - we can't free part of a pool element and don't want to copy the rest */ -#define mem_trim(mem, size) (mem) -#else /* MEM_USE_POOLS */ -/* lwIP alternative malloc */ -void mem_init(void); -void *mem_trim(void *mem, mem_size_t size); -#endif /* MEM_USE_POOLS */ -void *mem_malloc(mem_size_t size); -void *mem_calloc(mem_size_t count, mem_size_t size); -void mem_free(void *mem); -#endif /* MEM_LIBC_MALLOC */ - -/** Calculate memory size for an aligned buffer - returns the next highest - * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and - * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). - */ -#ifndef LWIP_MEM_ALIGN_SIZE -#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) -#endif - -/** Calculate safe memory size for an aligned buffer when using an unaligned - * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the - * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) - */ -#ifndef LWIP_MEM_ALIGN_BUFFER -#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1)) -#endif - -/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT - * so that ADDR % MEM_ALIGNMENT == 0 - */ -#ifndef LWIP_MEM_ALIGN -#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_MEM_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/memp.h b/external/badvpn_dns/lwip/src/include/lwip/memp.h deleted file mode 100644 index f0d0739..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/memp.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#ifndef __LWIP_MEMP_H__ -#define __LWIP_MEMP_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ -typedef enum { -#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, -#include "lwip/memp_std.h" - MEMP_MAX -} memp_t; - -#if MEM_USE_POOLS -/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ -typedef enum { - /* Get the first (via: - MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ - MEMP_POOL_HELPER_FIRST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START 1 -#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 -#define LWIP_MALLOC_MEMPOOL_END -#include "lwip/memp_std.h" - ) , - /* Get the last (via: - MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ - MEMP_POOL_HELPER_LAST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * -#define LWIP_MALLOC_MEMPOOL_END 1 -#include "lwip/memp_std.h" - ) -} memp_pool_helper_t; - -/* The actual start and stop values are here (cast them over) - We use this helper type and these defines so we can avoid using const memp_t values */ -#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) -#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) -#endif /* MEM_USE_POOLS */ - -#if MEMP_MEM_MALLOC || MEM_USE_POOLS -extern const u16_t memp_sizes[MEMP_MAX]; -#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ - -#if MEMP_MEM_MALLOC - -#include "mem.h" - -#define memp_init() -#define memp_malloc(type) mem_malloc(memp_sizes[type]) -#define memp_free(type, mem) mem_free(mem) - -#else /* MEMP_MEM_MALLOC */ - -#if MEM_USE_POOLS -/** This structure is used to save the pool one element came from. */ -struct memp_malloc_helper -{ - memp_t poolnr; -}; -#endif /* MEM_USE_POOLS */ - -void memp_init(void); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_fn(memp_t type, const char* file, const int line); -#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) -#else -void *memp_malloc(memp_t type); -#endif -void memp_free(memp_t type, void *mem); - -#endif /* MEMP_MEM_MALLOC */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_MEMP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/memp_std.h b/external/badvpn_dns/lwip/src/include/lwip/memp_std.h deleted file mode 100644 index 592a282..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/memp_std.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * SETUP: Make sure we define everything we will need. - * - * We have create three types of pools: - * 1) MEMPOOL - standard pools - * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c - * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct - * - * If the include'r doesn't require any special treatment of each of the types - * above, then will declare #2 & #3 to be just standard mempools. - */ -#ifndef LWIP_MALLOC_MEMPOOL -/* This treats "malloc pools" just like any other pool. - The pools are a little bigger to provide 'size' as the amount of user data. */ -#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL_END -#endif /* LWIP_MALLOC_MEMPOOL */ - -#ifndef LWIP_PBUF_MEMPOOL -/* This treats "pbuf pools" just like any other pool. - * Allocates buffers for a pbuf struct AND a payload size */ -#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) -#endif /* LWIP_PBUF_MEMPOOL */ - - -/* - * A list of internal pools used by LWIP. - * - * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - */ -#if LWIP_RAW -LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") -#endif /* LWIP_RAW */ - -#if LWIP_UDP -LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") -#endif /* LWIP_UDP */ - -#if LWIP_TCP -LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") -LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") -LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") -#endif /* LWIP_TCP */ - -#if IP_REASSEMBLY -LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") -#endif /* IP_REASSEMBLY */ -#if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPV6_FRAG -LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") -#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ - -#if LWIP_NETCONN -LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") -LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") -#endif /* LWIP_NETCONN */ - -#if NO_SYS==0 -LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") -#if !LWIP_TCPIP_CORE_LOCKING_INPUT -LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ -#endif /* NO_SYS==0 */ - -#if LWIP_ARP && ARP_QUEUEING -LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") -#endif /* LWIP_ARP && ARP_QUEUEING */ - -#if LWIP_IGMP -LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") -#endif /* LWIP_IGMP */ - -#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ -LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") -#endif /* LWIP_TIMERS */ - -#if LWIP_SNMP -LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") -LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") -LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") -LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") -#endif /* LWIP_SNMP */ -#if LWIP_DNS && LWIP_SOCKET -LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") -#endif /* LWIP_DNS && LWIP_SOCKET */ -#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") -#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#if PPP_SUPPORT && PPPOE_SUPPORT -LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ - -#if LWIP_IPV6 && LWIP_ND6_QUEUEING -LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") -#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ - -#if LWIP_IPV6 && LWIP_IPV6_REASS -LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_MLD -LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - -/* - * A list of pools of pbuf's used by LWIP. - * - * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - * This allocates enough space for the pbuf struct and a payload. - * (Example: pbuf_payload_size=0 allocates only size for the struct) - */ -LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") -LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") - - -/* - * Allow for user-defined pools; this must be explicitly set in lwipopts.h - * since the default is to NOT look for lwippools.h - */ -#if MEMP_USE_CUSTOM_POOLS -#include "lwippools.h" -#endif /* MEMP_USE_CUSTOM_POOLS */ - -/* - * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later - * (#undef is ignored for something that is not defined) - */ -#undef LWIP_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL_START -#undef LWIP_MALLOC_MEMPOOL_END -#undef LWIP_PBUF_MEMPOOL diff --git a/external/badvpn_dns/lwip/src/include/lwip/netbuf.h b/external/badvpn_dns/lwip/src/include/lwip/netbuf.h deleted file mode 100644 index d12fe27..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/netbuf.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_NETBUF_H__ -#define __LWIP_NETBUF_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This netbuf has dest-addr/port set */ -#define NETBUF_FLAG_DESTADDR 0x01 -/** This netbuf includes a checksum */ -#define NETBUF_FLAG_CHKSUM 0x02 - -struct netbuf { - struct pbuf *p, *ptr; - ipX_addr_t addr; - u16_t port; -#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY -#if LWIP_CHECKSUM_ON_COPY - u8_t flags; -#endif /* LWIP_CHECKSUM_ON_COPY */ - u16_t toport_chksum; -#if LWIP_NETBUF_RECVINFO - ipX_addr_t toaddr; -#endif /* LWIP_NETBUF_RECVINFO */ -#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ -}; - -/* Network buffer functions: */ -struct netbuf * netbuf_new (void); -void netbuf_delete (struct netbuf *buf); -void * netbuf_alloc (struct netbuf *buf, u16_t size); -void netbuf_free (struct netbuf *buf); -err_t netbuf_ref (struct netbuf *buf, - const void *dataptr, u16_t size); -void netbuf_chain (struct netbuf *head, - struct netbuf *tail); - -err_t netbuf_data (struct netbuf *buf, - void **dataptr, u16_t *len); -s8_t netbuf_next (struct netbuf *buf); -void netbuf_first (struct netbuf *buf); - - -#define netbuf_copy_partial(buf, dataptr, len, offset) \ - pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) -#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) -#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) -#define netbuf_len(buf) ((buf)->p->tot_len) -#define netbuf_fromaddr(buf) (ipX_2_ip(&((buf)->addr))) -#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(ipX_2_ip(&((buf)->addr)), fromaddr) -#define netbuf_fromport(buf) ((buf)->port) -#if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) (ipX_2_ip(&((buf)->toaddr))) -#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(ipX_2_ip(&((buf)->toaddr)), destaddr) -#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) -#endif /* LWIP_NETBUF_RECVINFO */ -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ - (buf)->toport_chksum = chksum; } while(0) -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#if LWIP_IPV6 -#define netbuf_fromaddr_ip6(buf) (ipX_2_ip6(&((buf)->addr))) -#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set(ipX_2_ip6(&((buf)->addr)), fromaddr) -#define netbuf_destaddr_ip6(buf) (ipX_2_ip6(&((buf)->toaddr))) -#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set(ipX_2_ip6(&((buf)->toaddr)), destaddr) -#endif /* LWIP_IPV6 */ - -#define netbuf_fromaddr_ipX(buf) (&((buf)->addr)) -#define netbuf_destaddr_ipX(buf) (&((buf)->toaddr)) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_NETBUF_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/netdb.h b/external/badvpn_dns/lwip/src/include/lwip/netdb.h deleted file mode 100644 index 7587e2f..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/netdb.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef __LWIP_NETDB_H__ -#define __LWIP_NETDB_H__ - -#include "lwip/opt.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include <stddef.h> /* for size_t */ - -#include "lwip/inet.h" -#include "lwip/sockets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* some rarely used options */ -#ifndef LWIP_DNS_API_DECLARE_H_ERRNO -#define LWIP_DNS_API_DECLARE_H_ERRNO 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_ERRORS -#define LWIP_DNS_API_DEFINE_ERRORS 1 -#endif - -#ifndef LWIP_DNS_API_DECLARE_STRUCTS -#define LWIP_DNS_API_DECLARE_STRUCTS 1 -#endif - -#if LWIP_DNS_API_DEFINE_ERRORS -/** Errors used by the DNS API functions, h_errno can be one of them */ -#define EAI_NONAME 200 -#define EAI_SERVICE 201 -#define EAI_FAIL 202 -#define EAI_MEMORY 203 - -#define HOST_NOT_FOUND 210 -#define NO_DATA 211 -#define NO_RECOVERY 212 -#define TRY_AGAIN 213 -#endif /* LWIP_DNS_API_DEFINE_ERRORS */ - -#if LWIP_DNS_API_DECLARE_STRUCTS -struct hostent { - char *h_name; /* Official name of the host. */ - char **h_aliases; /* A pointer to an array of pointers to alternative host names, - terminated by a null pointer. */ - int h_addrtype; /* Address type. */ - int h_length; /* The length, in bytes, of the address. */ - char **h_addr_list; /* A pointer to an array of pointers to network addresses (in - network byte order) for the host, terminated by a null pointer. */ -#define h_addr h_addr_list[0] /* for backward compatibility */ -}; - -struct addrinfo { - int ai_flags; /* Input flags. */ - int ai_family; /* Address family of socket. */ - int ai_socktype; /* Socket type. */ - int ai_protocol; /* Protocol of socket. */ - socklen_t ai_addrlen; /* Length of socket address. */ - struct sockaddr *ai_addr; /* Socket address of socket. */ - char *ai_canonname; /* Canonical name of service location. */ - struct addrinfo *ai_next; /* Pointer to next in list. */ -}; -#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ - -#if LWIP_DNS_API_DECLARE_H_ERRNO -/* application accessable error code set by the DNS API functions */ -extern int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ - -struct hostent *lwip_gethostbyname(const char *name); -int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop); -void lwip_freeaddrinfo(struct addrinfo *ai); -int lwip_getaddrinfo(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res); - -#if LWIP_COMPAT_SOCKETS -#define gethostbyname(name) lwip_gethostbyname(name) -#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ - lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) -#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) -#define getaddrinfo(nodname, servname, hints, res) \ - lwip_getaddrinfo(nodname, servname, hints, res) -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS && LWIP_SOCKET */ - -#endif /* __LWIP_NETDB_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/netif.h b/external/badvpn_dns/lwip/src/include/lwip/netif.h deleted file mode 100644 index f977032..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/netif.h +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_NETIF_H__ -#define __LWIP_NETIF_H__ - -#include "lwip/opt.h" - -#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) - -#include "lwip/err.h" - -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#if LWIP_DHCP -struct dhcp; -#endif -#if LWIP_AUTOIP -struct autoip; -#endif -#if LWIP_IPV6_DHCP6 -#include "lwip/dhcp6.h" -#endif /* LWIP_IPV6_DHCP6 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses are expected to be in - * the same byte order as in IP_PCB. */ - -/** must be the maximum of all used hardware address lengths - across all types of interfaces in use */ -#define NETIF_MAX_HWADDR_LEN 6U - -/** Whether the network interface is 'up'. This is - * a software flag used to control whether this network - * interface is enabled and processes traffic. - * It is set by the startup code (for static IP configuration) or - * by dhcp/autoip when an address has been assigned. - */ -#define NETIF_FLAG_UP 0x01U -/** If set, the netif has broadcast capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_BROADCAST 0x02U -/** If set, the netif is one end of a point-to-point connection. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_POINTTOPOINT 0x04U -/** If set, the interface is configured using DHCP. - * Set by the DHCP code when starting or stopping DHCP. */ -#define NETIF_FLAG_DHCP 0x08U -/** If set, the interface has an active link - * (set by the network interface driver). - * Either set by the netif driver in its init function (if the link - * is up at that time) or at a later point once the link comes up - * (if link detection is supported by the hardware). */ -#define NETIF_FLAG_LINK_UP 0x10U -/** If set, the netif is an ethernet device using ARP. - * Set by the netif driver in its init function. - * Used to check input packet types and use of DHCP. */ -#define NETIF_FLAG_ETHARP 0x20U -/** If set, the netif is an ethernet device. It might not use - * ARP or TCP/IP if it is used for PPPoE only. - */ -#define NETIF_FLAG_ETHERNET 0x40U -/** If set, the netif has IGMP capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_IGMP 0x80U -/** Whether to pretend that we are every host for TCP packets. - * Set by netif_set_pretend_tcp. */ -#define NETIF_FLAG_PRETEND_TCP 0x100U - -/** Function prototype for netif init functions. Set up flags and output/linkoutput - * callback functions in this function. - * - * @param netif The netif to initialize - */ -typedef err_t (*netif_init_fn)(struct netif *netif); -/** Function prototype for netif->input functions. This function is saved as 'input' - * callback function in the netif struct. Call it when a packet has been received. - * - * @param p The received packet, copied into a pbuf - * @param inp The netif which received the packet - */ -typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); -/** Function prototype for netif->output functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'etharp_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IP address to which the packet shall be sent - */ -typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr); -#if LWIP_IPV6 -/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'nd_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IPv6 address to which the packet shall be sent - */ -typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, - ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ -/** Function prototype for netif->linkoutput functions. Only used for ethernet - * netifs. This function is called by ARP when a packet shall be sent. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (raw ethernet packet) - */ -typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); -/** Function prototype for netif status- or link-callback functions. */ -typedef void (*netif_status_callback_fn)(struct netif *netif); -/** Function prototype for netif igmp_mac_filter functions */ -typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, - ip_addr_t *group, u8_t action); -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** Function prototype for netif mld_mac_filter functions */ -typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, - ip6_addr_t *group, u8_t action); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -/** Generic data structure used for all lwIP network interfaces. - * The following fields should be filled in by the initialization - * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ -struct netif { - /** pointer to next in linked list */ - struct netif *next; - - /** IP address configuration in network byte order */ - ip_addr_t ip_addr; - ip_addr_t netmask; - ip_addr_t gw; - -#if LWIP_IPV6 - /** Array of IPv6 addresses for this netif. */ - ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; - /** The state of each IPv6 address (Tentative, Preferred, etc). - * @see ip6_addr.h */ - u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; -#endif /* LWIP_IPV6 */ - /** This function is called by the network device driver - * to pass a packet up the TCP/IP stack. */ - netif_input_fn input; - /** This function is called by the IP module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. */ - netif_output_fn output; - /** This function is called by the ARP module when it wants - * to send a packet on the interface. This function outputs - * the pbuf as-is on the link medium. */ - netif_linkoutput_fn linkoutput; -#if LWIP_IPV6 - /** This function is called by the IPv6 module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. */ - netif_output_ip6_fn output_ip6; -#endif /* LWIP_IPV6 */ -#if LWIP_NETIF_STATUS_CALLBACK - /** This function is called when the netif state is set to up or down - */ - netif_status_callback_fn status_callback; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - /** This function is called when the netif link is set to up or down - */ - netif_status_callback_fn link_callback; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK - /** This function is called when the netif has been removed */ - netif_status_callback_fn remove_callback; -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - /** This field can be set by the device driver and could point - * to state information for the device. */ - void *state; -#if LWIP_DHCP - /** the DHCP client state information for this netif */ - struct dhcp *dhcp; -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - /** the AutoIP client state information for this netif */ - struct autoip *autoip; -#endif -#if LWIP_IPV6_AUTOCONFIG - /** is this netif enabled for IPv6 autoconfiguration */ - u8_t ip6_autoconfig_enabled; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /** Number of Router Solicitation messages that remain to be sent. */ - u8_t rs_count; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if LWIP_IPV6_DHCP6 - /** the DHCPv6 client state information for this netif */ - struct dhcp6 *dhcp6; -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_NETIF_HOSTNAME - /* the hostname for this netif, NULL is a valid value */ - char* hostname; -#endif /* LWIP_NETIF_HOSTNAME */ - /** maximum transfer unit (in bytes) */ - u16_t mtu; - /** number of bytes used in hwaddr */ - u8_t hwaddr_len; - /** link level hardware address of this interface */ - u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; - /** flags (see NETIF_FLAG_ above) */ - u16_t flags; - /** descriptive abbreviation */ - char name[2]; - /** number of this interface */ - u8_t num; -#if LWIP_SNMP - /** link type (from "snmp_ifType" enum from snmp.h) */ - u8_t link_type; - /** (estimate) link speed */ - u32_t link_speed; - /** timestamp at last change made (up/down) */ - u32_t ts; - /** counters */ - u32_t ifinoctets; - u32_t ifinucastpkts; - u32_t ifinnucastpkts; - u32_t ifindiscards; - u32_t ifoutoctets; - u32_t ifoutucastpkts; - u32_t ifoutnucastpkts; - u32_t ifoutdiscards; -#endif /* LWIP_SNMP */ -#if LWIP_IGMP - /** This function could be called to add or delete an entry in the multicast - filter table of the ethernet MAC.*/ - netif_igmp_mac_filter_fn igmp_mac_filter; -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /** This function could be called to add or delete an entry in the IPv6 multicast - filter table of the ethernet MAC. */ - netif_mld_mac_filter_fn mld_mac_filter; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if LWIP_NETIF_HWADDRHINT - u8_t *addr_hint; -#endif /* LWIP_NETIF_HWADDRHINT */ -#if ENABLE_LOOPBACK - /* List of packets to be queued for ourselves. */ - struct pbuf *loop_first; - struct pbuf *loop_last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t loop_cnt_current; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ -#endif /* ENABLE_LOOPBACK */ -}; - -#if LWIP_SNMP -#define NETIF_INIT_SNMP(netif, type, speed) \ - /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ - (netif)->link_type = (type); \ - /* your link speed here (units: bits per second) */ \ - (netif)->link_speed = (speed); \ - (netif)->ts = 0; \ - (netif)->ifinoctets = 0; \ - (netif)->ifinucastpkts = 0; \ - (netif)->ifinnucastpkts = 0; \ - (netif)->ifindiscards = 0; \ - (netif)->ifoutoctets = 0; \ - (netif)->ifoutucastpkts = 0; \ - (netif)->ifoutnucastpkts = 0; \ - (netif)->ifoutdiscards = 0 -#else /* LWIP_SNMP */ -#define NETIF_INIT_SNMP(netif, type, speed) -#endif /* LWIP_SNMP */ - - -/** The list of network interfaces. */ -extern struct netif *netif_list; -/** The default network interface. */ -extern struct netif *netif_default; - -void netif_init(void); - -struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); - -void -netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw); -void netif_remove(struct netif * netif); - -/* Returns a network interface given its name. The name is of the form - "et0", where the first two letters are the "name" field in the - netif structure, and the digit is in the num field in the same - structure. */ -struct netif *netif_find(char *name); - -int netif_is_named (struct netif *netif, const char name[3]); - -void netif_set_default(struct netif *netif); - -void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); -void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); -void netif_set_gw(struct netif *netif, ip_addr_t *gw); -void netif_set_pretend_tcp(struct netif *netif, u8_t pretend); - -void netif_set_up(struct netif *netif); -void netif_set_down(struct netif *netif); -/** Ask if an interface is up */ -#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_STATUS_CALLBACK -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK -void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -void netif_set_link_up(struct netif *netif); -void netif_set_link_down(struct netif *netif); -/** Ask if a link is up */ -#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_LINK_CALLBACK -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if LWIP_NETIF_HOSTNAME -#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) -#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) -#endif /* LWIP_NETIF_HOSTNAME */ - -#if LWIP_IGMP -#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) -#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) -#endif /* LWIP_IGMP */ - -#if ENABLE_LOOPBACK -err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip); -void netif_poll(struct netif *netif); -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -void netif_poll_all(void); -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_IPV6 -#define netif_ip6_addr(netif, i) (&((netif)->ip6_addr[(i)])) -#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[(i)]) -#define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state)) -s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr); -void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); -#endif /* LWIP_IPV6 */ - -#if LWIP_NETIF_HWADDRHINT -#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) -#else /* LWIP_NETIF_HWADDRHINT */ -#define NETIF_SET_HWADDRHINT(netif, hint) -#endif /* LWIP_NETIF_HWADDRHINT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_NETIF_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/netifapi.h b/external/badvpn_dns/lwip/src/include/lwip/netifapi.h deleted file mode 100644 index 33318ef..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/netifapi.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef __LWIP_NETIFAPI_H__ -#define __LWIP_NETIFAPI_H__ - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*netifapi_void_fn)(struct netif *netif); -typedef err_t (*netifapi_errt_fn)(struct netif *netif); - -struct netifapi_msg_msg { -#if !LWIP_TCPIP_CORE_LOCKING - sys_sem_t sem; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - err_t err; - struct netif *netif; - union { - struct { - ip_addr_t *ipaddr; - ip_addr_t *netmask; - ip_addr_t *gw; - void *state; - netif_init_fn init; - netif_input_fn input; - } add; - struct { - netifapi_void_fn voidfunc; - netifapi_errt_fn errtfunc; - } common; - } msg; -}; - -struct netifapi_msg { - void (* function)(struct netifapi_msg_msg *msg); - struct netifapi_msg_msg msg; -}; - - -/* API for application */ -err_t netifapi_netif_add ( struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw, - void *state, - netif_init_fn init, - netif_input_fn input); - -err_t netifapi_netif_set_addr ( struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw ); - -err_t netifapi_netif_common ( struct netif *netif, - netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc); - -#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) -#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) -#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) -#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) -#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) -#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) -#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) -#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETIF_API */ - -#endif /* __LWIP_NETIFAPI_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/opt.h b/external/badvpn_dns/lwip/src/include/lwip/opt.h deleted file mode 100644 index e51f8e5..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/opt.h +++ /dev/null @@ -1,2417 +0,0 @@ -/** - * @file - * - * lwIP Options Configuration - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_OPT_H__ -#define __LWIP_OPT_H__ - -/* - * Include user defined options first. Anything not defined in these files - * will be set to standard values. Override anything you dont like! - */ -#include "lwipopts.h" -#include "lwip/debug.h" - -/* - ----------------------------------------------- - ---------- Platform specific locking ---------- - ----------------------------------------------- -*/ - -/** - * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain - * critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#ifndef SYS_LIGHTWEIGHT_PROT -#define SYS_LIGHTWEIGHT_PROT 0 -#endif - -/** - * NO_SYS==1: Provides VERY minimal functionality. Otherwise, - * use lwIP facilities. - */ -#ifndef NO_SYS -#define NO_SYS 0 -#endif - -/** - * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 - * Mainly for compatibility to old versions. - */ -#ifndef NO_SYS_NO_TIMERS -#define NO_SYS_NO_TIMERS 0 -#endif - -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#ifndef MEMCPY -#define MEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#ifndef SMEMCPY -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#ifndef MEM_LIBC_MALLOC -#define MEM_LIBC_MALLOC 0 -#endif - -/** -* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. -* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution -* speed and usage from interrupts! -*/ -#ifndef MEMP_MEM_MALLOC -#define MEMP_MEM_MALLOC 0 -#endif - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> #define MEM_ALIGNMENT 4 - * 2 byte alignment -> #define MEM_ALIGNMENT 2 - */ -#ifndef MEM_ALIGNMENT -#define MEM_ALIGNMENT 1 -#endif - -/** - * MEM_SIZE: the size of the heap memory. If the application will send - * a lot of data that needs to be copied, this should be set high. - */ -#ifndef MEM_SIZE -#define MEM_SIZE 1600 -#endif - -/** - * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. - * This can be used to individually change the location of each pool. - * Default is one big array for all pools - */ -#ifndef MEMP_SEPARATE_POOLS -#define MEMP_SEPARATE_POOLS 0 -#endif - -/** - * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable - * amount of bytes before and after each memp element in every pool and fills - * it with a prominent default value. - * MEMP_OVERFLOW_CHECK == 0 no checking - * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed - * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time - * memp_malloc() or memp_free() is called (useful but slow!) - */ -#ifndef MEMP_OVERFLOW_CHECK -#define MEMP_OVERFLOW_CHECK 0 -#endif - -/** - * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make - * sure that there are no cycles in the linked lists. - */ -#ifndef MEMP_SANITY_CHECK -#define MEMP_SANITY_CHECK 0 -#endif - -/** - * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set - * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the length needed is returned. - * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. - */ -#ifndef MEM_USE_POOLS -#define MEM_USE_POOLS 0 -#endif - -/** - * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next - * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more - * reliable. */ -#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL -#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 -#endif - -/** - * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h - * that defines additional pools beyond the "standard" ones required - * by lwIP. If you set this to 1, you must have lwippools.h in your - * inlude path somewhere. - */ -#ifndef MEMP_USE_CUSTOM_POOLS -#define MEMP_USE_CUSTOM_POOLS 0 -#endif - -/** - * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from - * interrupt context (or another context that doesn't allow waiting for a - * semaphore). - * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, - * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs - * with each loop so that mem_free can run. - * - * ATTENTION: As you can see from the above description, this leads to dis-/ - * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc - * can need longer. - * - * If you don't want that, at least for NO_SYS=0, you can still use the following - * functions to enqueue a deallocation call which then runs in the tcpip_thread - * context: - * - pbuf_free_callback(p); - * - mem_free_callback(m); - */ -#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT -#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 -#endif - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ -/** - * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). - * If the application sends a lot of data out of ROM (or other static memory), - * this should be set high. - */ -#ifndef MEMP_NUM_PBUF -#define MEMP_NUM_PBUF 16 -#endif - -/** - * MEMP_NUM_RAW_PCB: Number of raw connection PCBs - * (requires the LWIP_RAW option) - */ -#ifndef MEMP_NUM_RAW_PCB -#define MEMP_NUM_RAW_PCB 4 -#endif - -/** - * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - * per active UDP "connection". - * (requires the LWIP_UDP option) - */ -#ifndef MEMP_NUM_UDP_PCB -#define MEMP_NUM_UDP_PCB 4 -#endif - -/** - * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_PCB -#define MEMP_NUM_TCP_PCB 5 -#endif - -/** - * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_PCB_LISTEN -#define MEMP_NUM_TCP_PCB_LISTEN 8 -#endif - -/** - * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_SEG -#define MEMP_NUM_TCP_SEG 16 -#endif - -/** - * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for - * reassembly (whole packets, not fragments!) - */ -#ifndef MEMP_NUM_REASSDATA -#define MEMP_NUM_REASSDATA 5 -#endif - -/** - * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent - * (fragments, not whole packets!). - * This is only used with IP_FRAG_USES_STATIC_BUF==0 and - * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs - * where the packet is not yet sent when netif->output returns. - */ -#ifndef MEMP_NUM_FRAG_PBUF -#define MEMP_NUM_FRAG_PBUF 15 -#endif - -/** - * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing - * packets (pbufs) that are waiting for an ARP request (to resolve - * their destination address) to finish. - * (requires the ARP_QUEUEING option) - */ -#ifndef MEMP_NUM_ARP_QUEUE -#define MEMP_NUM_ARP_QUEUE 30 -#endif - -/** - * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces - * can be members et the same time (one per netif - allsystems group -, plus one - * per netif membership). - * (requires the LWIP_IGMP option) - */ -#ifndef MEMP_NUM_IGMP_GROUP -#define MEMP_NUM_IGMP_GROUP 8 -#endif - -/** - * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. - * (requires NO_SYS==0) - * The default number of timeouts is calculated here for all enabled modules. - * The formula expects settings to be either '0' or '1'. - */ -#ifndef MEMP_NUM_SYS_TIMEOUT -#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) -#endif - -/** - * MEMP_NUM_NETBUF: the number of struct netbufs. - * (only needed if you use the sequential API, like api_lib.c) - */ -#ifndef MEMP_NUM_NETBUF -#define MEMP_NUM_NETBUF 2 -#endif - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#ifndef MEMP_NUM_NETCONN -#define MEMP_NUM_NETCONN 4 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used - * for callback/timeout API communication. - * (only needed if you use tcpip.c) - */ -#ifndef MEMP_NUM_TCPIP_MSG_API -#define MEMP_NUM_TCPIP_MSG_API 8 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used - * for incoming packets. - * (only needed if you use tcpip.c) - */ -#ifndef MEMP_NUM_TCPIP_MSG_INPKT -#define MEMP_NUM_TCPIP_MSG_INPKT 8 -#endif - -/** - * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. - */ -#ifndef MEMP_NUM_SNMP_NODE -#define MEMP_NUM_SNMP_NODE 50 -#endif - -/** - * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. - * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! - */ -#ifndef MEMP_NUM_SNMP_ROOTNODE -#define MEMP_NUM_SNMP_ROOTNODE 30 -#endif - -/** - * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to - * be changed normally) - 2 of these are used per request (1 for input, - * 1 for output) - */ -#ifndef MEMP_NUM_SNMP_VARBIND -#define MEMP_NUM_SNMP_VARBIND 2 -#endif - -/** - * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used - * (does not have to be changed normally) - 3 of these are used per request - * (1 for the value read and 2 for OIDs - input and output) - */ -#ifndef MEMP_NUM_SNMP_VALUE -#define MEMP_NUM_SNMP_VALUE 3 -#endif - -/** - * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls - * (before freeing the corresponding memory using lwip_freeaddrinfo()). - */ -#ifndef MEMP_NUM_NETDB -#define MEMP_NUM_NETDB 1 -#endif - -/** - * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list - * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. - */ -#ifndef MEMP_NUM_LOCALHOSTLIST -#define MEMP_NUM_LOCALHOSTLIST 1 -#endif - -/** - * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE - * interfaces (only used with PPPOE_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOE_INTERFACES -#define MEMP_NUM_PPPOE_INTERFACES 1 -#endif - -/** - * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. - */ -#ifndef PBUF_POOL_SIZE -#define PBUF_POOL_SIZE 16 -#endif - -/* - --------------------------------- - ---------- ARP options ---------- - --------------------------------- -*/ -/** - * LWIP_ARP==1: Enable ARP functionality. - */ -#ifndef LWIP_ARP -#define LWIP_ARP 1 -#endif - -/** - * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. - */ -#ifndef ARP_TABLE_SIZE -#define ARP_TABLE_SIZE 10 -#endif - -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#ifndef ARP_QUEUEING -#define ARP_QUEUEING 0 -#endif - -/** - * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be - * updated with the source MAC and IP addresses supplied in the packet. - * You may want to disable this if you do not trust LAN peers to have the - * correct addresses, or as a limited approach to attempt to handle - * spoofing. If disabled, lwIP will need to make a new ARP request if - * the peer is not already in the ARP table, adding a little latency. - * The peer *is* in the ARP table if it requested our address before. - * Also notice that this slows down input processing of every IP packet! - */ -#ifndef ETHARP_TRUST_IP_MAC -#define ETHARP_TRUST_IP_MAC 0 -#endif - -/** - * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. - * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. - * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. - * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. - * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) - * that returns 1 to accept a packet or 0 to drop a packet. - */ -#ifndef ETHARP_SUPPORT_VLAN -#define ETHARP_SUPPORT_VLAN 0 -#endif - -/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP - * might be disabled - */ -#ifndef LWIP_ETHERNET -#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) -#endif - -/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure - * alignment of payload after that header. Since the header is 14 bytes long, - * without this padding e.g. addresses in the IP header will not be aligned - * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. - */ -#ifndef ETH_PAD_SIZE -#define ETH_PAD_SIZE 0 -#endif - -/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table - * entries (using etharp_add_static_entry/etharp_remove_static_entry). - */ -#ifndef ETHARP_SUPPORT_STATIC_ENTRIES -#define ETHARP_SUPPORT_STATIC_ENTRIES 0 -#endif - - -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * IP_FORWARD==1: Enables the ability to forward IP packets across network - * interfaces. If you are going to run lwIP on a device with only one network - * interface, define this to 0. - */ -#ifndef IP_FORWARD -#define IP_FORWARD 0 -#endif - -/** - * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. - * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. - * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). - */ -#ifndef IP_OPTIONS_ALLOWED -#define IP_OPTIONS_ALLOWED 1 -#endif - -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#ifndef IP_REASSEMBLY -#define IP_REASSEMBLY 1 -#endif - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#ifndef IP_FRAG -#define IP_FRAG 1 -#endif - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#ifndef IP_REASS_MAXAGE -#define IP_REASS_MAXAGE 3 -#endif - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#ifndef IP_REASS_MAX_PBUFS -#define IP_REASS_MAX_PBUFS 10 -#endif - -/** - * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP - * fragmentation. Otherwise pbufs are allocated and reference the original - * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, - * new PBUF_RAM pbufs are used for fragments). - * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! - */ -#ifndef IP_FRAG_USES_STATIC_BUF -#define IP_FRAG_USES_STATIC_BUF 0 -#endif - -/** - * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer - * (requires IP_FRAG_USES_STATIC_BUF==1) - */ -#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) -#define IP_FRAG_MAX_MTU 1500 -#endif - -/** - * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. - */ -#ifndef IP_DEFAULT_TTL -#define IP_DEFAULT_TTL 255 -#endif - -/** - * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast - * filter per pcb on udp and raw send operations. To enable broadcast filter - * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. - */ -#ifndef IP_SOF_BROADCAST -#define IP_SOF_BROADCAST 0 -#endif - -/** - * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast - * filter on recv operations. - */ -#ifndef IP_SOF_BROADCAST_RECV -#define IP_SOF_BROADCAST_RECV 0 -#endif - -/** - * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back - * out on the netif where it was received. This should only be used for - * wireless networks. - * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming - * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! - */ -#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF -#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 -#endif - -/** - * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first - * local TCP/UDP pcb (default==0). This can prevent creating predictable port - * numbers after booting a device. - */ -#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS -#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 -#endif - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_ICMP==1: Enable ICMP module inside the IP stack. - * Be careful, disable that make your product non-compliant to RFC1122 - */ -#ifndef LWIP_ICMP -#define LWIP_ICMP 1 -#endif - -/** - * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. - */ -#ifndef ICMP_TTL -#define ICMP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#ifndef LWIP_BROADCAST_PING -#define LWIP_BROADCAST_PING 0 -#endif - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#ifndef LWIP_MULTICAST_PING -#define LWIP_MULTICAST_PING 0 -#endif - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#ifndef LWIP_RAW -#define LWIP_RAW 1 -#endif - -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#ifndef RAW_TTL -#define RAW_TTL (IP_DEFAULT_TTL) -#endif - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#ifndef LWIP_DHCP -#define LWIP_DHCP 0 -#endif - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#ifndef DHCP_DOES_ARP_CHECK -#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) -#endif - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/** - * LWIP_AUTOIP==1: Enable AUTOIP module. - */ -#ifndef LWIP_AUTOIP -#define LWIP_AUTOIP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on - * the same interface at the same time. - */ -#ifndef LWIP_DHCP_AUTOIP_COOP -#define LWIP_DHCP_AUTOIP_COOP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes - * that should be sent before falling back on AUTOIP. This can be set - * as low as 1 to get an AutoIP address very quickly, but you should - * be prepared to handle a changing IP address when DHCP overrides - * AutoIP. - */ -#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES -#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 -#endif - -/* - ---------------------------------- - ---------- SNMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP - * transport. - */ -#ifndef LWIP_SNMP -#define LWIP_SNMP 0 -#endif - -/** - * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will - * allow. At least one request buffer is required. - * Does not have to be changed unless external MIBs answer request asynchronously - */ -#ifndef SNMP_CONCURRENT_REQUESTS -#define SNMP_CONCURRENT_REQUESTS 1 -#endif - -/** - * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap - * destination is required - */ -#ifndef SNMP_TRAP_DESTINATIONS -#define SNMP_TRAP_DESTINATIONS 1 -#endif - -/** - * SNMP_PRIVATE_MIB: - * When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. - */ -#ifndef SNMP_PRIVATE_MIB -#define SNMP_PRIVATE_MIB 0 -#endif - -/** - * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not - * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). - * Unsafe requests are disabled by default! - */ -#ifndef SNMP_SAFE_REQUESTS -#define SNMP_SAFE_REQUESTS 1 -#endif - -/** - * The maximum length of strings used. This affects the size of - * MEMP_SNMP_VALUE elements. - */ -#ifndef SNMP_MAX_OCTET_STRING_LEN -#define SNMP_MAX_OCTET_STRING_LEN 127 -#endif - -/** - * The maximum depth of the SNMP tree. - * With private MIBs enabled, this depends on your MIB! - * This affects the size of MEMP_SNMP_VALUE elements. - */ -#ifndef SNMP_MAX_TREE_DEPTH -#define SNMP_MAX_TREE_DEPTH 15 -#endif - -/** - * The size of the MEMP_SNMP_VALUE elements, normally calculated from - * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. - */ -#ifndef SNMP_MAX_VALUE_SIZE -#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) -#endif - -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#ifndef LWIP_IGMP -#define LWIP_IGMP 0 -#endif - -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#ifndef LWIP_DNS -#define LWIP_DNS 0 -#endif - -/** DNS maximum number of entries to maintain locally. */ -#ifndef DNS_TABLE_SIZE -#define DNS_TABLE_SIZE 4 -#endif - -/** DNS maximum host name length supported in the name table. */ -#ifndef DNS_MAX_NAME_LENGTH -#define DNS_MAX_NAME_LENGTH 256 -#endif - -/** The maximum of DNS servers */ -#ifndef DNS_MAX_SERVERS -#define DNS_MAX_SERVERS 2 -#endif - -/** DNS do a name checking between the query and the response. */ -#ifndef DNS_DOES_NAME_CHECK -#define DNS_DOES_NAME_CHECK 1 -#endif - -/** DNS message max. size. Default value is RFC compliant. */ -#ifndef DNS_MSG_SIZE -#define DNS_MSG_SIZE 512 -#endif - -/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, - * you have to define - * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} - * (an array of structs name/address, where address is an u32_t in network - * byte order). - * - * Instead, you can also use an external function: - * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) - * that returns the IP address or INADDR_NONE if not found. - */ -#ifndef DNS_LOCAL_HOSTLIST -#define DNS_LOCAL_HOSTLIST 0 -#endif /* DNS_LOCAL_HOSTLIST */ - -/** If this is turned on, the local host-list can be dynamically changed - * at runtime. */ -#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/** - * LWIP_UDP==1: Turn on UDP. - */ -#ifndef LWIP_UDP -#define LWIP_UDP 1 -#endif - -/** - * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) - */ -#ifndef LWIP_UDPLITE -#define LWIP_UDPLITE 0 -#endif - -/** - * UDP_TTL: Default Time-To-Live value. - */ -#ifndef UDP_TTL -#define UDP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. - */ -#ifndef LWIP_NETBUF_RECVINFO -#define LWIP_NETBUF_RECVINFO 0 -#endif - -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * LWIP_TCP==1: Turn on TCP. - */ -#ifndef LWIP_TCP -#define LWIP_TCP 1 -#endif - -/** - * TCP_TTL: Default Time-To-Live value. - */ -#ifndef TCP_TTL -#define TCP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well - */ -#ifndef TCP_WND -#define TCP_WND (4 * TCP_MSS) -#endif - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#ifndef TCP_MAXRTX -#define TCP_MAXRTX 12 -#endif - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#ifndef TCP_SYNMAXRTX -#define TCP_SYNMAXRTX 6 -#endif - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#ifndef TCP_QUEUE_OOSEQ -#define TCP_QUEUE_OOSEQ (LWIP_TCP) -#endif - -/** - * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, - * you might want to increase this.) - * For the receive side, this MSS is advertised to the remote side - * when opening a connection. For the transmit size, this MSS sets - * an upper limit on the MSS advertised by the remote host. - */ -#ifndef TCP_MSS -#define TCP_MSS 536 -#endif - -/** - * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really - * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which - * reflects the available reassembly buffer size at the remote host) and the - * largest size permitted by the IP layer" (RFC 1122) - * Setting this to 1 enables code that checks TCP_MSS against the MTU of the - * netif used for a connection and limits the MSS if it would be too big otherwise. - */ -#ifndef TCP_CALCULATE_EFF_SEND_MSS -#define TCP_CALCULATE_EFF_SEND_MSS 1 -#endif - - -/** - * TCP_SND_BUF: TCP sender buffer space (bytes). - * To achieve good performance, this should be at least 2 * TCP_MSS. - */ -#ifndef TCP_SND_BUF -#define TCP_SND_BUF (2 * TCP_MSS) -#endif - -/** - * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least - * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. - */ -#ifndef TCP_SND_QUEUELEN -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) -#endif - -/** - * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than - * TCP_SND_BUF. It is the amount of space which must be available in the - * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). - */ -#ifndef TCP_SNDLOWAT -#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -#endif - -/** - * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less - * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below - * this number, select returns writable (combined with TCP_SNDLOWAT). - */ -#ifndef TCP_SNDQUEUELOWAT -#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) -#endif - -/** - * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. - */ -#ifndef TCP_OOSEQ_MAX_BYTES -#define TCP_OOSEQ_MAX_BYTES 0 -#endif - -/** - * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. - */ -#ifndef TCP_OOSEQ_MAX_PBUFS -#define TCP_OOSEQ_MAX_PBUFS 0 -#endif - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#ifndef TCP_LISTEN_BACKLOG -#define TCP_LISTEN_BACKLOG 0 -#endif - -/** - * The maximum allowed backlog for TCP listen netconns. - * This backlog is used unless another is explicitly specified. - * 0xff is the maximum (u8_t). - */ -#ifndef TCP_DEFAULT_LISTEN_BACKLOG -#define TCP_DEFAULT_LISTEN_BACKLOG 0xff -#endif - -/** - * TCP_OVERSIZE: The maximum number of bytes that tcp_write may - * allocate ahead of time in an attempt to create shorter pbuf chains - * for transmission. The meaningful range is 0 to TCP_MSS. Some - * suggested values are: - * - * 0: Disable oversized allocation. Each tcp_write() allocates a new - pbuf (old behaviour). - * 1: Allocate size-aligned pbufs with minimal excess. Use this if your - * scatter-gather DMA requires aligned fragments. - * 128: Limit the pbuf/memory overhead to 20%. - * TCP_MSS: Try to create unfragmented TCP packets. - * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. - */ -#ifndef TCP_OVERSIZE -#define TCP_OVERSIZE TCP_MSS -#endif - -/** - * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. - */ -#ifndef LWIP_TCP_TIMESTAMPS -#define LWIP_TCP_TIMESTAMPS 0 -#endif - -/** - * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an - * explicit window update - */ -#ifndef TCP_WND_UPDATE_THRESHOLD -#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) -#endif - -/** - * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. - */ -#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) -#define LWIP_EVENT_API 0 -#define LWIP_CALLBACK_API 1 -#endif - - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ -/** - * PBUF_LINK_HLEN: the number of bytes that should be allocated for a - * link level header. The default is 14, the standard value for - * Ethernet. - */ -#ifndef PBUF_LINK_HLEN -#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) -#endif - -/** - * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is - * designed to accomodate single full size TCP frame in one pbuf, including - * TCP_MSS, IP header, and link header. - */ -#ifndef PBUF_POOL_BUFSIZE -#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) -#endif - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#ifndef LWIP_NETIF_HOSTNAME -#define LWIP_NETIF_HOSTNAME 0 -#endif - -/** - * LWIP_NETIF_API==1: Support netif api (in netifapi.c) - */ -#ifndef LWIP_NETIF_API -#define LWIP_NETIF_API 0 -#endif - -/** - * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface - * changes its up/down status (i.e., due to DHCP IP acquistion) - */ -#ifndef LWIP_NETIF_STATUS_CALLBACK -#define LWIP_NETIF_STATUS_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface - * whenever the link changes (i.e., link down) - */ -#ifndef LWIP_NETIF_LINK_CALLBACK -#define LWIP_NETIF_LINK_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called - * when a netif has been removed - */ -#ifndef LWIP_NETIF_REMOVE_CALLBACK -#define LWIP_NETIF_REMOVE_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table - * indices) in struct netif. TCP and UDP can make use of this to prevent - * scanning the ARP table for every sent packet. While this is faster for big - * ARP tables or many concurrent connections, it might be counterproductive - * if you have a tiny ARP table or if there never are concurrent connections. - */ -#ifndef LWIP_NETIF_HWADDRHINT -#define LWIP_NETIF_HWADDRHINT 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP - * address equal to the netif IP address, looping them back up the stack. - */ -#ifndef LWIP_NETIF_LOOPBACK -#define LWIP_NETIF_LOOPBACK 0 -#endif - -/** - * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback - * sending for each netif (0 = disabled) - */ -#ifndef LWIP_LOOPBACK_MAX_PBUFS -#define LWIP_LOOPBACK_MAX_PBUFS 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in - * the system, as netifs must change how they behave depending on this setting - * for the LWIP_NETIF_LOOPBACK option to work. - * Setting this is needed to avoid reentering non-reentrant functions like - * tcp_input(). - * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a - * multithreaded environment like tcpip.c. In this case, netif->input() - * is called directly. - * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. - * The packets are put on a list and netif_poll() must be called in - * the main application loop. - */ -#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING -#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) -#endif - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: - */ -#ifndef LWIP_NETIF_TX_SINGLE_PBUF -#define LWIP_NETIF_TX_SINGLE_PBUF 0 -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c - */ -#ifndef LWIP_HAVE_LOOPIF -#define LWIP_HAVE_LOOPIF 0 -#endif - -/* - ------------------------------------ - ---------- SLIPIF options ---------- - ------------------------------------ -*/ -/** - * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c - */ -#ifndef LWIP_HAVE_SLIPIF -#define LWIP_HAVE_SLIPIF 0 -#endif - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. - */ -#ifndef TCPIP_THREAD_NAME -#define TCPIP_THREAD_NAME "tcpip_thread" -#endif - -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef TCPIP_THREAD_STACKSIZE -#define TCPIP_THREAD_STACKSIZE 0 -#endif - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef TCPIP_THREAD_PRIO -#define TCPIP_THREAD_PRIO 1 -#endif - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#ifndef TCPIP_MBOX_SIZE -#define TCPIP_MBOX_SIZE 0 -#endif - -/** - * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. - */ -#ifndef SLIPIF_THREAD_NAME -#define SLIPIF_THREAD_NAME "slipif_loop" -#endif - -/** - * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef SLIPIF_THREAD_STACKSIZE -#define SLIPIF_THREAD_STACKSIZE 0 -#endif - -/** - * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef SLIPIF_THREAD_PRIO -#define SLIPIF_THREAD_PRIO 1 -#endif - -/** - * PPP_THREAD_NAME: The name assigned to the pppInputThread. - */ -#ifndef PPP_THREAD_NAME -#define PPP_THREAD_NAME "pppInputThread" -#endif - -/** - * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_STACKSIZE -#define PPP_THREAD_STACKSIZE 0 -#endif - -/** - * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_PRIO -#define PPP_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. - */ -#ifndef DEFAULT_THREAD_NAME -#define DEFAULT_THREAD_NAME "lwIP" -#endif - -/** - * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef DEFAULT_THREAD_STACKSIZE -#define DEFAULT_THREAD_STACKSIZE 0 -#endif - -/** - * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef DEFAULT_THREAD_PRIO -#define DEFAULT_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_RAW_RECVMBOX_SIZE -#define DEFAULT_RAW_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_UDP_RECVMBOX_SIZE -#define DEFAULT_UDP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_TCP_RECVMBOX_SIZE -#define DEFAULT_TCP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#ifndef DEFAULT_ACCEPTMBOX_SIZE -#define DEFAULT_ACCEPTMBOX_SIZE 0 -#endif - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ -/** - * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) - * Don't use it if you're not an active lwIP project member - */ -#ifndef LWIP_TCPIP_CORE_LOCKING -#define LWIP_TCPIP_CORE_LOCKING 0 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) - * Don't use it if you're not an active lwIP project member - */ -#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT -#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 -#endif - -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#ifndef LWIP_NETCONN -#define LWIP_NETCONN 1 -#endif - -/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create - * timers running in tcpip_thread from another thread. - */ -#ifndef LWIP_TCPIP_TIMEOUT -#define LWIP_TCPIP_TIMEOUT 1 -#endif - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#ifndef LWIP_SOCKET -#define LWIP_SOCKET 1 -#endif - -/** - * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. - * (only used if you use sockets.c) - */ -#ifndef LWIP_COMPAT_SOCKETS -#define LWIP_COMPAT_SOCKETS 1 -#endif - -/** - * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. - * Disable this option if you use a POSIX operating system that uses the same - * names (read, write & close). (only used if you use sockets.c) - */ -#ifndef LWIP_POSIX_SOCKETS_IO_NAMES -#define LWIP_POSIX_SOCKETS_IO_NAMES 1 -#endif - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#ifndef LWIP_TCP_KEEPALIVE -#define LWIP_TCP_KEEPALIVE 0 -#endif - -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#ifndef LWIP_SO_SNDTIMEO -#define LWIP_SO_SNDTIMEO 0 -#endif - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#ifndef LWIP_SO_RCVTIMEO -#define LWIP_SO_RCVTIMEO 0 -#endif - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#ifndef LWIP_SO_RCVBUF -#define LWIP_SO_RCVBUF 0 -#endif - -/** - * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. - */ -#ifndef RECV_BUFSIZE_DEFAULT -#define RECV_BUFSIZE_DEFAULT INT_MAX -#endif - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#ifndef SO_REUSE -#define SO_REUSE 0 -#endif - -/** - * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets - * to all local matches if SO_REUSEADDR is turned on. - * WARNING: Adds a memcpy for every packet if passing to more than one pcb! - */ -#ifndef SO_REUSE_RXTOALL -#define SO_REUSE_RXTOALL 0 -#endif - -/** - * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of - * pending data in the network buffer. This is the way windows does it. It's - * the default for lwIP since it is smaller. - * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next - * pending datagram in bytes. This is the way linux does it. This code is only - * here for compatibility. - */ -#ifndef LWIP_FIONREAD_LINUXMODE -#define LWIP_FIONREAD_LINUXMODE 0 -#endif - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#ifndef LWIP_STATS -#define LWIP_STATS 1 -#endif - -#if LWIP_STATS - -/** - * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. - */ -#ifndef LWIP_STATS_DISPLAY -#define LWIP_STATS_DISPLAY 0 -#endif - -/** - * LINK_STATS==1: Enable link stats. - */ -#ifndef LINK_STATS -#define LINK_STATS 1 -#endif - -/** - * ETHARP_STATS==1: Enable etharp stats. - */ -#ifndef ETHARP_STATS -#define ETHARP_STATS (LWIP_ARP) -#endif - -/** - * IP_STATS==1: Enable IP stats. - */ -#ifndef IP_STATS -#define IP_STATS 1 -#endif - -/** - * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is - * on if using either frag or reass. - */ -#ifndef IPFRAG_STATS -#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) -#endif - -/** - * ICMP_STATS==1: Enable ICMP stats. - */ -#ifndef ICMP_STATS -#define ICMP_STATS 1 -#endif - -/** - * IGMP_STATS==1: Enable IGMP stats. - */ -#ifndef IGMP_STATS -#define IGMP_STATS (LWIP_IGMP) -#endif - -/** - * UDP_STATS==1: Enable UDP stats. Default is on if - * UDP enabled, otherwise off. - */ -#ifndef UDP_STATS -#define UDP_STATS (LWIP_UDP) -#endif - -/** - * TCP_STATS==1: Enable TCP stats. Default is on if TCP - * enabled, otherwise off. - */ -#ifndef TCP_STATS -#define TCP_STATS (LWIP_TCP) -#endif - -/** - * MEM_STATS==1: Enable mem.c stats. - */ -#ifndef MEM_STATS -#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) -#endif - -/** - * MEMP_STATS==1: Enable memp.c pool stats. - */ -#ifndef MEMP_STATS -#define MEMP_STATS (MEMP_MEM_MALLOC == 0) -#endif - -/** - * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). - */ -#ifndef SYS_STATS -#define SYS_STATS (NO_SYS == 0) -#endif - -/** - * IP6_STATS==1: Enable IPv6 stats. - */ -#ifndef IP6_STATS -#define IP6_STATS (LWIP_IPV6) -#endif - -/** - * ICMP6_STATS==1: Enable ICMP for IPv6 stats. - */ -#ifndef ICMP6_STATS -#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) -#endif - -/** - * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. - */ -#ifndef IP6_FRAG_STATS -#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) -#endif - -/** - * MLD6_STATS==1: Enable MLD for IPv6 stats. - */ -#ifndef MLD6_STATS -#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) -#endif - -/** - * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. - */ -#ifndef ND6_STATS -#define ND6_STATS (LWIP_IPV6) -#endif - -#else - -#define LINK_STATS 0 -#define IP_STATS 0 -#define IPFRAG_STATS 0 -#define ICMP_STATS 0 -#define IGMP_STATS 0 -#define UDP_STATS 0 -#define TCP_STATS 0 -#define MEM_STATS 0 -#define MEMP_STATS 0 -#define SYS_STATS 0 -#define LWIP_STATS_DISPLAY 0 -#define IP6_STATS 0 -#define ICMP6_STATS 0 -#define IP6_FRAG_STATS 0 -#define MLD6_STATS 0 -#define ND6_STATS 0 - -#endif /* LWIP_STATS */ - -/* - --------------------------------- - ---------- PPP options ---------- - --------------------------------- -*/ -/** - * PPP_SUPPORT==1: Enable PPP. - */ -#ifndef PPP_SUPPORT -#define PPP_SUPPORT 0 -#endif - -/** - * PPPOE_SUPPORT==1: Enable PPP Over Ethernet - */ -#ifndef PPPOE_SUPPORT -#define PPPOE_SUPPORT 0 -#endif - -/** - * PPPOS_SUPPORT==1: Enable PPP Over Serial - */ -#ifndef PPPOS_SUPPORT -#define PPPOS_SUPPORT PPP_SUPPORT -#endif - -#if PPP_SUPPORT - -/** - * NUM_PPP: Max PPP sessions. - */ -#ifndef NUM_PPP -#define NUM_PPP 1 -#endif - -/** - * PAP_SUPPORT==1: Support PAP. - */ -#ifndef PAP_SUPPORT -#define PAP_SUPPORT 0 -#endif - -/** - * CHAP_SUPPORT==1: Support CHAP. - */ -#ifndef CHAP_SUPPORT -#define CHAP_SUPPORT 0 -#endif - -/** - * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 0 -#endif - -/** - * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CBCP_SUPPORT -#define CBCP_SUPPORT 0 -#endif - -/** - * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CCP_SUPPORT -#define CCP_SUPPORT 0 -#endif - -/** - * VJ_SUPPORT==1: Support VJ header compression. - */ -#ifndef VJ_SUPPORT -#define VJ_SUPPORT 0 -#endif - -/** - * MD5_SUPPORT==1: Support MD5 (see also CHAP). - */ -#ifndef MD5_SUPPORT -#define MD5_SUPPORT 0 -#endif - -/* - * Timeouts - */ -#ifndef FSM_DEFTIMEOUT -#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ -#endif - -#ifndef FSM_DEFMAXTERMREQS -#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#endif - -#ifndef FSM_DEFMAXCONFREQS -#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#endif - -#ifndef FSM_DEFMAXNAKLOOPS -#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ -#endif - -#ifndef UPAP_DEFTIMEOUT -#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ -#endif - -#ifndef UPAP_DEFREQTIME -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ -#endif - -#ifndef CHAP_DEFTIMEOUT -#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ -#endif - -#ifndef CHAP_DEFTRANSMITS -#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ -#endif - -/* Interval in seconds between keepalive echo requests, 0 to disable. */ -#ifndef LCP_ECHOINTERVAL -#define LCP_ECHOINTERVAL 0 -#endif - -/* Number of unanswered echo requests before failure. */ -#ifndef LCP_MAXECHOFAILS -#define LCP_MAXECHOFAILS 3 -#endif - -/* Max Xmit idle time (in jiffies) before resend flag char. */ -#ifndef PPP_MAXIDLEFLAG -#define PPP_MAXIDLEFLAG 100 -#endif - -/* - * Packet sizes - * - * Note - lcp shouldn't be allowed to negotiate stuff outside these - * limits. See lcp.h in the pppd directory. - * (XXX - these constants should simply be shared by lcp.c instead - * of living in lcp.h) - */ -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#ifndef PPP_MAXMTU -/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ -#define PPP_MAXMTU 1500 /* Largest MTU we allow */ -#endif -#define PPP_MINMTU 64 -#define PPP_MRU 1500 /* default MRU = max length of info field */ -#define PPP_MAXMRU 1500 /* Largest MRU we allow */ -#ifndef PPP_DEFMRU -#define PPP_DEFMRU 296 /* Try for this */ -#endif -#define PPP_MINMRU 128 /* No MRUs below this */ - -#ifndef MAXNAMELEN -#define MAXNAMELEN 256 /* max length of hostname or name for auth */ -#endif -#ifndef MAXSECRETLEN -#define MAXSECRETLEN 256 /* max length of password or secret */ -#endif - -#endif /* PPP_SUPPORT */ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ -/** - * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. - */ -#ifndef CHECKSUM_GEN_IP -#define CHECKSUM_GEN_IP 1 -#endif - -/** - * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. - */ -#ifndef CHECKSUM_GEN_UDP -#define CHECKSUM_GEN_UDP 1 -#endif - -/** - * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. - */ -#ifndef CHECKSUM_GEN_TCP -#define CHECKSUM_GEN_TCP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. - */ -#ifndef CHECKSUM_GEN_ICMP -#define CHECKSUM_GEN_ICMP 1 -#endif - -/** - * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. - */ -#ifndef CHECKSUM_CHECK_IP -#define CHECKSUM_CHECK_IP 1 -#endif - -/** - * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. - */ -#ifndef CHECKSUM_CHECK_UDP -#define CHECKSUM_CHECK_UDP 1 -#endif - -/** - * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. - */ -#ifndef CHECKSUM_CHECK_TCP -#define CHECKSUM_CHECK_TCP 1 -#endif - -/** - * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from - * application buffers to pbufs. - */ -#ifndef LWIP_CHECKSUM_ON_COPY -#define LWIP_CHECKSUM_ON_COPY 0 -#endif - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#ifndef LWIP_IPV6 -#define LWIP_IPV6 0 -#endif - -/** - * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. - */ -#ifndef LWIP_IPV6_NUM_ADDRESSES -#define LWIP_IPV6_NUM_ADDRESSES 3 -#endif - -/** - * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs - */ -#ifndef LWIP_IPV6_FORWARD -#define LWIP_IPV6_FORWARD 0 -#endif - -/** - * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) - */ -#ifndef LWIP_ICMP6 -#define LWIP_ICMP6 (LWIP_IPV6) -#endif - -/** - * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in - * ICMPv6 error messages. - */ -#ifndef LWIP_ICMP6_DATASIZE -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/** - * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages - */ -#ifndef LWIP_ICMP6_HL -#define LWIP_ICMP6_HL 255 -#endif - -/** - * LWIP_ICMP6_CHECKSUM_CHECK==1: verify checksum on ICMPv6 packets - */ -#ifndef LWIP_ICMP6_CHECKSUM_CHECK -#define LWIP_ICMP6_CHECKSUM_CHECK 1 -#endif - -/** - * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. - */ -#ifndef LWIP_IPV6_MLD -#define LWIP_IPV6_MLD (LWIP_IPV6) -#endif - -/** - * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast that can be joined. - */ -#ifndef MEMP_NUM_MLD6_GROUP -#define MEMP_NUM_MLD6_GROUP 4 -#endif - -/** - * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. - */ -#ifndef LWIP_IPV6_FRAG -#define LWIP_IPV6_FRAG 0 -#endif - -/** - * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented - */ -#ifndef LWIP_IPV6_REASS -#define LWIP_IPV6_REASS (LWIP_IPV6) -#endif - -/** - * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address - * is being resolved. - */ -#ifndef LWIP_ND6_QUEUEING -#define LWIP_ND6_QUEUEING (LWIP_IPV6) -#endif - -/** - * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. - */ -#ifndef MEMP_NUM_ND6_QUEUE -#define MEMP_NUM_ND6_QUEUE 20 -#endif - -/** - * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache - */ -#ifndef LWIP_ND6_NUM_NEIGHBORS -#define LWIP_ND6_NUM_NEIGHBORS 10 -#endif - -/** - * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache - */ -#ifndef LWIP_ND6_NUM_DESTINATIONS -#define LWIP_ND6_NUM_DESTINATIONS 10 -#endif - -/** - * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache - */ -#ifndef LWIP_ND6_NUM_PREFIXES -#define LWIP_ND6_NUM_PREFIXES 5 -#endif - -/** - * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache - */ -#ifndef LWIP_ND6_NUM_ROUTERS -#define LWIP_ND6_NUM_ROUTERS 3 -#endif - -/** - * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send - * (neighbor solicit and router solicit) - */ -#ifndef LWIP_ND6_MAX_MULTICAST_SOLICIT -#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 -#endif - -/** - * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages - * to send during neighbor reachability detection. - */ -#ifndef LWIP_ND6_MAX_UNICAST_SOLICIT -#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 -#endif - -/** - * Unused: See ND RFC (time in milliseconds). - */ -#ifndef LWIP_ND6_MAX_ANYCAST_DELAY_TIME -#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 -#endif - -/** - * Unused: See ND RFC - */ -#ifndef LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT -#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 -#endif - -/** - * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). - * May be updated by router advertisement messages. - */ -#ifndef LWIP_ND6_REACHABLE_TIME -#define LWIP_ND6_REACHABLE_TIME 30000 -#endif - -/** - * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages - */ -#ifndef LWIP_ND6_RETRANS_TIMER -#define LWIP_ND6_RETRANS_TIMER 1000 -#endif - -/** - * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation - * message is sent, during neighbor reachability detection. - */ -#ifndef LWIP_ND6_DELAY_FIRST_PROBE_TIME -#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 -#endif - -/** - * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update - * Reachable time and retransmission timers, and netif MTU. - */ -#ifndef LWIP_ND6_ALLOW_RA_UPDATES -#define LWIP_ND6_ALLOW_RA_UPDATES 1 -#endif - -/** - * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during - * network startup. - */ -#ifndef LWIP_IPV6_SEND_ROUTER_SOLICIT -#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 -#endif - -/** - * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery - * with reachability hints for connected destinations. This helps avoid sending - * unicast neighbor solicitation messages. - */ -#ifndef LWIP_ND6_TCP_REACHABILITY_HINTS -#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 -#endif - -/** - * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. - */ -#ifndef LWIP_IPV6_AUTOCONFIG -#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) -#endif - -/** - * LWIP_IPV6_DUP_DETECT_ATTEMPTS: Number of duplicate address detection attempts. - */ -#ifndef LWIP_IPV6_DUP_DETECT_ATTEMPTS -#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 -#endif - -/** - * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. - */ -#ifndef LWIP_IPV6_DHCP6 -#define LWIP_IPV6_DHCP6 0 -#endif - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/* Hooks are undefined by default, define them to a function if you need them. */ - -/** - * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): - * - called from ip_input() (IPv4) - * - pbuf: received struct pbuf passed to ip_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ - -/** - * LWIP_HOOK_IP4_ROUTE(dest): - * - called from ip_route() (IPv4) - * - dest: destination IPv4 address - * Returns the destination netif or NULL if no destination netif is found. In - * that case, ip_route() continues as normal. - */ - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is - * compared against this value. If it is smaller, then debugging - * messages are written. - */ -#ifndef LWIP_DBG_MIN_LEVEL -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL -#endif - -/** - * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable - * debug messages of certain types. - */ -#ifndef LWIP_DBG_TYPES_ON -#define LWIP_DBG_TYPES_ON LWIP_DBG_ON -#endif - -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#ifndef ETHARP_DEBUG -#define ETHARP_DEBUG LWIP_DBG_OFF -#endif - -/** - * NETIF_DEBUG: Enable debugging in netif.c. - */ -#ifndef NETIF_DEBUG -#define NETIF_DEBUG LWIP_DBG_OFF -#endif - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#ifndef PBUF_DEBUG -#define PBUF_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#ifndef API_LIB_DEBUG -#define API_LIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_MSG_DEBUG: Enable debugging in api_msg.c. - */ -#ifndef API_MSG_DEBUG -#define API_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#ifndef SOCKETS_DEBUG -#define SOCKETS_DEBUG LWIP_DBG_OFF -#endif - -/** - * ICMP_DEBUG: Enable debugging in icmp.c. - */ -#ifndef ICMP_DEBUG -#define ICMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IGMP_DEBUG: Enable debugging in igmp.c. - */ -#ifndef IGMP_DEBUG -#define IGMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * INET_DEBUG: Enable debugging in inet.c. - */ -#ifndef INET_DEBUG -#define INET_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#ifndef IP_DEBUG -#define IP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. - */ -#ifndef IP_REASS_DEBUG -#define IP_REASS_DEBUG LWIP_DBG_OFF -#endif - -/** - * RAW_DEBUG: Enable debugging in raw.c. - */ -#ifndef RAW_DEBUG -#define RAW_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEM_DEBUG: Enable debugging in mem.c. - */ -#ifndef MEM_DEBUG -#define MEM_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#ifndef MEMP_DEBUG -#define MEMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SYS_DEBUG: Enable debugging in sys.c. - */ -#ifndef SYS_DEBUG -#define SYS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TIMERS_DEBUG: Enable debugging in timers.c. - */ -#ifndef TIMERS_DEBUG -#define TIMERS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_DEBUG: Enable debugging for TCP. - */ -#ifndef TCP_DEBUG -#define TCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#ifndef TCP_INPUT_DEBUG -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. - */ -#ifndef TCP_FR_DEBUG -#define TCP_FR_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit - * timeout. - */ -#ifndef TCP_RTO_DEBUG -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. - */ -#ifndef TCP_CWND_DEBUG -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. - */ -#ifndef TCP_WND_DEBUG -#define TCP_WND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#ifndef TCP_OUTPUT_DEBUG -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. - */ -#ifndef TCP_RST_DEBUG -#define TCP_RST_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. - */ -#ifndef TCP_QLEN_DEBUG -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#endif - -/** - * UDP_DEBUG: Enable debugging in UDP. - */ -#ifndef UDP_DEBUG -#define UDP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#ifndef TCPIP_DEBUG -#define TCPIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * PPP_DEBUG: Enable debugging for PPP. - */ -#ifndef PPP_DEBUG -#define PPP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SLIP_DEBUG: Enable debugging in slipif.c. - */ -#ifndef SLIP_DEBUG -#define SLIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#ifndef DHCP_DEBUG -#define DHCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * AUTOIP_DEBUG: Enable debugging in autoip.c. - */ -#ifndef AUTOIP_DEBUG -#define AUTOIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. - */ -#ifndef SNMP_MSG_DEBUG -#define SNMP_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. - */ -#ifndef SNMP_MIB_DEBUG -#define SNMP_MIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * DNS_DEBUG: Enable debugging for DNS. - */ -#ifndef DNS_DEBUG -#define DNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP6_DEBUG: Enable debugging for IPv6. - */ -#ifndef IP6_DEBUG -#define IP6_DEBUG LWIP_DBG_OFF -#endif - -#endif /* __LWIP_OPT_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/pbuf.h b/external/badvpn_dns/lwip/src/include/lwip/pbuf.h deleted file mode 100644 index 4f8dca8..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/pbuf.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#ifndef __LWIP_PBUF_H__ -#define __LWIP_PBUF_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Currently, the pbuf_custom code is only needed for one specific configuration - * of IP_FRAG */ -#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) - -/* @todo: We need a mechanism to prevent wasting memory in every pbuf - (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ - -#define PBUF_TRANSPORT_HLEN 20 -#if LWIP_IPV6 -#define PBUF_IP_HLEN 40 -#else -#define PBUF_IP_HLEN 20 -#endif - -typedef enum { - PBUF_TRANSPORT, - PBUF_IP, - PBUF_LINK, - PBUF_RAW -} pbuf_layer; - -typedef enum { - PBUF_RAM, /* pbuf data is stored in RAM */ - PBUF_ROM, /* pbuf data is stored in ROM */ - PBUF_REF, /* pbuf comes from the pbuf pool */ - PBUF_POOL /* pbuf payload refers to RAM */ -} pbuf_type; - - -/** indicates this packet's data should be immediately passed to the application */ -#define PBUF_FLAG_PUSH 0x01U -/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a - a pbuf differently */ -#define PBUF_FLAG_IS_CUSTOM 0x02U -/** indicates this pbuf is UDP multicast to be looped back */ -#define PBUF_FLAG_MCASTLOOP 0x04U -/** indicates this pbuf was received as link-level broadcast */ -#define PBUF_FLAG_LLBCAST 0x08U -/** indicates this pbuf was received as link-level multicast */ -#define PBUF_FLAG_LLMCAST 0x10U -/** indicates this pbuf includes a TCP FIN flag */ -#define PBUF_FLAG_TCP_FIN 0x20U - -struct pbuf { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; - - /** pointer to the actual data in the buffer */ - void *payload; - - /** - * total length of this buffer and all next buffers in chain - * belonging to the same packet. - * - * For non-queue packet chains this is the invariant: - * p->tot_len == p->len + (p->next? p->next->tot_len: 0) - */ - u16_t tot_len; - - /** length of this buffer */ - u16_t len; - - /** pbuf_type as u8_t instead of enum to save space */ - u8_t /*pbuf_type*/ type; - - /** misc flags */ - u8_t flags; - - /** - * the reference count always equals the number of pointers - * that refer to this pbuf. This can be pointers from an application, - * the stack itself, or pbuf->next pointers from a chain. - */ - u16_t ref; -}; - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** Prototype for a function to free a custom pbuf */ -typedef void (*pbuf_free_custom_fn)(struct pbuf *p); - -/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ -struct pbuf_custom { - /** The actual pbuf */ - struct pbuf pbuf; - /** This function is called when pbuf_free deallocates this pbuf(_custom) */ - pbuf_free_custom_fn custom_free_function; -}; -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -#if LWIP_TCP && TCP_QUEUE_OOSEQ -/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ -#ifndef PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_FREE_OOSEQ 1 -#endif /* PBUF_POOL_FREE_OOSEQ */ -#if NO_SYS && PBUF_POOL_FREE_OOSEQ -extern volatile u8_t pbuf_free_ooseq_pending; -void pbuf_free_ooseq(void); -/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level to check if ooseq pbufs need to be - freed! */ -#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ - /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ - ooseq queued pbufs now */ \ - pbuf_free_ooseq(); }}while(0) -#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ - -/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ -#define pbuf_init() - -struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); -#if LWIP_SUPPORT_CUSTOM_PBUF -struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, - struct pbuf_custom *p, void *payload_mem, - u16_t payload_mem_len); -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ -void pbuf_realloc(struct pbuf *p, u16_t size); -u8_t pbuf_header(struct pbuf *p, s16_t header_size); -void pbuf_ref(struct pbuf *p); -u8_t pbuf_free(struct pbuf *p); -u8_t pbuf_clen(struct pbuf *p); -void pbuf_cat(struct pbuf *head, struct pbuf *tail); -void pbuf_chain(struct pbuf *head, struct pbuf *tail); -struct pbuf *pbuf_dechain(struct pbuf *p); -err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); -u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); -err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); -struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); -#if LWIP_CHECKSUM_ON_COPY -err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum); -#endif /* LWIP_CHECKSUM_ON_COPY */ - -u8_t pbuf_get_at(struct pbuf* p, u16_t offset); -u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); -u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); -u16_t pbuf_strstr(struct pbuf* p, const char* substr); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_PBUF_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/raw.h b/external/badvpn_dns/lwip/src/include/lwip/raw.h deleted file mode 100644 index f0c8ed4..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/raw.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_RAW_H__ -#define __LWIP_RAW_H__ - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct raw_pcb; - -/** Function prototype for raw pcb receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - ip_addr_t *addr); - -#if LWIP_IPV6 -/** Function prototype for raw pcb IPv6 receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IPv6 address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_ip6_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - ip6_addr_t *addr); -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV6 -#define RAW_PCB_RECV_IP6 raw_recv_ip6_fn ip6; -#else -#define RAW_PCB_RECV_IP6 -#endif /* LWIP_IPV6 */ - -struct raw_pcb { - /* Common members of all PCB types */ - IP_PCB; - - struct raw_pcb *next; - - u8_t protocol; - - /** receive callback function */ - union { - raw_recv_fn ip4; - RAW_PCB_RECV_IP6 - } recv; - /* user-supplied argument for the recv callback */ - void *recv_arg; -}; - -/* The following functions is the application layer interface to the - RAW code. */ -struct raw_pcb * raw_new (u8_t proto); -void raw_remove (struct raw_pcb *pcb); -err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); -err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); - -void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); -err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); -err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); - -#if LWIP_IPV6 -struct raw_pcb * raw_new_ip6 (u8_t proto); -#define raw_bind_ip6(pcb, ip6addr) raw_bind(pcb, ip6_2_ip(ip6addr)) -#define raw_connect_ip6(pcb, ip6addr) raw_connect(pcb, ip6_2_ip(ip6addr)) -#define raw_recv_ip6(pcb, recv_ip6_fn, recv_arg) raw_recv(pcb, (raw_recv_fn)recv_ip6_fn, recv_arg) -#define raw_sendto_ip6(pcb, pbuf, ip6addr) raw_sendto(pcb, pbuf, ip6_2_ip(ip6addr)) -#endif /* LWIP_IPV6 */ - -/* The following functions are the lower layer interface to RAW. */ -u8_t raw_input (struct pbuf *p, struct netif *inp); -#define raw_init() /* Compatibility define, not init needed. */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW */ - -#endif /* __LWIP_RAW_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/sio.h b/external/badvpn_dns/lwip/src/include/lwip/sio.h deleted file mode 100644 index 28ae2f2..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/sio.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - */ - -/* - * This is the interface to the platform specific serial IO module - * It needs to be implemented by those platforms which need SLIP or PPP - */ - -#ifndef __SIO_H__ -#define __SIO_H__ - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If you want to define sio_fd_t elsewhere or differently, - define this in your cc.h file. */ -#ifndef __sio_fd_t_defined -typedef void * sio_fd_t; -#endif - -/* The following functions can be defined to something else in your cc.h file - or be implemented in your custom sio.c file. */ - -#ifndef sio_open -/** - * Opens a serial device for communication. - * - * @param devnum device number - * @return handle to serial device if successful, NULL otherwise - */ -sio_fd_t sio_open(u8_t devnum); -#endif - -#ifndef sio_send -/** - * Sends a single character to the serial device. - * - * @param c character to send - * @param fd serial device handle - * - * @note This function will block until the character can be sent. - */ -void sio_send(u8_t c, sio_fd_t fd); -#endif - -#ifndef sio_recv -/** - * Receives a single character from the serial device. - * - * @param fd serial device handle - * - * @note This function will block until a character is received. - */ -u8_t sio_recv(sio_fd_t fd); -#endif - -#ifndef sio_read -/** - * Reads from the serial device. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort - * - * @note This function will block until data can be received. The blocking - * can be cancelled by calling sio_read_abort(). - */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_tryread -/** - * Tries to read from the serial device. Same as sio_read but returns - * immediately if no data is available and never blocks. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_write -/** - * Writes to the serial device. - * - * @param fd serial device handle - * @param data pointer to data to send - * @param len length (in bytes) of data to send - * @return number of bytes actually sent - * - * @note This function will block until all data can be sent. - */ -u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_read_abort -/** - * Aborts a blocking sio_read() call. - * - * @param fd serial device handle - */ -void sio_read_abort(sio_fd_t fd); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __SIO_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/snmp.h b/external/badvpn_dns/lwip/src/include/lwip/snmp.h deleted file mode 100644 index 2ed043d..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/snmp.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Leon Woestenberg leon.woestenberg@axon.tv - * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg leon.woestenberg@axon.tv - * - */ -#ifndef __LWIP_SNMP_H__ -#define __LWIP_SNMP_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/ip_addr.h" - -struct udp_pcb; -struct netif; - -/** - * @see RFC1213, "MIB-II, 6. Definitions" - */ -enum snmp_ifType { - snmp_ifType_other=1, /* none of the following */ - snmp_ifType_regular1822, - snmp_ifType_hdh1822, - snmp_ifType_ddn_x25, - snmp_ifType_rfc877_x25, - snmp_ifType_ethernet_csmacd, - snmp_ifType_iso88023_csmacd, - snmp_ifType_iso88024_tokenBus, - snmp_ifType_iso88025_tokenRing, - snmp_ifType_iso88026_man, - snmp_ifType_starLan, - snmp_ifType_proteon_10Mbit, - snmp_ifType_proteon_80Mbit, - snmp_ifType_hyperchannel, - snmp_ifType_fddi, - snmp_ifType_lapb, - snmp_ifType_sdlc, - snmp_ifType_ds1, /* T-1 */ - snmp_ifType_e1, /* european equiv. of T-1 */ - snmp_ifType_basicISDN, - snmp_ifType_primaryISDN, /* proprietary serial */ - snmp_ifType_propPointToPointSerial, - snmp_ifType_ppp, - snmp_ifType_softwareLoopback, - snmp_ifType_eon, /* CLNP over IP [11] */ - snmp_ifType_ethernet_3Mbit, - snmp_ifType_nsip, /* XNS over IP */ - snmp_ifType_slip, /* generic SLIP */ - snmp_ifType_ultra, /* ULTRA technologies */ - snmp_ifType_ds3, /* T-3 */ - snmp_ifType_sip, /* SMDS */ - snmp_ifType_frame_relay -}; - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -/** SNMP "sysuptime" Interval */ -#define SNMP_SYSUPTIME_INTERVAL 10 - -/** fixed maximum length for object identifier type */ -#define LWIP_SNMP_OBJ_ID_LEN 32 - -/** internal object identifier representation */ -struct snmp_obj_id -{ - u8_t len; - s32_t id[LWIP_SNMP_OBJ_ID_LEN]; -}; - -/* system */ -void snmp_set_sysdesr(u8_t* str, u8_t* len); -void snmp_set_sysobjid(struct snmp_obj_id *oid); -void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); -void snmp_inc_sysuptime(void); -void snmp_add_sysuptime(u32_t value); -void snmp_get_sysuptime(u32_t *value); -void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); -void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); -void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); - -/* network interface */ -void snmp_add_ifinoctets(struct netif *ni, u32_t value); -void snmp_inc_ifinucastpkts(struct netif *ni); -void snmp_inc_ifinnucastpkts(struct netif *ni); -void snmp_inc_ifindiscards(struct netif *ni); -void snmp_add_ifoutoctets(struct netif *ni, u32_t value); -void snmp_inc_ifoutucastpkts(struct netif *ni); -void snmp_inc_ifoutnucastpkts(struct netif *ni); -void snmp_inc_ifoutdiscards(struct netif *ni); -void snmp_inc_iflist(void); -void snmp_dec_iflist(void); - -/* ARP (for atTable and ipNetToMediaTable) */ -void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); -void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); - -/* IP */ -void snmp_inc_ipinreceives(void); -void snmp_inc_ipinhdrerrors(void); -void snmp_inc_ipinaddrerrors(void); -void snmp_inc_ipforwdatagrams(void); -void snmp_inc_ipinunknownprotos(void); -void snmp_inc_ipindiscards(void); -void snmp_inc_ipindelivers(void); -void snmp_inc_ipoutrequests(void); -void snmp_inc_ipoutdiscards(void); -void snmp_inc_ipoutnoroutes(void); -void snmp_inc_ipreasmreqds(void); -void snmp_inc_ipreasmoks(void); -void snmp_inc_ipreasmfails(void); -void snmp_inc_ipfragoks(void); -void snmp_inc_ipfragfails(void); -void snmp_inc_ipfragcreates(void); -void snmp_inc_iproutingdiscards(void); -void snmp_insert_ipaddridx_tree(struct netif *ni); -void snmp_delete_ipaddridx_tree(struct netif *ni); -void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); -void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); - -/* ICMP */ -void snmp_inc_icmpinmsgs(void); -void snmp_inc_icmpinerrors(void); -void snmp_inc_icmpindestunreachs(void); -void snmp_inc_icmpintimeexcds(void); -void snmp_inc_icmpinparmprobs(void); -void snmp_inc_icmpinsrcquenchs(void); -void snmp_inc_icmpinredirects(void); -void snmp_inc_icmpinechos(void); -void snmp_inc_icmpinechoreps(void); -void snmp_inc_icmpintimestamps(void); -void snmp_inc_icmpintimestampreps(void); -void snmp_inc_icmpinaddrmasks(void); -void snmp_inc_icmpinaddrmaskreps(void); -void snmp_inc_icmpoutmsgs(void); -void snmp_inc_icmpouterrors(void); -void snmp_inc_icmpoutdestunreachs(void); -void snmp_inc_icmpouttimeexcds(void); -void snmp_inc_icmpoutparmprobs(void); -void snmp_inc_icmpoutsrcquenchs(void); -void snmp_inc_icmpoutredirects(void); -void snmp_inc_icmpoutechos(void); -void snmp_inc_icmpoutechoreps(void); -void snmp_inc_icmpouttimestamps(void); -void snmp_inc_icmpouttimestampreps(void); -void snmp_inc_icmpoutaddrmasks(void); -void snmp_inc_icmpoutaddrmaskreps(void); - -/* TCP */ -void snmp_inc_tcpactiveopens(void); -void snmp_inc_tcppassiveopens(void); -void snmp_inc_tcpattemptfails(void); -void snmp_inc_tcpestabresets(void); -void snmp_inc_tcpinsegs(void); -void snmp_inc_tcpoutsegs(void); -void snmp_inc_tcpretranssegs(void); -void snmp_inc_tcpinerrs(void); -void snmp_inc_tcpoutrsts(void); - -/* UDP */ -void snmp_inc_udpindatagrams(void); -void snmp_inc_udpnoports(void); -void snmp_inc_udpinerrors(void); -void snmp_inc_udpoutdatagrams(void); -void snmp_insert_udpidx_tree(struct udp_pcb *pcb); -void snmp_delete_udpidx_tree(struct udp_pcb *pcb); - -/* SNMP */ -void snmp_inc_snmpinpkts(void); -void snmp_inc_snmpoutpkts(void); -void snmp_inc_snmpinbadversions(void); -void snmp_inc_snmpinbadcommunitynames(void); -void snmp_inc_snmpinbadcommunityuses(void); -void snmp_inc_snmpinasnparseerrs(void); -void snmp_inc_snmpintoobigs(void); -void snmp_inc_snmpinnosuchnames(void); -void snmp_inc_snmpinbadvalues(void); -void snmp_inc_snmpinreadonlys(void); -void snmp_inc_snmpingenerrs(void); -void snmp_add_snmpintotalreqvars(u8_t value); -void snmp_add_snmpintotalsetvars(u8_t value); -void snmp_inc_snmpingetrequests(void); -void snmp_inc_snmpingetnexts(void); -void snmp_inc_snmpinsetrequests(void); -void snmp_inc_snmpingetresponses(void); -void snmp_inc_snmpintraps(void); -void snmp_inc_snmpouttoobigs(void); -void snmp_inc_snmpoutnosuchnames(void); -void snmp_inc_snmpoutbadvalues(void); -void snmp_inc_snmpoutgenerrs(void); -void snmp_inc_snmpoutgetrequests(void); -void snmp_inc_snmpoutgetnexts(void); -void snmp_inc_snmpoutsetrequests(void); -void snmp_inc_snmpoutgetresponses(void); -void snmp_inc_snmpouttraps(void); -void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); -void snmp_set_snmpenableauthentraps(u8_t *value); -void snmp_get_snmpenableauthentraps(u8_t *value); - -/* LWIP_SNMP support not available */ -/* define everything to be empty */ -#else - -/* system */ -#define snmp_set_sysdesr(str, len) -#define snmp_set_sysobjid(oid); -#define snmp_get_sysobjid_ptr(oid) -#define snmp_inc_sysuptime() -#define snmp_add_sysuptime(value) -#define snmp_get_sysuptime(value) -#define snmp_set_syscontact(ocstr, ocstrlen); -#define snmp_set_sysname(ocstr, ocstrlen); -#define snmp_set_syslocation(ocstr, ocstrlen); - -/* network interface */ -#define snmp_add_ifinoctets(ni,value) -#define snmp_inc_ifinucastpkts(ni) -#define snmp_inc_ifinnucastpkts(ni) -#define snmp_inc_ifindiscards(ni) -#define snmp_add_ifoutoctets(ni,value) -#define snmp_inc_ifoutucastpkts(ni) -#define snmp_inc_ifoutnucastpkts(ni) -#define snmp_inc_ifoutdiscards(ni) -#define snmp_inc_iflist() -#define snmp_dec_iflist() - -/* ARP */ -#define snmp_insert_arpidx_tree(ni,ip) -#define snmp_delete_arpidx_tree(ni,ip) - -/* IP */ -#define snmp_inc_ipinreceives() -#define snmp_inc_ipinhdrerrors() -#define snmp_inc_ipinaddrerrors() -#define snmp_inc_ipforwdatagrams() -#define snmp_inc_ipinunknownprotos() -#define snmp_inc_ipindiscards() -#define snmp_inc_ipindelivers() -#define snmp_inc_ipoutrequests() -#define snmp_inc_ipoutdiscards() -#define snmp_inc_ipoutnoroutes() -#define snmp_inc_ipreasmreqds() -#define snmp_inc_ipreasmoks() -#define snmp_inc_ipreasmfails() -#define snmp_inc_ipfragoks() -#define snmp_inc_ipfragfails() -#define snmp_inc_ipfragcreates() -#define snmp_inc_iproutingdiscards() -#define snmp_insert_ipaddridx_tree(ni) -#define snmp_delete_ipaddridx_tree(ni) -#define snmp_insert_iprteidx_tree(dflt, ni) -#define snmp_delete_iprteidx_tree(dflt, ni) - -/* ICMP */ -#define snmp_inc_icmpinmsgs() -#define snmp_inc_icmpinerrors() -#define snmp_inc_icmpindestunreachs() -#define snmp_inc_icmpintimeexcds() -#define snmp_inc_icmpinparmprobs() -#define snmp_inc_icmpinsrcquenchs() -#define snmp_inc_icmpinredirects() -#define snmp_inc_icmpinechos() -#define snmp_inc_icmpinechoreps() -#define snmp_inc_icmpintimestamps() -#define snmp_inc_icmpintimestampreps() -#define snmp_inc_icmpinaddrmasks() -#define snmp_inc_icmpinaddrmaskreps() -#define snmp_inc_icmpoutmsgs() -#define snmp_inc_icmpouterrors() -#define snmp_inc_icmpoutdestunreachs() -#define snmp_inc_icmpouttimeexcds() -#define snmp_inc_icmpoutparmprobs() -#define snmp_inc_icmpoutsrcquenchs() -#define snmp_inc_icmpoutredirects() -#define snmp_inc_icmpoutechos() -#define snmp_inc_icmpoutechoreps() -#define snmp_inc_icmpouttimestamps() -#define snmp_inc_icmpouttimestampreps() -#define snmp_inc_icmpoutaddrmasks() -#define snmp_inc_icmpoutaddrmaskreps() -/* TCP */ -#define snmp_inc_tcpactiveopens() -#define snmp_inc_tcppassiveopens() -#define snmp_inc_tcpattemptfails() -#define snmp_inc_tcpestabresets() -#define snmp_inc_tcpinsegs() -#define snmp_inc_tcpoutsegs() -#define snmp_inc_tcpretranssegs() -#define snmp_inc_tcpinerrs() -#define snmp_inc_tcpoutrsts() - -/* UDP */ -#define snmp_inc_udpindatagrams() -#define snmp_inc_udpnoports() -#define snmp_inc_udpinerrors() -#define snmp_inc_udpoutdatagrams() -#define snmp_insert_udpidx_tree(pcb) -#define snmp_delete_udpidx_tree(pcb) - -/* SNMP */ -#define snmp_inc_snmpinpkts() -#define snmp_inc_snmpoutpkts() -#define snmp_inc_snmpinbadversions() -#define snmp_inc_snmpinbadcommunitynames() -#define snmp_inc_snmpinbadcommunityuses() -#define snmp_inc_snmpinasnparseerrs() -#define snmp_inc_snmpintoobigs() -#define snmp_inc_snmpinnosuchnames() -#define snmp_inc_snmpinbadvalues() -#define snmp_inc_snmpinreadonlys() -#define snmp_inc_snmpingenerrs() -#define snmp_add_snmpintotalreqvars(value) -#define snmp_add_snmpintotalsetvars(value) -#define snmp_inc_snmpingetrequests() -#define snmp_inc_snmpingetnexts() -#define snmp_inc_snmpinsetrequests() -#define snmp_inc_snmpingetresponses() -#define snmp_inc_snmpintraps() -#define snmp_inc_snmpouttoobigs() -#define snmp_inc_snmpoutnosuchnames() -#define snmp_inc_snmpoutbadvalues() -#define snmp_inc_snmpoutgenerrs() -#define snmp_inc_snmpoutgetrequests() -#define snmp_inc_snmpoutgetnexts() -#define snmp_inc_snmpoutsetrequests() -#define snmp_inc_snmpoutgetresponses() -#define snmp_inc_snmpouttraps() -#define snmp_get_snmpgrpid_ptr(oid) -#define snmp_set_snmpenableauthentraps(value) -#define snmp_get_snmpenableauthentraps(value) - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_SNMP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/snmp_asn1.h b/external/badvpn_dns/lwip/src/include/lwip/snmp_asn1.h deleted file mode 100644 index 605fa3f..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/snmp_asn1.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) codec. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#ifndef __LWIP_SNMP_ASN1_H__ -#define __LWIP_SNMP_ASN1_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/snmp.h" - -#if LWIP_SNMP - -#ifdef __cplusplus -extern "C" { -#endif - -#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ -#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ -#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ - -#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ -#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ - -/* universal tags */ -#define SNMP_ASN1_INTEG 2 -#define SNMP_ASN1_OC_STR 4 -#define SNMP_ASN1_NUL 5 -#define SNMP_ASN1_OBJ_ID 6 -#define SNMP_ASN1_SEQ 16 - -/* application specific (SNMP) tags */ -#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ -#define SNMP_ASN1_COUNTER 1 /* u32_t */ -#define SNMP_ASN1_GAUGE 2 /* u32_t */ -#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ -#define SNMP_ASN1_OPAQUE 4 /* octet string */ - -/* context specific (SNMP) tags */ -#define SNMP_ASN1_PDU_GET_REQ 0 -#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 -#define SNMP_ASN1_PDU_GET_RESP 2 -#define SNMP_ASN1_PDU_SET_REQ 3 -#define SNMP_ASN1_PDU_TRAP 4 - -err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); -err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); -err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); -err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); -err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); -err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); - -void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); -void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); -void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); -void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); -err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); -err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); -err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); -err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); -err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); -err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_ASN1_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/snmp_msg.h b/external/badvpn_dns/lwip/src/include/lwip/snmp_msg.h deleted file mode 100644 index 1183e3a..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/snmp_msg.h +++ /dev/null @@ -1,315 +0,0 @@ -/** - * @file - * SNMP Agent message handling structures. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#ifndef __LWIP_SNMP_MSG_H__ -#define __LWIP_SNMP_MSG_H__ - -#include "lwip/opt.h" -#include "lwip/snmp.h" -#include "lwip/snmp_structs.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#if LWIP_SNMP - -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -#include "private_mib.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* The listen port of the SNMP agent. Clients have to make their requests to - this port. Most standard clients won't work if you change this! */ -#ifndef SNMP_IN_PORT -#define SNMP_IN_PORT 161 -#endif -/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't - work if you change this! */ -#ifndef SNMP_TRAP_PORT -#define SNMP_TRAP_PORT 162 -#endif - -#define SNMP_ES_NOERROR 0 -#define SNMP_ES_TOOBIG 1 -#define SNMP_ES_NOSUCHNAME 2 -#define SNMP_ES_BADVALUE 3 -#define SNMP_ES_READONLY 4 -#define SNMP_ES_GENERROR 5 - -#define SNMP_GENTRAP_COLDSTART 0 -#define SNMP_GENTRAP_WARMSTART 1 -#define SNMP_GENTRAP_AUTHFAIL 4 -#define SNMP_GENTRAP_ENTERPRISESPC 6 - -struct snmp_varbind -{ - /* next pointer, NULL for last in list */ - struct snmp_varbind *next; - /* previous pointer, NULL for first in list */ - struct snmp_varbind *prev; - - /* object identifier length (in s32_t) */ - u8_t ident_len; - /* object identifier array */ - s32_t *ident; - - /* object value ASN1 type */ - u8_t value_type; - /* object value length (in u8_t) */ - u8_t value_len; - /* object value */ - void *value; - - /* encoding varbind seq length length */ - u8_t seqlenlen; - /* encoding object identifier length length */ - u8_t olenlen; - /* encoding object value length length */ - u8_t vlenlen; - /* encoding varbind seq length */ - u16_t seqlen; - /* encoding object identifier length */ - u16_t olen; - /* encoding object value length */ - u16_t vlen; -}; - -struct snmp_varbind_root -{ - struct snmp_varbind *head; - struct snmp_varbind *tail; - /* number of variable bindings in list */ - u8_t count; - /* encoding varbind-list seq length length */ - u8_t seqlenlen; - /* encoding varbind-list seq length */ - u16_t seqlen; -}; - -/** output response message header length fields */ -struct snmp_resp_header_lengths -{ - /* encoding error-index length length */ - u8_t erridxlenlen; - /* encoding error-status length length */ - u8_t errstatlenlen; - /* encoding request id length length */ - u8_t ridlenlen; - /* encoding pdu length length */ - u8_t pdulenlen; - /* encoding community length length */ - u8_t comlenlen; - /* encoding version length length */ - u8_t verlenlen; - /* encoding sequence length length */ - u8_t seqlenlen; - - /* encoding error-index length */ - u16_t erridxlen; - /* encoding error-status length */ - u16_t errstatlen; - /* encoding request id length */ - u16_t ridlen; - /* encoding pdu length */ - u16_t pdulen; - /* encoding community length */ - u16_t comlen; - /* encoding version length */ - u16_t verlen; - /* encoding sequence length */ - u16_t seqlen; -}; - -/** output response message header length fields */ -struct snmp_trap_header_lengths -{ - /* encoding timestamp length length */ - u8_t tslenlen; - /* encoding specific-trap length length */ - u8_t strplenlen; - /* encoding generic-trap length length */ - u8_t gtrplenlen; - /* encoding agent-addr length length */ - u8_t aaddrlenlen; - /* encoding enterprise-id length length */ - u8_t eidlenlen; - /* encoding pdu length length */ - u8_t pdulenlen; - /* encoding community length length */ - u8_t comlenlen; - /* encoding version length length */ - u8_t verlenlen; - /* encoding sequence length length */ - u8_t seqlenlen; - - /* encoding timestamp length */ - u16_t tslen; - /* encoding specific-trap length */ - u16_t strplen; - /* encoding generic-trap length */ - u16_t gtrplen; - /* encoding agent-addr length */ - u16_t aaddrlen; - /* encoding enterprise-id length */ - u16_t eidlen; - /* encoding pdu length */ - u16_t pdulen; - /* encoding community length */ - u16_t comlen; - /* encoding version length */ - u16_t verlen; - /* encoding sequence length */ - u16_t seqlen; -}; - -/* Accepting new SNMP messages. */ -#define SNMP_MSG_EMPTY 0 -/* Search for matching object for variable binding. */ -#define SNMP_MSG_SEARCH_OBJ 1 -/* Perform SNMP operation on in-memory object. - Pass-through states, for symmetry only. */ -#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 -#define SNMP_MSG_INTERNAL_GET_VALUE 3 -#define SNMP_MSG_INTERNAL_SET_TEST 4 -#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 -#define SNMP_MSG_INTERNAL_SET_VALUE 6 -/* Perform SNMP operation on object located externally. - In theory this could be used for building a proxy agent. - Practical use is for an enterprise spc. app. gateway. */ -#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 -#define SNMP_MSG_EXTERNAL_GET_VALUE 8 -#define SNMP_MSG_EXTERNAL_SET_TEST 9 -#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 -#define SNMP_MSG_EXTERNAL_SET_VALUE 11 - -#define SNMP_COMMUNITY_STR_LEN 64 -struct snmp_msg_pstat -{ - /* lwIP local port (161) binding */ - struct udp_pcb *pcb; - /* source IP address */ - ip_addr_t sip; - /* source UDP port */ - u16_t sp; - /* request type */ - u8_t rt; - /* request ID */ - s32_t rid; - /* error status */ - s32_t error_status; - /* error index */ - s32_t error_index; - /* community name (zero terminated) */ - u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; - /* community string length (exclusive zero term) */ - u8_t com_strlen; - /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ - u8_t state; - /* saved arguments for MSG_EXTERNAL_x */ - struct mib_external_node *ext_mib_node; - struct snmp_name_ptr ext_name_ptr; - struct obj_def ext_object_def; - struct snmp_obj_id ext_oid; - /* index into input variable binding list */ - u8_t vb_idx; - /* ptr into input variable binding list */ - struct snmp_varbind *vb_ptr; - /* list of variable bindings from input */ - struct snmp_varbind_root invb; - /* list of variable bindings to output */ - struct snmp_varbind_root outvb; - /* output response lengths used in ASN encoding */ - struct snmp_resp_header_lengths rhl; -}; - -struct snmp_msg_trap -{ - /* lwIP local port (161) binding */ - struct udp_pcb *pcb; - /* destination IP address in network order */ - ip_addr_t dip; - - /* source enterprise ID (sysObjectID) */ - struct snmp_obj_id *enterprise; - /* source IP address, raw network order format */ - u8_t sip_raw[4]; - /* generic trap code */ - u32_t gen_trap; - /* specific trap code */ - u32_t spc_trap; - /* timestamp */ - u32_t ts; - /* list of variable bindings to output */ - struct snmp_varbind_root outvb; - /* output trap lengths used in ASN encoding */ - struct snmp_trap_header_lengths thl; -}; - -/** Agent Version constant, 0 = v1 oddity */ -extern const s32_t snmp_version; -/** Agent default "public" community string */ -extern const char snmp_publiccommunity[7]; - -extern struct snmp_msg_trap trap_msg; - -/** Agent setup, start listening to port 161. */ -void snmp_init(void); -void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); -void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); - -/** Varbind-list functions. */ -struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); -void snmp_varbind_free(struct snmp_varbind *vb); -void snmp_varbind_list_free(struct snmp_varbind_root *root); -void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); -struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); - -/** Handle an internal (recv) or external (private response) event. */ -void snmp_msg_event(u8_t request_id); -err_t snmp_send_response(struct snmp_msg_pstat *m_stat); -err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); -void snmp_coldstart_trap(void); -void snmp_authfail_trap(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_MSG_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/snmp_structs.h b/external/badvpn_dns/lwip/src/include/lwip/snmp_structs.h deleted file mode 100644 index 0d3b46a..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/snmp_structs.h +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @file - * Generic MIB tree structures. - * - * @todo namespace prefixes - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons christiaan.simons@axon.tv - */ - -#ifndef __LWIP_SNMP_STRUCTS_H__ -#define __LWIP_SNMP_STRUCTS_H__ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" - -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -#include "private_mib.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* MIB object instance */ -#define MIB_OBJECT_NONE 0 -#define MIB_OBJECT_SCALAR 1 -#define MIB_OBJECT_TAB 2 - -/* MIB access types */ -#define MIB_ACCESS_READ 1 -#define MIB_ACCESS_WRITE 2 - -/* MIB object access */ -#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ -#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) -#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE -#define MIB_OBJECT_NOT_ACCESSIBLE 0 - -/** object definition returned by (get_object_def)() */ -struct obj_def -{ - /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ - u8_t instance; - /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ - u8_t access; - /* ASN type for this object */ - u8_t asn_type; - /* value length (host length) */ - u16_t v_len; - /* length of instance part of supplied object identifier */ - u8_t id_inst_len; - /* instance part of supplied object identifier */ - s32_t *id_inst_ptr; -}; - -struct snmp_name_ptr -{ - u8_t ident_len; - s32_t *ident; -}; - -/** MIB const scalar (.0) node */ -#define MIB_NODE_SC 0x01 -/** MIB const array node */ -#define MIB_NODE_AR 0x02 -/** MIB array node (mem_malloced from RAM) */ -#define MIB_NODE_RA 0x03 -/** MIB list root node (mem_malloced from RAM) */ -#define MIB_NODE_LR 0x04 -/** MIB node for external objects */ -#define MIB_NODE_EX 0x05 - -/** node "base class" layout, the mandatory fields for a node */ -struct mib_node -{ - /** returns struct obj_def for the given object identifier */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - /** returns object value for the given object identifier, - @note the caller must allocate at least len bytes for the value */ - void (*get_value)(struct obj_def *od, u16_t len, void *value); - /** tests length and/or range BEFORE setting */ - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - /** sets object value, only to be called when set_test() */ - void (*set_value)(struct obj_def *od, u16_t len, void *value); - /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ - u8_t node_type; - /* array or max list length */ - u16_t maxlength; -}; - -/** derived node for scalars .0 index */ -typedef struct mib_node mib_scalar_node; - -/** derived node, points to a fixed size const array - of sub-identifiers plus a 'child' pointer */ -struct mib_array_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - const s32_t *objid; - struct mib_node* const *nptr; -}; - -/** derived node, points to a fixed size mem_malloced array - of sub-identifiers plus a 'child' pointer */ -struct mib_ram_array_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* aditional struct members */ - s32_t *objid; - struct mib_node **nptr; -}; - -struct mib_list_node -{ - struct mib_list_node *prev; - struct mib_list_node *next; - s32_t objid; - struct mib_node *nptr; -}; - -/** derived node, points to a doubly linked list - of sub-identifiers plus a 'child' pointer */ -struct mib_list_rootnode -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - struct mib_list_node *head; - struct mib_list_node *tail; - /* counts list nodes in list */ - u16_t count; -}; - -/** derived node, has access functions for mib object in external memory or device - using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ -struct mib_external_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - /** points to an external (in memory) record of some sort of addressing - information, passed to and interpreted by the funtions below */ - void* addr_inf; - /** tree levels under this node */ - u8_t tree_levels; - /** number of objects at this level */ - u16_t (*level_length)(void* addr_inf, u8_t level); - /** compares object sub identifier with external id - return zero when equal, nonzero when unequal */ - s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); - void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); - - /** async Questions */ - void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); - void (*get_value_q)(u8_t rid, struct obj_def *od); - void (*set_test_q)(u8_t rid, struct obj_def *od); - void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); - /** async Answers */ - void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - /** async Panic Close (agent returns error reply, - e.g. used for external transaction cleanup) */ - void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); - void (*get_value_pc)(u8_t rid, struct obj_def *od); - void (*set_test_pc)(u8_t rid, struct obj_def *od); - void (*set_value_pc)(u8_t rid, struct obj_def *od); -}; - -/** export MIB tree from mib2.c */ -extern const struct mib_array_node internet; - -/** dummy function pointers for non-leaf MIB nodes from mib2.c */ -void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -void noleafs_get_value(struct obj_def *od, u16_t len, void *value); -u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); -void noleafs_set_value(struct obj_def *od, u16_t len, void *value); - -void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); -void snmp_iptooid(ip_addr_t *ip, s32_t *ident); -void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); -void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); - -struct mib_list_node* snmp_mib_ln_alloc(s32_t id); -void snmp_mib_ln_free(struct mib_list_node *ln); -struct mib_list_rootnode* snmp_mib_lrn_alloc(void); -void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); - -s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); -s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); -struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); - -struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); -struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); -u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); -u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_STRUCTS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/sockets.h b/external/badvpn_dns/lwip/src/include/lwip/sockets.h deleted file mode 100644 index 7346137..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/sockets.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - - -#ifndef __LWIP_SOCKETS_H__ -#define __LWIP_SOCKETS_H__ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include <stddef.h> /* for size_t */ - -#include "lwip/ip_addr.h" -#include "lwip/inet.h" -#include "lwip/inet6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* members are in network byte order */ -struct sockaddr_in { - u8_t sin_len; - u8_t sin_family; - u16_t sin_port; - struct in_addr sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; - -#if LWIP_IPV6 -struct sockaddr_in6 { - u8_t sin6_len; /* length of this structure */ - u8_t sin6_family; /* AF_INET6 */ - u16_t sin6_port; /* Transport layer port # */ - u32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ -}; -#endif /* LWIP_IPV6 */ - -struct sockaddr { - u8_t sa_len; - u8_t sa_family; -#if LWIP_IPV6 - u8_t sa_data[22]; -#else /* LWIP_IPV6 */ - u8_t sa_data[14]; -#endif /* LWIP_IPV6 */ -}; - -/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) -typedef u32_t socklen_t; -#endif - -/* Socket protocol types (TCP/UDP/RAW) */ -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 - -/* - * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) - */ -#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ -#define SO_KEEPALIVE 0x0008 /* keep connections alive */ -#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ -#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ -#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ - -#define SO_DONTLINGER ((int)(~SO_LINGER)) - -/* - * Additional options, not kept in so_options. - */ -#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ -#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ -#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ -#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ -#define SO_RCVTIMEO 0x1006 /* receive timeout */ -#define SO_ERROR 0x1007 /* get error status and clear */ -#define SO_TYPE 0x1008 /* get socket type */ -#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ -#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ - - -/* - * Structure used for manipulating linger option. - */ -struct linger { - int l_onoff; /* option on/off */ - int l_linger; /* linger time */ -}; - -/* - * Level number for (get/set)sockopt() to apply to socket itself. - */ -#define SOL_SOCKET 0xfff /* options for socket level */ - - -#define AF_UNSPEC 0 -#define AF_INET 2 -#if LWIP_IPV6 -#define AF_INET6 10 -#else /* LWIP_IPV6 */ -#define AF_INET6 AF_UNSPEC -#endif /* LWIP_IPV6 */ -#define PF_INET AF_INET -#define PF_INET6 AF_INET6 -#define PF_UNSPEC AF_UNSPEC - -#define IPPROTO_IP 0 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#if LWIP_IPV6 -#define IPPROTO_IPV6 41 -#endif /* LWIP_IPV6 */ -#define IPPROTO_UDPLITE 136 - -/* Flags we can use with send and recv. */ -#define MSG_PEEK 0x01 /* Peeks at an incoming message */ -#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ -#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ -#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ -#define MSG_MORE 0x10 /* Sender will send more */ - - -/* - * Options for level IPPROTO_IP - */ -#define IP_TOS 1 -#define IP_TTL 2 - -#if LWIP_TCP -/* - * Options for level IPPROTO_TCP - */ -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ -#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ -#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ -#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* - * Options for level IPPROTO_IPV6 - */ -#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* - * Options for level IPPROTO_UDPLITE - */ -#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ -#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ -#endif /* LWIP_UDP && LWIP_UDPLITE*/ - - -#if LWIP_IGMP -/* - * Options and types for UDP multicast traffic handling - */ -#define IP_ADD_MEMBERSHIP 3 -#define IP_DROP_MEMBERSHIP 4 -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 - -typedef struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -} ip_mreq; -#endif /* LWIP_IGMP */ - -/* - * The Type of Service provides an indication of the abstract - * parameters of the quality of service desired. These parameters are - * to be used to guide the selection of the actual service parameters - * when transmitting a datagram through a particular network. Several - * networks offer service precedence, which somehow treats high - * precedence traffic as more important than other traffic (generally - * by accepting only traffic above a certain precedence at time of high - * load). The major choice is a three way tradeoff between low-delay, - * high-reliability, and high-throughput. - * The use of the Delay, Throughput, and Reliability indications may - * increase the cost (in some sense) of the service. In many networks - * better performance for one of these parameters is coupled with worse - * performance on another. Except for very unusual cases at most two - * of these three indications should be set. - */ -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST - -/* - * The Network Control precedence designation is intended to be used - * within a network only. The actual use and control of that - * designation is up to each network. The Internetwork Control - * designation is intended for use by gateway control originators only. - * If the actual use of these precedence designations is of concern to - * a particular network, it is the responsibility of that network to - * control the access to, and use of, those precedence designations. - */ -#define IPTOS_PREC_MASK 0xe0 -#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - - -/* - * Commands for ioctlsocket(), taken from the BSD file fcntl.h. - * lwip_ioctl only supports FIONREAD and FIONBIO, for now - * - * Ioctl's have the command encoded in the lower word, - * and the size of any in or out parameters in the upper - * word. The high 2 bits of the upper word are used - * to encode the in/out status of the parameter; for now - * we restrict parameters to at most 128 bytes. - */ -#if !defined(FIONREAD) || !defined(FIONBIO) -#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ -#define IOC_VOID 0x20000000UL /* no parameters */ -#define IOC_OUT 0x40000000UL /* copy out parameters */ -#define IOC_IN 0x80000000UL /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) - /* 0x20000000 distinguishes new & - old ioctl's */ -#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) - -#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) - -#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) -#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ - -#ifndef FIONREAD -#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ -#endif -#ifndef FIONBIO -#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ -#endif - -/* Socket I/O Controls: unimplemented */ -#ifndef SIOCSHIWAT -#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ -#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ -#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ -#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ -#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ -#endif - -/* commands for fnctl */ -#ifndef F_GETFL -#define F_GETFL 3 -#endif -#ifndef F_SETFL -#define F_SETFL 4 -#endif - -/* File status flags and file access modes for fnctl, - these are bits in an int. */ -#ifndef O_NONBLOCK -#define O_NONBLOCK 1 /* nonblocking I/O */ -#endif -#ifndef O_NDELAY -#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ -#endif - -#ifndef SHUT_RD - #define SHUT_RD 0 - #define SHUT_WR 1 - #define SHUT_RDWR 2 -#endif - -/* FD_SET used for lwip_select */ -#ifndef FD_SET - #undef FD_SETSIZE - /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ - #define FD_SETSIZE MEMP_NUM_NETCONN - #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) - #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) - #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) - #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) - - typedef struct fd_set { - unsigned char fd_bits [(FD_SETSIZE+7)/8]; - } fd_set; - -#endif /* FD_SET */ - -/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided - * by your system, set this to 0 and include <sys/time.h> in cc.h */ -#ifndef LWIP_TIMEVAL_PRIVATE -#define LWIP_TIMEVAL_PRIVATE 1 -#endif - -#if LWIP_TIMEVAL_PRIVATE -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* LWIP_TIMEVAL_PRIVATE */ - -void lwip_socket_init(void); - -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_shutdown(int s, int how); -int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); -int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); -int lwip_close(int s); -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_listen(int s, int backlog); -int lwip_recv(int s, void *mem, size_t len, int flags); -int lwip_read(int s, void *mem, size_t len); -int lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -int lwip_send(int s, const void *dataptr, size_t size, int flags); -int lwip_sendto(int s, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); -int lwip_socket(int domain, int type, int protocol); -int lwip_write(int s, const void *dataptr, size_t size); -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout); -int lwip_ioctl(int s, long cmd, void *argp); -int lwip_fcntl(int s, int cmd, int val); - -#if LWIP_COMPAT_SOCKETS -#define accept(a,b,c) lwip_accept(a,b,c) -#define bind(a,b,c) lwip_bind(a,b,c) -#define shutdown(a,b) lwip_shutdown(a,b) -#define closesocket(s) lwip_close(s) -#define connect(a,b,c) lwip_connect(a,b,c) -#define getsockname(a,b,c) lwip_getsockname(a,b,c) -#define getpeername(a,b,c) lwip_getpeername(a,b,c) -#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) -#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) -#define listen(a,b) lwip_listen(a,b) -#define recv(a,b,c,d) lwip_recv(a,b,c,d) -#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) -#define send(a,b,c,d) lwip_send(a,b,c,d) -#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) -#define socket(a,b,c) lwip_socket(a,b,c) -#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) -#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) - -#if LWIP_POSIX_SOCKETS_IO_NAMES -#define read(a,b,c) lwip_read(a,b,c) -#define write(a,b,c) lwip_write(a,b,c) -#define close(s) lwip_close(s) -#define fcntl(a,b,c) lwip_fcntl(a,b,c) -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ - -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SOCKET */ - -#endif /* __LWIP_SOCKETS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/stats.h b/external/badvpn_dns/lwip/src/include/lwip/stats.h deleted file mode 100644 index d911216..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/stats.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_STATS_H__ -#define __LWIP_STATS_H__ - -#include "lwip/opt.h" - -#include "lwip/mem.h" -#include "lwip/memp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_STATS - -#ifndef LWIP_STATS_LARGE -#define LWIP_STATS_LARGE 0 -#endif - -#if LWIP_STATS_LARGE -#define STAT_COUNTER u32_t -#define STAT_COUNTER_F U32_F -#else -#define STAT_COUNTER u16_t -#define STAT_COUNTER_F U16_F -#endif - -struct stats_proto { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER fw; /* Forwarded packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER rterr; /* Routing error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER opterr; /* Error in options. */ - STAT_COUNTER err; /* Misc error. */ - STAT_COUNTER cachehit; -}; - -struct stats_igmp { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER rx_v1; /* Received v1 frames. */ - STAT_COUNTER rx_group; /* Received group-specific queries. */ - STAT_COUNTER rx_general; /* Received general queries. */ - STAT_COUNTER rx_report; /* Received reports. */ - STAT_COUNTER tx_join; /* Sent joins. */ - STAT_COUNTER tx_leave; /* Sent leaves. */ - STAT_COUNTER tx_report; /* Sent reports. */ -}; - -struct stats_mem { -#ifdef LWIP_DEBUG - const char *name; -#endif /* LWIP_DEBUG */ - mem_size_t avail; - mem_size_t used; - mem_size_t max; - STAT_COUNTER err; - STAT_COUNTER illegal; -}; - -struct stats_syselem { - STAT_COUNTER used; - STAT_COUNTER max; - STAT_COUNTER err; -}; - -struct stats_sys { - struct stats_syselem sem; - struct stats_syselem mutex; - struct stats_syselem mbox; -}; - -struct stats_ { -#if LINK_STATS - struct stats_proto link; -#endif -#if ETHARP_STATS - struct stats_proto etharp; -#endif -#if IPFRAG_STATS - struct stats_proto ip_frag; -#endif -#if IP_STATS - struct stats_proto ip; -#endif -#if ICMP_STATS - struct stats_proto icmp; -#endif -#if IGMP_STATS - struct stats_igmp igmp; -#endif -#if UDP_STATS - struct stats_proto udp; -#endif -#if TCP_STATS - struct stats_proto tcp; -#endif -#if MEM_STATS - struct stats_mem mem; -#endif -#if MEMP_STATS - struct stats_mem memp[MEMP_MAX]; -#endif -#if SYS_STATS - struct stats_sys sys; -#endif -#if IP6_STATS - struct stats_proto ip6; -#endif -#if ICMP6_STATS - struct stats_proto icmp6; -#endif -#if IP6_FRAG_STATS - struct stats_proto ip6_frag; -#endif -#if MLD6_STATS - struct stats_igmp mld6; -#endif -#if ND6_STATS - struct stats_proto nd6; -#endif -}; - -extern struct stats_ lwip_stats; - -void stats_init(void); - -#define STATS_INC(x) ++lwip_stats.x -#define STATS_DEC(x) --lwip_stats.x -#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ - if (lwip_stats.x.max < lwip_stats.x.used) { \ - lwip_stats.x.max = lwip_stats.x.used; \ - } \ - } while(0) -#else /* LWIP_STATS */ -#define stats_init() -#define STATS_INC(x) -#define STATS_DEC(x) -#define STATS_INC_USED(x) -#endif /* LWIP_STATS */ - -#if TCP_STATS -#define TCP_STATS_INC(x) STATS_INC(x) -#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") -#else -#define TCP_STATS_INC(x) -#define TCP_STATS_DISPLAY() -#endif - -#if UDP_STATS -#define UDP_STATS_INC(x) STATS_INC(x) -#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") -#else -#define UDP_STATS_INC(x) -#define UDP_STATS_DISPLAY() -#endif - -#if ICMP_STATS -#define ICMP_STATS_INC(x) STATS_INC(x) -#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") -#else -#define ICMP_STATS_INC(x) -#define ICMP_STATS_DISPLAY() -#endif - -#if IGMP_STATS -#define IGMP_STATS_INC(x) STATS_INC(x) -#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") -#else -#define IGMP_STATS_INC(x) -#define IGMP_STATS_DISPLAY() -#endif - -#if IP_STATS -#define IP_STATS_INC(x) STATS_INC(x) -#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") -#else -#define IP_STATS_INC(x) -#define IP_STATS_DISPLAY() -#endif - -#if IPFRAG_STATS -#define IPFRAG_STATS_INC(x) STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") -#else -#define IPFRAG_STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() -#endif - -#if ETHARP_STATS -#define ETHARP_STATS_INC(x) STATS_INC(x) -#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") -#else -#define ETHARP_STATS_INC(x) -#define ETHARP_STATS_DISPLAY() -#endif - -#if LINK_STATS -#define LINK_STATS_INC(x) STATS_INC(x) -#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") -#else -#define LINK_STATS_INC(x) -#define LINK_STATS_DISPLAY() -#endif - -#if MEM_STATS -#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y -#define MEM_STATS_INC(x) STATS_INC(mem.x) -#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) -#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y -#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") -#else -#define MEM_STATS_AVAIL(x, y) -#define MEM_STATS_INC(x) -#define MEM_STATS_INC_USED(x, y) -#define MEM_STATS_DEC_USED(x, y) -#define MEM_STATS_DISPLAY() -#endif - -#if MEMP_STATS -#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y -#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) -#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) -#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) -#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) -#else -#define MEMP_STATS_AVAIL(x, i, y) -#define MEMP_STATS_INC(x, i) -#define MEMP_STATS_DEC(x, i) -#define MEMP_STATS_INC_USED(x, i) -#define MEMP_STATS_DISPLAY(i) -#endif - -#if SYS_STATS -#define SYS_STATS_INC(x) STATS_INC(sys.x) -#define SYS_STATS_DEC(x) STATS_DEC(sys.x) -#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) -#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) -#else -#define SYS_STATS_INC(x) -#define SYS_STATS_DEC(x) -#define SYS_STATS_INC_USED(x) -#define SYS_STATS_DISPLAY() -#endif - -#if IP6_STATS -#define IP6_STATS_INC(x) STATS_INC(x) -#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") -#else -#define IP6_STATS_INC(x) -#define IP6_STATS_DISPLAY() -#endif - -#if ICMP6_STATS -#define ICMP6_STATS_INC(x) STATS_INC(x) -#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") -#else -#define ICMP6_STATS_INC(x) -#define ICMP6_STATS_DISPLAY() -#endif - -#if IP6_FRAG_STATS -#define IP6_FRAG_STATS_INC(x) STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") -#else -#define IP6_FRAG_STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() -#endif - -#if MLD6_STATS -#define MLD6_STATS_INC(x) STATS_INC(x) -#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") -#else -#define MLD6_STATS_INC(x) -#define MLD6_STATS_DISPLAY() -#endif - -#if ND6_STATS -#define ND6_STATS_INC(x) STATS_INC(x) -#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") -#else -#define ND6_STATS_INC(x) -#define ND6_STATS_DISPLAY() -#endif - -/* Display of statistics */ -#if LWIP_STATS_DISPLAY -void stats_display(void); -void stats_display_proto(struct stats_proto *proto, const char *name); -void stats_display_igmp(struct stats_igmp *igmp, const char *name); -void stats_display_mem(struct stats_mem *mem, const char *name); -void stats_display_memp(struct stats_mem *mem, int index); -void stats_display_sys(struct stats_sys *sys); -#else /* LWIP_STATS_DISPLAY */ -#define stats_display() -#define stats_display_proto(proto, name) -#define stats_display_igmp(igmp, name) -#define stats_display_mem(mem, name) -#define stats_display_memp(mem, index) -#define stats_display_sys(sys) -#endif /* LWIP_STATS_DISPLAY */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_STATS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/sys.h b/external/badvpn_dns/lwip/src/include/lwip/sys.h deleted file mode 100644 index fd45ee8..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/sys.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_SYS_H__ -#define __LWIP_SYS_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if NO_SYS - -/* For a totally minimal and standalone system, we provide null - definitions of the sys_ functions. */ -typedef u8_t sys_sem_t; -typedef u8_t sys_mutex_t; -typedef u8_t sys_mbox_t; - -#define sys_sem_new(s, c) ERR_OK -#define sys_sem_signal(s) -#define sys_sem_wait(s) -#define sys_arch_sem_wait(s,t) -#define sys_sem_free(s) -#define sys_sem_valid(s) 0 -#define sys_sem_set_invalid(s) -#define sys_mutex_new(mu) ERR_OK -#define sys_mutex_lock(mu) -#define sys_mutex_unlock(mu) -#define sys_mutex_free(mu) -#define sys_mutex_valid(mu) 0 -#define sys_mutex_set_invalid(mu) -#define sys_mbox_new(m, s) ERR_OK -#define sys_mbox_fetch(m,d) -#define sys_mbox_tryfetch(m,d) -#define sys_mbox_post(m,d) -#define sys_mbox_trypost(m,d) -#define sys_mbox_free(m) -#define sys_mbox_valid(m) -#define sys_mbox_set_invalid(m) - -#define sys_thread_new(n,t,a,s,p) - -#define sys_msleep(t) - -#else /* NO_SYS */ - -/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ -#define SYS_ARCH_TIMEOUT 0xffffffffUL - -/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. - * For now we use the same magic value, but we allow this to change in future. - */ -#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT - -#include "lwip/err.h" -#include "arch/sys_arch.h" - -/** Function prototype for thread functions */ -typedef void (*lwip_thread_fn)(void *arg); - -/* Function prototypes for functions to be implemented by platform ports - (in sys_arch.c) */ - -/* Mutex functions: */ - -/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores - should be used instead */ -#if LWIP_COMPAT_MUTEX -/* for old ports that don't have mutexes: define them to binary semaphores */ -#define sys_mutex_t sys_sem_t -#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) -#define sys_mutex_lock(mutex) sys_sem_wait(mutex) -#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) -#define sys_mutex_free(mutex) sys_sem_free(mutex) -#define sys_mutex_valid(mutex) sys_sem_valid(mutex) -#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) - -#else /* LWIP_COMPAT_MUTEX */ - -/** Create a new mutex - * @param mutex pointer to the mutex to create - * @return a new mutex */ -err_t sys_mutex_new(sys_mutex_t *mutex); -/** Lock a mutex - * @param mutex the mutex to lock */ -void sys_mutex_lock(sys_mutex_t *mutex); -/** Unlock a mutex - * @param mutex the mutex to unlock */ -void sys_mutex_unlock(sys_mutex_t *mutex); -/** Delete a semaphore - * @param mutex the mutex to delete */ -void sys_mutex_free(sys_mutex_t *mutex); -#ifndef sys_mutex_valid -/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_mutex_valid(sys_mutex_t *mutex); -#endif -#ifndef sys_mutex_set_invalid -/** Set a mutex invalid so that sys_mutex_valid returns 0 */ -void sys_mutex_set_invalid(sys_mutex_t *mutex); -#endif -#endif /* LWIP_COMPAT_MUTEX */ - -/* Semaphore functions: */ - -/** Create a new semaphore - * @param sem pointer to the semaphore to create - * @param count initial count of the semaphore - * @return ERR_OK if successful, another err_t otherwise */ -err_t sys_sem_new(sys_sem_t *sem, u8_t count); -/** Signals a semaphore - * @param sem the semaphore to signal */ -void sys_sem_signal(sys_sem_t *sem); -/** Wait for a semaphore for the specified timeout - * @param sem the semaphore to wait for - * @param timeout timeout in milliseconds to wait (0 = wait forever) - * @return time (in milliseconds) waited for the semaphore - * or SYS_ARCH_TIMEOUT on timeout */ -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); -/** Delete a semaphore - * @param sem semaphore to delete */ -void sys_sem_free(sys_sem_t *sem); -/** Wait for a semaphore - forever/no timeout */ -#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) -#ifndef sys_sem_valid -/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_sem_valid(sys_sem_t *sem); -#endif -#ifndef sys_sem_set_invalid -/** Set a semaphore invalid so that sys_sem_valid returns 0 */ -void sys_sem_set_invalid(sys_sem_t *sem); -#endif - -/* Time functions. */ -#ifndef sys_msleep -void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ -#endif - -/* Mailbox functions. */ - -/** Create a new mbox of specified size - * @param mbox pointer to the mbox to create - * @param size (miminum) number of messages in this mbox - * @return ERR_OK if successful, another err_t otherwise */ -err_t sys_mbox_new(sys_mbox_t *mbox, int size); -/** Post a message to an mbox - may not fail - * -> blocks if full, only used from tasks not from ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) */ -void sys_mbox_post(sys_mbox_t *mbox, void *msg); -/** Try to post a message to an mbox - may fail if full or ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) */ -err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); -/** Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) - * @return time (in milliseconds) waited for a message, may be 0 if not waited - or SYS_ARCH_TIMEOUT on timeout - * The returned time has to be accurate to prevent timer jitter! */ -u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); -/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */ -#ifndef sys_arch_mbox_tryfetch -/** Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @return 0 (milliseconds) if a message has been received - * or SYS_MBOX_EMPTY if the mailbox is empty */ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); -#endif -/** For now, we map straight to sys_arch implementation. */ -#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) -/** Delete an mbox - * @param mbox mbox to delete */ -void sys_mbox_free(sys_mbox_t *mbox); -#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) -#ifndef sys_mbox_valid -/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_mbox_valid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_set_invalid -/** Set an mbox invalid so that sys_mbox_valid returns 0 */ -void sys_mbox_set_invalid(sys_mbox_t *mbox); -#endif - -/** The only thread function: - * Creates a new thread - * @param name human-readable name for the thread (used for debugging purposes) - * @param thread thread-function - * @param arg parameter passed to 'thread' - * @param stacksize stack size in bytes for the new thread (may be ignored by ports) - * @param prio priority of the new thread (may be ignored by ports) */ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); - -#endif /* NO_SYS */ - -/* sys_init() must be called before anthing else. */ -void sys_init(void); - -#ifndef sys_jiffies -/** Ticks/jiffies since power up. */ -u32_t sys_jiffies(void); -#endif - -/** Returns the current time in milliseconds, - * may be the same as sys_jiffies or at least based on it. */ -u32_t sys_now(void); - -/* Critical Region Protection */ -/* These functions must be implemented in the sys_arch.c file. - In some implementations they can provide a more light-weight protection - mechanism than using semaphores. Otherwise semaphores can be used for - implementation */ -#ifndef SYS_ARCH_PROTECT -/** SYS_LIGHTWEIGHT_PROT - * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection - * for certain critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#if SYS_LIGHTWEIGHT_PROT - -/** SYS_ARCH_DECL_PROTECT - * declare a protection variable. This macro will default to defining a variable of - * type sys_prot_t. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h. - */ -#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev -/** SYS_ARCH_PROTECT - * Perform a "fast" protect. This could be implemented by - * disabling interrupts for an embedded system or by using a semaphore or - * mutex. The implementation should allow calling SYS_ARCH_PROTECT when - * already protected. The old protection level is returned in the variable - * "lev". This macro will default to calling the sys_arch_protect() function - * which should be implemented in sys_arch.c. If a particular port needs a - * different implementation, then this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() -/** SYS_ARCH_UNPROTECT - * Perform a "fast" set of the protection level to "lev". This could be - * implemented by setting the interrupt level to "lev" within the MACRO or by - * using a semaphore or mutex. This macro will default to calling the - * sys_arch_unprotect() function which should be implemented in - * sys_arch.c. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) -sys_prot_t sys_arch_protect(void); -void sys_arch_unprotect(sys_prot_t pval); - -#else - -#define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) -#define SYS_ARCH_UNPROTECT(lev) - -#endif /* SYS_LIGHTWEIGHT_PROT */ - -#endif /* SYS_ARCH_PROTECT */ - -/* - * Macros to set/get and increase/decrease variables in a thread-safe way. - * Use these for accessing variable that are used from more than one thread. - */ - -#ifndef SYS_ARCH_INC -#define SYS_ARCH_INC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var += val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_INC */ - -#ifndef SYS_ARCH_DEC -#define SYS_ARCH_DEC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var -= val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_DEC */ - -#ifndef SYS_ARCH_GET -#define SYS_ARCH_GET(var, ret) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - ret = var; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_GET */ - -#ifndef SYS_ARCH_SET -#define SYS_ARCH_SET(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var = val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_SET */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_SYS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/tcp.h b/external/badvpn_dns/lwip/src/include/lwip/tcp.h deleted file mode 100644 index 535b6a3..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/tcp.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_TCP_H__ -#define __LWIP_TCP_H__ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct tcp_pcb; - -/** Function prototype for tcp accept callback functions. Called when a new - * connection can be accepted on a listening pcb. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param newpcb The new connection pcb - * @param err An error code if there has been an error accepting. - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); - -/** Function prototype for tcp receive callback functions. Called when data has - * been received. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which received data - * @param p The received data (or NULL when the connection has been closed!) - * @param err An error code if there has been an error receiving - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err); - -/** Function prototype for tcp sent callback functions. Called when sent data has - * been acknowledged by the remote side. Use it to free corresponding resources. - * This also means that the pcb has now space available to send new data. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb for which data has been acknowledged - * @param len The amount of bytes acknowledged - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, - u16_t len); - -/** Function prototype for tcp poll callback functions. Called periodically as - * specified by @see tcp_poll. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb tcp pcb - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); - -/** Function prototype for tcp error callback functions. Called when the pcb - * receives a RST or is unexpectedly closed for any other reason. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param err Error code to indicate why the pcb has been closed - * ERR_ABRT: aborted through tcp_abort or by a TCP timer - * ERR_RST: the connection was reset by the remote host - */ -typedef void (*tcp_err_fn)(void *arg, err_t err); - -/** Function prototype for tcp connected callback functions. Called when a pcb - * is connected to the remote side after initiating a connection attempt by - * calling tcp_connect(). - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which is connected - * @param err An unused error code, always ERR_OK currently ;-) TODO! - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - * - * @note When a connection attempt fails, the error callback is currently called! - */ -typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); - -enum tcp_state { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10 -}; - -#if LWIP_CALLBACK_API - /* Function to call when a listener has been connected. - * @param arg user-supplied argument (tcp_pcb.callback_arg) - * @param pcb a new tcp_pcb that now is connected - * @param err an error argument (TODO: that is current always ERR_OK?) - * @return ERR_OK: accept the new connection, - * any other err_t abortsthe new connection - */ -#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; -#else /* LWIP_CALLBACK_API */ -#define DEF_ACCEPT_CALLBACK -#endif /* LWIP_CALLBACK_API */ - -/** - * members common to struct tcp_pcb and struct tcp_listen_pcb - */ -#define TCP_PCB_COMMON(type) \ - type *next; /* for the linked list */ \ - void *callback_arg; \ - /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ - DEF_ACCEPT_CALLBACK \ - enum tcp_state state; /* TCP state */ \ - u8_t prio; \ - /* ports are in host byte order */ \ - int bound_to_netif; \ - u16_t local_port; \ - char local_netif[3] - - -/* the TCP protocol control block */ -struct tcp_pcb { -/** common PCB members */ - IP_PCB; -/** protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb); - - /* ports are in host byte order */ - u16_t remote_port; - - u8_t flags; -#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ -#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ -#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ -#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ -#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */ -#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ -#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ -#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ - - /* the rest of the fields are in host byte order - as we have to do some math with them */ - - /* Timers */ - u8_t polltmr, pollinterval; - u8_t last_timer; - u32_t tmr; - - /* receiver variables */ - u32_t rcv_nxt; /* next seqno expected */ - u16_t rcv_wnd; /* receiver window available */ - u16_t rcv_ann_wnd; /* receiver window to announce */ - u32_t rcv_ann_right_edge; /* announced right edge of window */ - - /* Retransmission timer. */ - s16_t rtime; - - u16_t mss; /* maximum segment size */ - - /* RTT (round trip time) estimation variables */ - u32_t rttest; /* RTT estimate in 500ms ticks */ - u32_t rtseq; /* sequence number being timed */ - s16_t sa, sv; /* @todo document this */ - - s16_t rto; /* retransmission time-out */ - u8_t nrtx; /* number of retransmissions */ - - /* fast retransmit/recovery */ - u8_t dupacks; - u32_t lastack; /* Highest acknowledged seqno. */ - - /* congestion avoidance/control variables */ - u16_t cwnd; - u16_t ssthresh; - - /* sender variables */ - u32_t snd_nxt; /* next new seqno to be sent */ - u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last - window update. */ - u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ - u16_t snd_wnd; /* sender window */ - u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ - - u16_t acked; - - u16_t snd_buf; /* Available buffer space for sending (in bytes). */ -#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) - u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ - -#if TCP_OVERSIZE - /* Extra bytes available at the end of the last pbuf in unsent. */ - u16_t unsent_oversize; -#endif /* TCP_OVERSIZE */ - - /* These are ordered by sequence number: */ - struct tcp_seg *unsent; /* Unsent (queued) segments. */ - struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ -#if TCP_QUEUE_OOSEQ - struct tcp_seg *ooseq; /* Received out of sequence segments. */ -#endif /* TCP_QUEUE_OOSEQ */ - - struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ - -#if LWIP_CALLBACK_API - /* Function to be called when more send buffer space is available. */ - tcp_sent_fn sent; - /* Function to be called when (in-sequence) data has arrived. */ - tcp_recv_fn recv; - /* Function to be called when a connection has been set up. */ - tcp_connected_fn connected; - /* Function which is called periodically. */ - tcp_poll_fn poll; - /* Function to be called whenever a fatal error occurs. */ - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - -#if LWIP_TCP_TIMESTAMPS - u32_t ts_lastacksent; - u32_t ts_recent; -#endif /* LWIP_TCP_TIMESTAMPS */ - - /* idle time before KEEPALIVE is sent */ - u32_t keep_idle; -#if LWIP_TCP_KEEPALIVE - u32_t keep_intvl; - u32_t keep_cnt; -#endif /* LWIP_TCP_KEEPALIVE */ - - /* Persist timer counter */ - u8_t persist_cnt; - /* Persist timer back-off */ - u8_t persist_backoff; - - /* KEEPALIVE counter */ - u8_t keep_cnt_sent; -}; - -struct tcp_pcb_listen { -/* Common members of all PCB types */ - IP_PCB; -/* Protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb_listen); - -#if TCP_LISTEN_BACKLOG - u8_t backlog; - u8_t accepts_pending; -#endif /* TCP_LISTEN_BACKLOG */ -#if LWIP_IPV6 - u8_t accept_any_ip_version; -#endif /* LWIP_IPV6 */ -}; - -#if LWIP_EVENT_API - -enum lwip_event { - LWIP_EVENT_ACCEPT, - LWIP_EVENT_SENT, - LWIP_EVENT_RECV, - LWIP_EVENT_CONNECTED, - LWIP_EVENT_POLL, - LWIP_EVENT_ERR -}; - -err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, - enum lwip_event, - struct pbuf *p, - u16_t size, - err_t err); - -#endif /* LWIP_EVENT_API */ - -/* Application program's interface: */ -struct tcp_pcb * tcp_new (void); - -void tcp_arg (struct tcp_pcb *pcb, void *arg); -void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); -void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); -void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); -void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); -void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); - -#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) -#define tcp_sndbuf(pcb) ((pcb)->snd_buf) -#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) -#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) -#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) -#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) - -#if TCP_LISTEN_BACKLOG -#define tcp_accepted(pcb) do { \ - LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ - (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) -#else /* TCP_LISTEN_BACKLOG */ -#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ - (pcb)->state == LISTEN) -#endif /* TCP_LISTEN_BACKLOG */ - -void tcp_recved (struct tcp_pcb *pcb, u16_t len); -err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -err_t tcp_bind_to_netif (struct tcp_pcb *pcb, const char ifname[3]); -err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port, tcp_connected_fn connected); - -struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) - -void tcp_abort (struct tcp_pcb *pcb); -err_t tcp_close (struct tcp_pcb *pcb); -err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); - -/* Flags for "apiflags" parameter in tcp_write */ -#define TCP_WRITE_FLAG_COPY 0x01 -#define TCP_WRITE_FLAG_MORE 0x02 - -err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags); - -void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); - -#define TCP_PRIO_MIN 1 -#define TCP_PRIO_NORMAL 64 -#define TCP_PRIO_MAX 127 - -err_t tcp_output (struct tcp_pcb *pcb); - - -const char* tcp_debug_state_str(enum tcp_state s); - -#if LWIP_IPV6 -struct tcp_pcb * tcp_new_ip6 (void); -#define tcp_bind_ip6(pcb, ip6addr, port) \ - tcp_bind(pcb, ip6_2_ip(ip6addr), port) -#define tcp_connect_ip6(pcb, ip6addr, port, connected) \ - tcp_connect(pcb, ip6_2_ip(ip6addr), port, connected) -struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) -#else /* LWIP_IPV6 */ -#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog) -#define tcp_listen_dual(pcb) tcp_listen(pcb) -#endif /* LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* __LWIP_TCP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/tcp_impl.h b/external/badvpn_dns/lwip/src/include/lwip/tcp_impl.h deleted file mode 100644 index 2afc20d..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/tcp_impl.h +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_TCP_IMPL_H__ -#define __LWIP_TCP_IMPL_H__ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Functions for interfacing with TCP: */ - -/* Lower layer interface to TCP: */ -void tcp_init (void); /* Initialize this module. */ -void tcp_tmr (void); /* Must be called every - TCP_TMR_INTERVAL - ms. (Typically 250 ms). */ -/* It is also possible to call these two functions at the right - intervals (instead of calling tcp_tmr()). */ -void tcp_slowtmr (void); -void tcp_fasttmr (void); - - -/* Only used by IP to pass a TCP segment to TCP: */ -void tcp_input (struct pbuf *p, struct netif *inp); -/* Used within the TCP code only: */ -struct tcp_pcb * tcp_alloc (u8_t prio); -void tcp_abandon (struct tcp_pcb *pcb, int reset); -err_t tcp_send_empty_ack(struct tcp_pcb *pcb); -void tcp_rexmit (struct tcp_pcb *pcb); -void tcp_rexmit_rto (struct tcp_pcb *pcb); -void tcp_rexmit_fast (struct tcp_pcb *pcb); -u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); -err_t tcp_process_refused_data(struct tcp_pcb *pcb); - -/** - * This is the Nagle algorithm: try to combine user data to send as few TCP - * segments as possible. Only send if - * - no previously transmitted data on the connection remains unacknowledged or - * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or - * - the only unsent segment is at least pcb->mss bytes long (or there is more - * than one unsent segment - with lwIP, this can happen although unsent->len < mss) - * - or if we are in fast-retransmit (TF_INFR) - */ -#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ - ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ - (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ - ((tpcb)->unsent->len >= (tpcb)->mss))) || \ - ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ - ) ? 1 : 0) -#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) - - -#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) -#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) -#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) -#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) -/* is b<=a<=c? */ -#if 0 /* see bug #10548 */ -#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) -#endif -#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) -#define TCP_FIN 0x01U -#define TCP_SYN 0x02U -#define TCP_RST 0x04U -#define TCP_PSH 0x08U -#define TCP_ACK 0x10U -#define TCP_URG 0x20U -#define TCP_ECE 0x40U -#define TCP_CWR 0x80U - -#define TCP_FLAGS 0x3fU - -/* Length of the TCP header, excluding options. */ -#define TCP_HLEN 20 - -#ifndef TCP_TMR_INTERVAL -#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ -#endif /* TCP_TMR_INTERVAL */ - -#ifndef TCP_FAST_INTERVAL -#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ -#endif /* TCP_FAST_INTERVAL */ - -#ifndef TCP_SLOW_INTERVAL -#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ -#endif /* TCP_SLOW_INTERVAL */ - -#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ -#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ - -#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ - -#ifndef TCP_MSL -#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ -#endif - -/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ -#ifndef TCP_KEEPIDLE_DEFAULT -#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ -#endif - -#ifndef TCP_KEEPINTVL_DEFAULT -#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ -#endif - -#ifndef TCP_KEEPCNT_DEFAULT -#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ -#endif - -#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ - -/* Fields are (of course) in network byte order. - * Some fields are converted to host byte order in tcp_input(). - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct tcp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); - PACK_STRUCT_FIELD(u32_t seqno); - PACK_STRUCT_FIELD(u32_t ackno); - PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); - PACK_STRUCT_FIELD(u16_t wnd); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t urgp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) -#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) - -#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) -#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) -#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) - -#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) -#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) - -#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) - -/** Flags used on input processing, not on pcb->flags -*/ -#define TF_RESET (u8_t)0x08U /* Connection was reset. */ -#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ -#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ - - -#if LWIP_EVENT_API - -#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_ACCEPT, NULL, 0, err) -#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_SENT, NULL, space, ERR_OK) -#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, (p), 0, (err)) -#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, NULL, 0, ERR_OK) -#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_CONNECTED, NULL, 0, (err)) -#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_POLL, NULL, 0, ERR_OK) -#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ - LWIP_EVENT_ERR, NULL, 0, (err)) - -#else /* LWIP_EVENT_API */ - -#define TCP_EVENT_ACCEPT(pcb,err,ret) \ - do { \ - if((pcb)->accept != NULL) \ - (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_ARG; \ - } while (0) - -#define TCP_EVENT_SENT(pcb,space,ret) \ - do { \ - if((pcb)->sent != NULL) \ - (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_RECV(pcb,p,err,ret) \ - do { \ - if((pcb)->recv != NULL) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ - } else { \ - (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ - } \ - } while (0) - -#define TCP_EVENT_CLOSED(pcb,ret) \ - do { \ - if(((pcb)->recv != NULL)) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ - } else { \ - (ret) = ERR_OK; \ - } \ - } while (0) - -#define TCP_EVENT_CONNECTED(pcb,err,ret) \ - do { \ - if((pcb)->connected != NULL) \ - (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_POLL(pcb,ret) \ - do { \ - if((pcb)->poll != NULL) \ - (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_ERR(errf,arg,err) \ - do { \ - if((errf) != NULL) \ - (errf)((arg),(err)); \ - } while (0) - -#endif /* LWIP_EVENT_API */ - -/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ -#if TCP_OVERSIZE && defined(LWIP_DEBUG) -#define TCP_OVERSIZE_DBGCHECK 1 -#else -#define TCP_OVERSIZE_DBGCHECK 0 -#endif - -/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ -#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) - -/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ -struct tcp_seg { - struct tcp_seg *next; /* used when putting segements on a queue */ - struct pbuf *p; /* buffer containing data + TCP header */ - u16_t len; /* the TCP length of this segment */ -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_left; /* Extra bytes available at the end of the last - pbuf in unsent (used for asserting vs. - tcp_pcb.unsent_oversized only) */ -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - u16_t chksum; - u8_t chksum_swapped; -#endif /* TCP_CHECKSUM_ON_COPY */ - u8_t flags; -#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ -#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ -#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is - checksummed into 'chksum' */ - struct tcp_hdr *tcphdr; /* the TCP header */ -}; - -#define LWIP_TCP_OPT_LENGTH(flags) \ - (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ - (flags & TF_SEG_OPTS_TS ? 12 : 0) - -/** This returns a TCP header option for MSS in an u32_t */ -#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) - -/* Global variables: */ -extern struct tcp_pcb *tcp_input_pcb; -extern u32_t tcp_ticks; -extern u8_t tcp_active_pcbs_changed; - -/* The TCP PCB lists. */ -union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ - struct tcp_pcb_listen *listen_pcbs; - struct tcp_pcb *pcbs; -}; -extern struct tcp_pcb *tcp_bound_pcbs; -extern union tcp_listen_pcbs_t tcp_listen_pcbs; -extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a - state in which they accept or send - data. */ -extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ - -extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ - -/* Axioms about the above lists: - 1) Every TCP PCB that is not CLOSED is in one of the lists. - 2) A PCB is only in one of the lists. - 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. - 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. -*/ -/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB - with a PCB list or removes a PCB from a list, respectively. */ -#ifndef TCP_DEBUG_PCB_LISTS -#define TCP_DEBUG_PCB_LISTS 0 -#endif -#if TCP_DEBUG_PCB_LISTS -#define TCP_REG(pcbs, npcb) do {\ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ - for(tcp_tmp_pcb = *(pcbs); \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ - } \ - LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ - (npcb)->next = *(pcbs); \ - LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ - *(pcbs) = (npcb); \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - tcp_timer_needed(); \ - } while(0) -#define TCP_RMV(pcbs, npcb) do { \ - LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ - if(*(pcbs) == (npcb)) { \ - *(pcbs) = (*pcbs)->next; \ - } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - (npcb)->next = NULL; \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ - } while(0) - -#else /* LWIP_DEBUG */ - -#define TCP_REG(pcbs, npcb) \ - do { \ - (npcb)->next = *pcbs; \ - *(pcbs) = (npcb); \ - tcp_timer_needed(); \ - } while (0) - -#define TCP_RMV(pcbs, npcb) \ - do { \ - if(*(pcbs) == (npcb)) { \ - (*(pcbs)) = (*pcbs)->next; \ - } \ - else { \ - for(tcp_tmp_pcb = *pcbs; \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - } \ - (npcb)->next = NULL; \ - } while(0) - -#endif /* LWIP_DEBUG */ - -#define TCP_REG_ACTIVE(npcb) \ - do { \ - TCP_REG(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_RMV_ACTIVE(npcb) \ - do { \ - TCP_RMV(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_PCB_REMOVE_ACTIVE(pcb) \ - do { \ - tcp_pcb_remove(&tcp_active_pcbs, pcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - - -/* Internal functions: */ -struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); -void tcp_pcb_purge(struct tcp_pcb *pcb); -void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); - -void tcp_segs_free(struct tcp_seg *seg); -void tcp_seg_free(struct tcp_seg *seg); -struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); - -#define tcp_ack(pcb) \ - do { \ - if((pcb)->flags & TF_ACK_DELAY) { \ - (pcb)->flags &= ~TF_ACK_DELAY; \ - (pcb)->flags |= TF_ACK_NOW; \ - } \ - else { \ - (pcb)->flags |= TF_ACK_DELAY; \ - } \ - } while (0) - -#define tcp_ack_now(pcb) \ - do { \ - (pcb)->flags |= TF_ACK_NOW; \ - } while (0) - -err_t tcp_send_fin(struct tcp_pcb *pcb); -err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); - -void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); - -void tcp_rst_impl(u32_t seqno, u32_t ackno, - ipX_addr_t *local_ip, ipX_addr_t *remote_ip, - u16_t local_port, u16_t remote_port -#if LWIP_IPV6 - , u8_t isipv6 -#endif /* LWIP_IPV6 */ - ); -#if LWIP_IPV6 -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ - tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) -#else /* LWIP_IPV6 */ -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ - tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) -#endif /* LWIP_IPV6 */ - -u32_t tcp_next_iss(void); - -void tcp_keepalive(struct tcp_pcb *pcb); -void tcp_zero_window_probe(struct tcp_pcb *pcb); - -#if TCP_CALCULATE_EFF_SEND_MSS -u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest -#if LWIP_IPV6 - , ipX_addr_t *src, u8_t isipv6 -#endif /* LWIP_IPV6 */ - ); -#if LWIP_IPV6 -#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) -#else /* LWIP_IPV6 */ -#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest) -#endif /* LWIP_IPV6 */ -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -#if LWIP_CALLBACK_API -err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -#endif /* LWIP_CALLBACK_API */ - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -void tcp_debug_print(struct tcp_hdr *tcphdr); -void tcp_debug_print_flags(u8_t flags); -void tcp_debug_print_state(enum tcp_state s); -void tcp_debug_print_pcbs(void); -s16_t tcp_pcbs_sane(void); -#else -# define tcp_debug_print(tcphdr) -# define tcp_debug_print_flags(flags) -# define tcp_debug_print_state(s) -# define tcp_debug_print_pcbs() -# define tcp_pcbs_sane() 1 -#endif /* TCP_DEBUG */ - -/** External function (implemented in timers.c), called when TCP detects - * that a timer is needed (i.e. active- or time-wait-pcb found). */ -void tcp_timer_needed(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* __LWIP_TCP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/tcpip.h b/external/badvpn_dns/lwip/src/include/lwip/tcpip.h deleted file mode 100644 index 04567f2..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/tcpip.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_TCPIP_H__ -#define __LWIP_TCPIP_H__ - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api_msg.h" -#include "lwip/netifapi.h" -#include "lwip/pbuf.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/timers.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Define this to something that triggers a watchdog. This is called from - * tcpip_thread after processing a message. */ -#ifndef LWIP_TCPIP_THREAD_ALIVE -#define LWIP_TCPIP_THREAD_ALIVE() -#endif - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -extern sys_mutex_t lock_tcpip_core; -#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) -#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) -#ifdef LWIP_DEBUG -#define TCIP_APIMSG_SET_ERR(m, e) (m)->msg.err = e /* catch functions that don't set err */ -#else -#define TCIP_APIMSG_SET_ERR(m, e) -#endif -#define TCPIP_APIMSG_NOERR(m,f) do { \ - TCIP_APIMSG_SET_ERR(m, ERR_VAL); \ - LOCK_TCPIP_CORE(); \ - f(&((m)->msg)); \ - UNLOCK_TCPIP_CORE(); \ -} while(0) -#define TCPIP_APIMSG(m,f,e) do { \ - TCPIP_APIMSG_NOERR(m,f); \ - (e) = (m)->msg.err; \ -} while(0) -#define TCPIP_APIMSG_ACK(m) -#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) -#define TCPIP_NETIFAPI_ACK(m) -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define LOCK_TCPIP_CORE() -#define UNLOCK_TCPIP_CORE() -#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) -#define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) -#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) -#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) -#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -/** Function prototype for the init_done function passed to tcpip_init */ -typedef void (*tcpip_init_done_fn)(void *arg); -/** Function prototype for functions passed to tcpip_callback() */ -typedef void (*tcpip_callback_fn)(void *ctx); - -/* Forward declarations */ -struct tcpip_callback_msg; - -void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); - -#if LWIP_NETCONN -err_t tcpip_apimsg(struct api_msg *apimsg); -#endif /* LWIP_NETCONN */ - -err_t tcpip_input(struct pbuf *p, struct netif *inp); - -#if LWIP_NETIF_API -err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); -#if LWIP_TCPIP_CORE_LOCKING -err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); -#endif /* LWIP_TCPIP_CORE_LOCKING */ -#endif /* LWIP_NETIF_API */ - -err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); -#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) - -struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); -void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); -err_t tcpip_trycallback(struct tcpip_callback_msg* msg); - -/* free pbufs or heap memory from another context without blocking */ -err_t pbuf_free_callback(struct pbuf *p); -err_t mem_free_callback(void *m); - -#if LWIP_TCPIP_TIMEOUT -err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); -err_t tcpip_untimeout(sys_timeout_handler h, void *arg); -#endif /* LWIP_TCPIP_TIMEOUT */ - -enum tcpip_msg_type { -#if LWIP_NETCONN - TCPIP_MSG_API, -#endif /* LWIP_NETCONN */ - TCPIP_MSG_INPKT, -#if LWIP_NETIF_API - TCPIP_MSG_NETIFAPI, -#endif /* LWIP_NETIF_API */ -#if LWIP_TCPIP_TIMEOUT - TCPIP_MSG_TIMEOUT, - TCPIP_MSG_UNTIMEOUT, -#endif /* LWIP_TCPIP_TIMEOUT */ - TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC -}; - -struct tcpip_msg { - enum tcpip_msg_type type; - sys_sem_t *sem; - union { -#if LWIP_NETCONN - struct api_msg *apimsg; -#endif /* LWIP_NETCONN */ -#if LWIP_NETIF_API - struct netifapi_msg *netifapimsg; -#endif /* LWIP_NETIF_API */ - struct { - struct pbuf *p; - struct netif *netif; - } inp; - struct { - tcpip_callback_fn function; - void *ctx; - } cb; -#if LWIP_TCPIP_TIMEOUT - struct { - u32_t msecs; - sys_timeout_handler h; - void *arg; - } tmo; -#endif /* LWIP_TCPIP_TIMEOUT */ - } msg; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* __LWIP_TCPIP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/timers.h b/external/badvpn_dns/lwip/src/include/lwip/timers.h deleted file mode 100644 index 04e78e0..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/timers.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * Simon Goldschmidt - * - */ -#ifndef __LWIP_TIMERS_H__ -#define __LWIP_TIMERS_H__ - -#include "lwip/opt.h" - -/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ -#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) - -#if LWIP_TIMERS - -#include "lwip/err.h" -#if !NO_SYS -#include "lwip/sys.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LWIP_DEBUG_TIMERNAMES -#ifdef LWIP_DEBUG -#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG -#else /* LWIP_DEBUG */ -#define LWIP_DEBUG_TIMERNAMES 0 -#endif /* LWIP_DEBUG*/ -#endif - -/** Function prototype for a timeout callback function. Register such a function - * using sys_timeout(). - * - * @param arg Additional argument to pass to the function - set up by sys_timeout() - */ -typedef void (* sys_timeout_handler)(void *arg); - -struct sys_timeo { - struct sys_timeo *next; - u32_t time; - sys_timeout_handler h; - void *arg; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -void sys_timeouts_init(void); - -#if LWIP_DEBUG_TIMERNAMES -void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); -#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) -#else /* LWIP_DEBUG_TIMERNAMES */ -void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); -#endif /* LWIP_DEBUG_TIMERNAMES */ - -void sys_untimeout(sys_timeout_handler handler, void *arg); -#if NO_SYS -void sys_check_timeouts(void); -void sys_restart_timeouts(void); -#else /* NO_SYS */ -void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); -#endif /* NO_SYS */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TIMERS */ -#endif /* __LWIP_TIMERS_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/lwip/udp.h b/external/badvpn_dns/lwip/src/include/lwip/udp.h deleted file mode 100644 index 14d5c0a..0000000 --- a/external/badvpn_dns/lwip/src/include/lwip/udp.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __LWIP_UDP_H__ -#define __LWIP_UDP_H__ - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_HLEN 8 - -/* Fields are (of course) in network byte order. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct udp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ - PACK_STRUCT_FIELD(u16_t len); - PACK_STRUCT_FIELD(u16_t chksum); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define UDP_FLAGS_NOCHKSUM 0x01U -#define UDP_FLAGS_UDPLITE 0x02U -#define UDP_FLAGS_CONNECTED 0x04U -#define UDP_FLAGS_MULTICAST_LOOP 0x08U - -struct udp_pcb; - -/** Function prototype for udp pcb receive callback functions - * addr and port are in same byte order as in the pcb - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf - * makes 'addr' invalid, too. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *addr, u16_t port); - -#if LWIP_IPV6 -/** Function prototype for udp pcb IPv6 receive callback functions - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IPv6 address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_ip6_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - ip6_addr_t *addr, u16_t port); -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV6 -#define UDP_PCB_RECV_IP6 udp_recv_ip6_fn ip6; -#else -#define UDP_PCB_RECV_IP6 -#endif /* LWIP_IPV6 */ - -struct udp_pcb { -/* Common members of all PCB types */ - IP_PCB; - -/* Protocol specific PCB members */ - - struct udp_pcb *next; - - u8_t flags; - /** ports are in host byte order */ - u16_t local_port, remote_port; - -#if LWIP_IGMP - /** outgoing network interface for multicast packets */ - ip_addr_t multicast_ip; -#endif /* LWIP_IGMP */ - -#if LWIP_UDPLITE - /** used for UDP_LITE only */ - u16_t chksum_len_rx, chksum_len_tx; -#endif /* LWIP_UDPLITE */ - - /** receive callback function */ - union { - udp_recv_fn ip4; - UDP_PCB_RECV_IP6 - }recv; - /** user-supplied argument for the recv callback */ - void *recv_arg; -}; -/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ -extern struct udp_pcb *udp_pcbs; - -/* The following functions is the application layer interface to the - UDP code. */ -struct udp_pcb * udp_new (void); -void udp_remove (struct udp_pcb *pcb); -err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -void udp_disconnect (struct udp_pcb *pcb); -void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, - void *recv_arg); -err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif); -err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port); -err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, u8_t have_chksum, - u16_t chksum); -err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - u8_t have_chksum, u16_t chksum); -err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -#define udp_flags(pcb) ((pcb)->flags) -#define udp_setflags(pcb, f) ((pcb)->flags = (f)) - -/* The following functions are the lower layer interface to UDP. */ -void udp_input (struct pbuf *p, struct netif *inp); - -void udp_init (void); - -#if LWIP_IPV6 -struct udp_pcb * udp_new_ip6(void); -#define udp_bind_ip6(pcb, ip6addr, port) \ - udp_bind(pcb, ip6_2_ip(ip6addr), port) -#define udp_connect_ip6(pcb, ip6addr, port) \ - udp_connect(pcb, ip6_2_ip(ip6addr), port) -#define udp_recv_ip6(pcb, recv_ip6_fn, recv_arg) \ - udp_recv(pcb, (udp_recv_fn)recv_ip6_fn, recv_arg) -#define udp_sendto_ip6(pcb, pbuf, ip6addr, port) \ - udp_sendto(pcb, pbuf, ip6_2_ip(ip6addr), port) -#define udp_sendto_if_ip6(pcb, pbuf, ip6addr, port, netif) \ - udp_sendto_if(pcb, pbuf, ip6_2_ip(ip6addr), port, netif) -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -#define udp_sendto_chksum_ip6(pcb, pbuf, ip6addr, port, have_chk, chksum) \ - udp_sendto_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, have_chk, chksum) -#define udp_sendto_if_chksum_ip6(pcb, pbuf, ip6addr, port, netif, have_chk, chksum) \ - udp_sendto_if_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, netif, have_chk, chksum) -#endif /*LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -#endif /* LWIP_IPV6 */ - -#if UDP_DEBUG -void udp_debug_print(struct udp_hdr *udphdr); -#else -#define udp_debug_print(udphdr) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_UDP */ - -#endif /* __LWIP_UDP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/netif/etharp.h b/external/badvpn_dns/lwip/src/include/netif/etharp.h deleted file mode 100644 index 8275a28..0000000 --- a/external/badvpn_dns/lwip/src/include/netif/etharp.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg leon.woestenberg@axon.tv - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -#ifndef __NETIF_ETHARP_H__ -#define __NETIF_ETHARP_H__ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETHARP_HWADDR_LEN -#define ETHARP_HWADDR_LEN 6 -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct eth_addr { - PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** Ethernet header */ -struct eth_hdr { -#if ETH_PAD_SIZE - PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); -#endif - PACK_STRUCT_FIELD(struct eth_addr dest); - PACK_STRUCT_FIELD(struct eth_addr src); - PACK_STRUCT_FIELD(u16_t type); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) - -#if ETHARP_SUPPORT_VLAN - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** VLAN header inserted between ethernet header and payload - * if 'type' in ethernet header is ETHTYPE_VLAN. - * See IEEE802.Q */ -struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t prio_vid); - PACK_STRUCT_FIELD(u16_t tpid); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_VLAN_HDR 4 -#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) - -#endif /* ETHARP_SUPPORT_VLAN */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** the ARP message, see RFC 826 ("Packet format") */ -struct etharp_hdr { - PACK_STRUCT_FIELD(u16_t hwtype); - PACK_STRUCT_FIELD(u16_t proto); - PACK_STRUCT_FIELD(u8_t hwlen); - PACK_STRUCT_FIELD(u8_t protolen); - PACK_STRUCT_FIELD(u16_t opcode); - PACK_STRUCT_FIELD(struct eth_addr shwaddr); - PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); - PACK_STRUCT_FIELD(struct eth_addr dhwaddr); - PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETHARP_HDR 28 -#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) - -/** 5 seconds period */ -#define ARP_TMR_INTERVAL 5000 - -#define ETHTYPE_ARP 0x0806U -#define ETHTYPE_IP 0x0800U -#define ETHTYPE_VLAN 0x8100U -#define ETHTYPE_IPV6 0x86DDU -#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ -#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables - * or known to be 32-bit aligned within the protocol header. */ -#ifndef ETHADDR32_COPY -#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) -#endif - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local - * variables and known to be 16-bit aligned within the protocol header. */ -#ifndef ETHADDR16_COPY -#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) -#endif - -#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -/** ARP message types (opcodes) */ -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) - * to a filter function that returns the correct netif when using multiple - * netifs on one hardware interface where the netif's low-level receive - * routine cannot decide for the correct netif (e.g. when mapping multiple - * IP addresses to one hardware interface). - */ -#ifndef LWIP_ARP_FILTER_NETIF -#define LWIP_ARP_FILTER_NETIF 0 -#endif - -#if ARP_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct etharp_q_entry { - struct etharp_q_entry *next; - struct pbuf *p; -}; -#endif /* ARP_QUEUEING */ - -#define etharp_init() /* Compatibility define, not init needed. */ -void etharp_tmr(void); -s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, - struct eth_addr **eth_ret, ip_addr_t **ip_ret); -err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); -err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); -err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); -/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; - * this is an ARP packet sent by a node in order to spontaneously cause other - * nodes to update an entry in their ARP cache. - * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ -#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) -void etharp_cleanup_netif(struct netif *netif); - -#if ETHARP_SUPPORT_STATIC_ENTRIES -err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); -err_t etharp_remove_static_entry(ip_addr_t *ipaddr); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#if LWIP_AUTOIP -err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, - const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, - const u16_t opcode); -#endif /* LWIP_AUTOIP */ - -#endif /* LWIP_ARP */ - -err_t ethernet_input(struct pbuf *p, struct netif *netif); - -#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) - -extern const struct eth_addr ethbroadcast, ethzero; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#endif /* __NETIF_ARP_H__ */ diff --git a/external/badvpn_dns/lwip/src/include/netif/ppp_oe.h b/external/badvpn_dns/lwip/src/include/netif/ppp_oe.h deleted file mode 100644 index e1cdfa5..0000000 --- a/external/badvpn_dns/lwip/src/include/netif/ppp_oe.h +++ /dev/null @@ -1,190 +0,0 @@ -/***************************************************************************** -* ppp_oe.h - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann martin@NetBSD.org. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef PPP_OE_H -#define PPP_OE_H - -#include "lwip/opt.h" - -#if PPPOE_SUPPORT > 0 - -#include "netif/etharp.h" - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoehdr { - PACK_STRUCT_FIELD(u8_t vertype); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t session); - PACK_STRUCT_FIELD(u16_t plen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoetag { - PACK_STRUCT_FIELD(u16_t tag); - PACK_STRUCT_FIELD(u16_t len); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_PADI_SENT 1 -#define PPPOE_STATE_PADR_SENT 2 -#define PPPOE_STATE_SESSION 3 -#define PPPOE_STATE_CLOSING 4 -/* passive */ -#define PPPOE_STATE_PADO_SENT 1 - -#define PPPOE_HEADERLEN sizeof(struct pppoehdr) -#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ - -#define PPPOE_TAG_EOL 0x0000 /* end of list */ -#define PPPOE_TAG_SNAME 0x0101 /* service name */ -#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ -#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ -#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ -#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ -#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ -#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ -#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ -#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ - -#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ -#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ -#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ -#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ -#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ - -#ifndef ETHERMTU -#define ETHERMTU 1500 -#endif - -/* two byte PPP protocol discriminator, then IP data */ -#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) - -#ifndef PPPOE_MAX_AC_COOKIE_LEN -#define PPPOE_MAX_AC_COOKIE_LEN 64 -#endif - -struct pppoe_softc { - struct pppoe_softc *next; - struct netif *sc_ethif; /* ethernet interface we are using */ - int sc_pd; /* ppp unit number */ - void (*sc_linkStatusCB)(int pd, int up); - - int sc_state; /* discovery phase or session connected */ - struct eth_addr sc_dest; /* hardware address of concentrator */ - u16_t sc_session; /* PPPoE session id */ - -#ifdef PPPOE_TODO - char *sc_service_name; /* if != NULL: requested name of service */ - char *sc_concentrator_name; /* if != NULL: requested concentrator id */ -#endif /* PPPOE_TODO */ - u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ - size_t sc_ac_cookie_len; /* length of cookie data */ -#ifdef PPPOE_SERVER - u8_t *sc_hunique; /* content of host unique we must echo back */ - size_t sc_hunique_len; /* length of host unique */ -#endif - int sc_padi_retried; /* number of PADI retries already done */ - int sc_padr_retried; /* number of PADR retries already done */ -}; - - -#define pppoe_init() /* compatibility define, no initialization needed */ - -err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); -err_t pppoe_destroy(struct netif *ifp); - -int pppoe_connect(struct pppoe_softc *sc); -void pppoe_disconnect(struct pppoe_softc *sc); - -void pppoe_disc_input(struct netif *netif, struct pbuf *p); -void pppoe_data_input(struct netif *netif, struct pbuf *p); - -err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); - -/** used in ppp.c */ -#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) - -#endif /* PPPOE_SUPPORT */ - -#endif /* PPP_OE_H */ diff --git a/external/badvpn_dns/lwip/src/include/netif/slipif.h b/external/badvpn_dns/lwip/src/include/netif/slipif.h deleted file mode 100644 index 7b6ce5e..0000000 --- a/external/badvpn_dns/lwip/src/include/netif/slipif.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ -#ifndef __NETIF_SLIPIF_H__ -#define __NETIF_SLIPIF_H__ - -#include "lwip/opt.h" -#include "lwip/netif.h" - -/** Set this to 1 to start a thread that blocks reading on the serial line - * (using sio_read()). - */ -#ifndef SLIP_USE_RX_THREAD -#define SLIP_USE_RX_THREAD !NO_SYS -#endif - -/** Set this to 1 to enable functions to pass in RX bytes from ISR context. - * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled - * packets on a queue, which is fed into lwIP from slipif_poll(). - * If disabled, slipif_poll() polls the serila line (using sio_tryread()). - */ -#ifndef SLIP_RX_FROM_ISR -#define SLIP_RX_FROM_ISR 0 -#endif - -/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets - * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. - * If disabled, packets will be dropped if more than one packet is received. - */ -#ifndef SLIP_RX_QUEUE -#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -err_t slipif_init(struct netif * netif); -void slipif_poll(struct netif *netif); -#if SLIP_RX_FROM_ISR -void slipif_process_rxqueue(struct netif *netif); -void slipif_received_byte(struct netif *netif, u8_t data); -void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); -#endif /* SLIP_RX_FROM_ISR */ - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/badvpn_dns/lwip/src/include/posix/netdb.h b/external/badvpn_dns/lwip/src/include/posix/netdb.h deleted file mode 100644 index 7134032..0000000 --- a/external/badvpn_dns/lwip/src/include/posix/netdb.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/netdb.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/netdb.h" diff --git a/external/badvpn_dns/lwip/src/include/posix/sys/socket.h b/external/badvpn_dns/lwip/src/include/posix/sys/socket.h deleted file mode 100644 index f7c7066..0000000 --- a/external/badvpn_dns/lwip/src/include/posix/sys/socket.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/sockets.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/sockets.h" diff --git a/external/badvpn_dns/lwip/src/netif/FILES b/external/badvpn_dns/lwip/src/netif/FILES deleted file mode 100644 index 099dbf3..0000000 --- a/external/badvpn_dns/lwip/src/netif/FILES +++ /dev/null @@ -1,29 +0,0 @@ -This directory contains generic network interface device drivers that -do not contain any hardware or architecture specific code. The files -are: - -etharp.c - Implements the ARP (Address Resolution Protocol) over - Ethernet. The code in this file should be used together with - Ethernet device drivers. Note that this module has been - largely made Ethernet independent so you should be able to - adapt this for other link layers (such as Firewire). - -ethernetif.c - An example of how an Ethernet device driver could look. This - file can be used as a "skeleton" for developing new Ethernet - network device drivers. It uses the etharp.c ARP code. - -loopif.c - A "loopback" network interface driver. It requires configuration - through the define LWIP_LOOPIF_MULTITHREADING (see opt.h). - -slipif.c - A generic implementation of the SLIP (Serial Line IP) - protocol. It requires a sio (serial I/O) module to work. - -ppp/ Point-to-Point Protocol stack - The PPP stack has been ported from ucip (http://ucip.sourceforge.net). - It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although - compared to that, it has some modifications for embedded systems and - the source code has been reordered a bit. \ No newline at end of file diff --git a/external/badvpn_dns/lwip/src/netif/etharp.c b/external/badvpn_dns/lwip/src/netif/etharp.c deleted file mode 100644 index 1b7eb98..0000000 --- a/external/badvpn_dns/lwip/src/netif/etharp.c +++ /dev/null @@ -1,1413 +0,0 @@ -/** - * @file - * Address Resolution Protocol module for IP over Ethernet - * - * Functionally, ARP is divided into two parts. The first maps an IP address - * to a physical address when sending a packet, and the second part answers - * requests from other machines for our physical address. - * - * This implementation complies with RFC 826 (Ethernet ARP). It supports - * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 - * if an interface calls etharp_gratuitous(our_netif) upon address change. - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg leon.woestenberg@axon.tv - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET - -#include "lwip/ip_addr.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "netif/etharp.h" -#include "lwip/ip6.h" - -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ - -#include <string.h> - -const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; -const struct eth_addr ethzero = {{0,0,0,0,0,0}}; - -/** The 24-bit IANA multicast OUI is 01-00-5e: */ -#define LL_MULTICAST_ADDR_0 0x01 -#define LL_MULTICAST_ADDR_1 0x00 -#define LL_MULTICAST_ADDR_2 0x5e - -#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -/** the time an ARP entry stays valid after its last update, - * for ARP_TMR_INTERVAL = 5000, this is - * (240 * 5) seconds = 20 minutes. - */ -#define ARP_MAXAGE 240 -/** Re-request a used ARP entry 1 minute before it would expire to prevent - * breaking a steadily used connection because the ARP entry timed out. */ -#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) - -/** the time an ARP entry stays pending after first request, - * for ARP_TMR_INTERVAL = 5000, this is - * (2 * 5) seconds = 10 seconds. - * - * @internal Keep this number at least 2, otherwise it might - * run out instantly if the timeout occurs directly after a request. - */ -#define ARP_MAXPENDING 2 - -#define HWTYPE_ETHERNET 1 - -enum etharp_state { - ETHARP_STATE_EMPTY = 0, - ETHARP_STATE_PENDING, - ETHARP_STATE_STABLE, - ETHARP_STATE_STABLE_REREQUESTING -#if ETHARP_SUPPORT_STATIC_ENTRIES - ,ETHARP_STATE_STATIC -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ -}; - -struct etharp_entry { -#if ARP_QUEUEING - /** Pointer to queue of pending outgoing packets on this ARP entry. */ - struct etharp_q_entry *q; -#else /* ARP_QUEUEING */ - /** Pointer to a single pending outgoing packet on this ARP entry. */ - struct pbuf *q; -#endif /* ARP_QUEUEING */ - ip_addr_t ipaddr; - struct netif *netif; - struct eth_addr ethaddr; - u8_t state; - u8_t ctime; -}; - -static struct etharp_entry arp_table[ARP_TABLE_SIZE]; - -#if !LWIP_NETIF_HWADDRHINT -static u8_t etharp_cached_entry; -#endif /* !LWIP_NETIF_HWADDRHINT */ - -/** Try hard to create a new entry - we want the IP address to appear in - the cache (even if this means removing an active entry or so). */ -#define ETHARP_FLAG_TRY_HARD 1 -#define ETHARP_FLAG_FIND_ONLY 2 -#if ETHARP_SUPPORT_STATIC_ENTRIES -#define ETHARP_FLAG_STATIC_ENTRY 4 -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#if LWIP_NETIF_HWADDRHINT -#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ - *((netif)->addr_hint) = (hint); -#else /* LWIP_NETIF_HWADDRHINT */ -#define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) -#endif /* LWIP_NETIF_HWADDRHINT */ - - -/* Some checks, instead of etharp_init(): */ -#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) - #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" -#endif - - -#if ARP_QUEUEING -/** - * Free a complete queue of etharp entries - * - * @param q a qeueue of etharp_q_entry's to free - */ -static void -free_etharp_q(struct etharp_q_entry *q) -{ - struct etharp_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("q->p != NULL", q->p != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ARP_QUEUE, r); - } -} -#else /* ARP_QUEUEING */ - -/** Compatibility define: free the queued pbuf */ -#define free_etharp_q(q) pbuf_free(q) - -#endif /* ARP_QUEUEING */ - -/** Clean up ARP table entries */ -static void -etharp_free_entry(int i) -{ - /* remove from SNMP ARP index tree */ - snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); - /* and empty packet queue */ - if (arp_table[i].q != NULL) { - /* remove all queued packets */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); - free_etharp_q(arp_table[i].q); - arp_table[i].q = NULL; - } - /* recycle entry for re-use */ - arp_table[i].state = ETHARP_STATE_EMPTY; -#ifdef LWIP_DEBUG - /* for debugging, clean out the complete entry */ - arp_table[i].ctime = 0; - arp_table[i].netif = NULL; - ip_addr_set_zero(&arp_table[i].ipaddr); - arp_table[i].ethaddr = ethzero; -#endif /* LWIP_DEBUG */ -} - -/** - * Clears expired entries in the ARP table. - * - * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), - * in order to expire entries in the ARP table. - */ -void -etharp_tmr(void) -{ - u8_t i; - - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); - /* remove expired entries from the ARP table */ - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if (state != ETHARP_STATE_EMPTY -#if ETHARP_SUPPORT_STATIC_ENTRIES - && (state != ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - ) { - arp_table[i].ctime++; - if ((arp_table[i].ctime >= ARP_MAXAGE) || - ((arp_table[i].state == ETHARP_STATE_PENDING) && - (arp_table[i].ctime >= ARP_MAXPENDING))) { - /* pending or stable entry has become old! */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", - arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); - /* clean up entries that have just been expired */ - etharp_free_entry(i); - } - else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { - /* Reset state to stable, so that the next transmitted packet will - re-send an ARP request. */ - arp_table[i].state = ETHARP_STATE_STABLE; - } -#if ARP_QUEUEING - /* still pending entry? (not expired) */ - if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* resend an ARP query here? */ - } -#endif /* ARP_QUEUEING */ - } - } -} - -/** - * Search the ARP table for a matching or new entry. - * - * If an IP address is given, return a pending or stable ARP entry that matches - * the address. If no match is found, create a new entry with this address set, - * but in state ETHARP_EMPTY. The caller must check and possibly change the - * state of the returned entry. - * - * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. - * - * In all cases, attempt to create new entries from an empty entry. If no - * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle - * old entries. Heuristic choose the least important entry for recycling. - * - * @param ipaddr IP address to find in ARP cache, or to add if not found. - * @param flags @see definition of ETHARP_FLAG_* - * @param netif netif related to this address (used for NETIF_HWADDRHINT) - * - * @return The ARP entry index that matched or is created, ERR_MEM if no - * entry is found or could be recycled. - */ -static s8_t -etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) -{ - s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; - s8_t empty = ARP_TABLE_SIZE; - u8_t i = 0, age_pending = 0, age_stable = 0; - /* oldest entry with packets on queue */ - s8_t old_queue = ARP_TABLE_SIZE; - /* its age */ - u8_t age_queue = 0; - - /** - * a) do a search through the cache, remember candidates - * b) select candidate entry - * c) create new entry - */ - - /* a) in a single search sweep, do all of this - * 1) remember the first empty entry (if any) - * 2) remember the oldest stable entry (if any) - * 3) remember the oldest pending entry without queued packets (if any) - * 4) remember the oldest pending entry with queued packets (if any) - * 5) search for a matching IP entry, either pending or stable - * until 5 matches, or all entries are searched for. - */ - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - /* no empty entry found yet and now we do find one? */ - if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); - /* remember first empty entry */ - empty = i; - } else if (state != ETHARP_STATE_EMPTY) { - LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", - state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); - /* if given, does IP address match IP address in ARP entry? */ - if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); - /* found exact IP address match, simply bail out */ - return i; - } - /* pending entry? */ - if (state == ETHARP_STATE_PENDING) { - /* pending with queued packets? */ - if (arp_table[i].q != NULL) { - if (arp_table[i].ctime >= age_queue) { - old_queue = i; - age_queue = arp_table[i].ctime; - } - } else - /* pending without queued packets? */ - { - if (arp_table[i].ctime >= age_pending) { - old_pending = i; - age_pending = arp_table[i].ctime; - } - } - /* stable entry? */ - } else if (state >= ETHARP_STATE_STABLE) { -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* don't record old_stable for static entries since they never expire */ - if (state < ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* remember entry with oldest stable entry in oldest, its age in maxtime */ - if (arp_table[i].ctime >= age_stable) { - old_stable = i; - age_stable = arp_table[i].ctime; - } - } - } - } - } - /* { we have no match } => try to create a new entry */ - - /* don't create new entry, only search? */ - if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || - /* or no empty entry found and not allowed to recycle? */ - ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); - return (s8_t)ERR_MEM; - } - - /* b) choose the least destructive entry to recycle: - * 1) empty entry - * 2) oldest stable entry - * 3) oldest pending entry without queued packets - * 4) oldest pending entry with queued packets - * - * { ETHARP_FLAG_TRY_HARD is set at this point } - */ - - /* 1) empty entry available? */ - if (empty < ARP_TABLE_SIZE) { - i = empty; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); - } else { - /* 2) found recyclable stable entry? */ - if (old_stable < ARP_TABLE_SIZE) { - /* recycle oldest stable*/ - i = old_stable; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); - /* no queued packets should exist on stable entries */ - LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); - /* 3) found recyclable pending entry without queued packets? */ - } else if (old_pending < ARP_TABLE_SIZE) { - /* recycle oldest pending */ - i = old_pending; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); - /* 4) found recyclable pending entry with queued packets? */ - } else if (old_queue < ARP_TABLE_SIZE) { - /* recycle oldest pending (queued packets are free in etharp_free_entry) */ - i = old_queue; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); - /* no empty or recyclable entries found */ - } else { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); - return (s8_t)ERR_MEM; - } - - /* { empty or recyclable entry found } */ - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - etharp_free_entry(i); - } - - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", - arp_table[i].state == ETHARP_STATE_EMPTY); - - /* IP address given? */ - if (ipaddr != NULL) { - /* set IP address */ - ip_addr_copy(arp_table[i].ipaddr, *ipaddr); - } - arp_table[i].ctime = 0; - return (err_t)i; -} - -/** - * Send an IP packet on the network using netif->linkoutput - * The ethernet header is filled in before sending. - * - * @params netif the lwIP network interface on which to send the packet - * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header - * @params src the source MAC address to be copied into the ethernet header - * @params dst the destination MAC address to be copied into the ethernet header - * @return ERR_OK if the packet was sent, any other err_t on failure - */ -static err_t -etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) -{ - struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; - - LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", - (netif->hwaddr_len == ETHARP_HWADDR_LEN)); - ETHADDR32_COPY(ðhdr->dest, dst); - ETHADDR16_COPY(ðhdr->src, src); - ethhdr->type = PP_HTONS(ETHTYPE_IP); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); - /* send the packet */ - return netif->linkoutput(netif, p); -} - -/** - * Update (or insert) a IP/MAC address pair in the ARP cache. - * - * If a pending entry is resolved, any queued packets will be sent - * at this point. - * - * @param netif netif related to this entry (used for NETIF_ADDRHINT) - * @param ipaddr IP address of the inserted ARP entry. - * @param ethaddr Ethernet address of the inserted ARP entry. - * @param flags @see definition of ETHARP_FLAG_* - * - * @return - * - ERR_OK Succesfully updated ARP cache. - * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - * @see pbuf_free() - */ -static err_t -etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) -{ - s8_t i; - LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], - ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); - /* non-unicast address? */ - if (ip_addr_isany(ipaddr) || - ip_addr_isbroadcast(ipaddr, netif) || - ip_addr_ismulticast(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, flags); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - -#if ETHARP_SUPPORT_STATIC_ENTRIES - if (flags & ETHARP_FLAG_STATIC_ENTRY) { - /* record static type */ - arp_table[i].state = ETHARP_STATE_STATIC; - } else -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* mark it stable */ - arp_table[i].state = ETHARP_STATE_STABLE; - } - - /* record network interface */ - arp_table[i].netif = netif; - /* insert in SNMP ARP index tree */ - snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); - - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); - /* update address */ - ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); - /* reset time stamp */ - arp_table[i].ctime = 0; - /* this is where we will send out queued packets! */ -#if ARP_QUEUEING - while (arp_table[i].q != NULL) { - struct pbuf *p; - /* remember remainder of queue */ - struct etharp_q_entry *q = arp_table[i].q; - /* pop first item off the queue */ - arp_table[i].q = q->next; - /* get the packet pointer */ - p = q->p; - /* now queue entry can be freed */ - memp_free(MEMP_ARP_QUEUE, q); -#else /* ARP_QUEUEING */ - if (arp_table[i].q != NULL) { - struct pbuf *p = arp_table[i].q; - arp_table[i].q = NULL; -#endif /* ARP_QUEUEING */ - /* send the queued IP packet */ - etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); - /* free the queued IP packet */ - pbuf_free(p); - } - return ERR_OK; -} - -#if ETHARP_SUPPORT_STATIC_ENTRIES -/** Add a new static entry to the ARP table. If an entry exists for the - * specified IP address, this entry is overwritten. - * If packets are queued for the specified IP address, they are sent out. - * - * @param ipaddr IP address for the new static entry - * @param ethaddr ethernet address for the new static entry - * @return @see return values of etharp_add_static_entry - */ -err_t -etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) -{ - struct netif *netif; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], - ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); - - netif = ip_route(ipaddr); - if (netif == NULL) { - return ERR_RTE; - } - - return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); -} - -/** Remove a static entry from the ARP table previously added with a call to - * etharp_add_static_entry. - * - * @param ipaddr IP address of the static entry to remove - * @return ERR_OK: entry removed - * ERR_MEM: entry wasn't found - * ERR_ARG: entry wasn't a static entry but a dynamic one - */ -err_t -etharp_remove_static_entry(ip_addr_t *ipaddr) -{ - s8_t i; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); - - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - - if (arp_table[i].state != ETHARP_STATE_STATIC) { - /* entry wasn't a static entry, cannot remove it */ - return ERR_ARG; - } - /* entry found, free it */ - etharp_free_entry(i); - return ERR_OK; -} -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -/** - * Remove all ARP table entries of the specified netif. - * - * @param netif points to a network interface - */ -void etharp_cleanup_netif(struct netif *netif) -{ - u8_t i; - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { - etharp_free_entry(i); - } - } -} - -/** - * Finds (stable) ethernet/IP address pair from ARP table - * using interface and IP address index. - * @note the addresses in the ARP table are in network order! - * - * @param netif points to interface index - * @param ipaddr points to the (network order) IP address index - * @param eth_ret points to return pointer - * @param ip_ret points to return pointer - * @return table index if found, -1 otherwise - */ -s8_t -etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, - struct eth_addr **eth_ret, ip_addr_t **ip_ret) -{ - s8_t i; - - LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", - eth_ret != NULL && ip_ret != NULL); - - LWIP_UNUSED_ARG(netif); - - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); - if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { - *eth_ret = &arp_table[i].ethaddr; - *ip_ret = &arp_table[i].ipaddr; - return i; - } - return -1; -} - -#if ETHARP_TRUST_IP_MAC -/** - * Updates the ARP table using the given IP packet. - * - * Uses the incoming IP packet's source address to update the - * ARP cache for the local network. The function does not alter - * or free the packet. This function must be called before the - * packet p is passed to the IP layer. - * - * @param netif The lwIP network interface on which the IP packet pbuf arrived. - * @param p The IP packet that arrived on netif. - * - * @return NULL - * - * @see pbuf_free() - */ -static void -etharp_ip_input(struct netif *netif, struct pbuf *p) -{ - struct eth_hdr *ethhdr; - struct ip_hdr *iphdr; - ip_addr_t iphdr_src; - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - /* Only insert an entry if the source IP address of the - incoming IP packet comes from a host on the local network. */ - ethhdr = (struct eth_hdr *)p->payload; - iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); -#if ETHARP_SUPPORT_VLAN - if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { - iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); - } -#endif /* ETHARP_SUPPORT_VLAN */ - - ip_addr_copy(iphdr_src, iphdr->src); - - /* source is not on the local network? */ - if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) { - /* do nothing */ - return; - } - - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); - /* update the source IP address in the cache, if present */ - /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk - * back soon (for example, if the destination IP address is ours. */ - etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); -} -#endif /* ETHARP_TRUST_IP_MAC */ - -/** - * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache - * send out queued IP packets. Updates cache with snooped address pairs. - * - * Should be called for incoming ARP packets. The pbuf in the argument - * is freed by this function. - * - * @param netif The lwIP network interface on which the ARP packet pbuf arrived. - * @param ethaddr Ethernet address of netif. - * @param p The ARP packet that arrived on netif. Is freed by this function. - * - * @return NULL - * - * @see pbuf_free() - */ -static void -etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) -{ - struct etharp_hdr *hdr; - struct eth_hdr *ethhdr; - /* these are aligned properly, whereas the ARP header fields might not be */ - ip_addr_t sipaddr, dipaddr; - u8_t for_us; -#if LWIP_AUTOIP - const u8_t * ethdst_hwaddr; -#endif /* LWIP_AUTOIP */ - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - /* drop short ARP packets: we have to check for p->len instead of p->tot_len here - since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ - if (p->len < SIZEOF_ETHARP_PACKET) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, - (s16_t)SIZEOF_ETHARP_PACKET)); - ETHARP_STATS_INC(etharp.lenerr); - ETHARP_STATS_INC(etharp.drop); - pbuf_free(p); - return; - } - - ethhdr = (struct eth_hdr *)p->payload; - hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); -#if ETHARP_SUPPORT_VLAN - if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { - hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); - } -#endif /* ETHARP_SUPPORT_VLAN */ - - /* RFC 826 "Packet Reception": */ - if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || - (hdr->hwlen != ETHARP_HWADDR_LEN) || - (hdr->protolen != sizeof(ip_addr_t)) || - (hdr->proto != PP_HTONS(ETHTYPE_IP))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", - hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - pbuf_free(p); - return; - } - ETHARP_STATS_INC(etharp.recv); - -#if LWIP_AUTOIP - /* We have to check if a host already has configured our random - * created link local address and continously check if there is - * a host with this IP-address so we can detect collisions */ - autoip_arp_reply(netif, hdr); -#endif /* LWIP_AUTOIP */ - - /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). */ - IPADDR2_COPY(&sipaddr, &hdr->sipaddr); - IPADDR2_COPY(&dipaddr, &hdr->dipaddr); - - /* this interface is not configured? */ - if (ip_addr_isany(&netif->ip_addr)) { - for_us = 0; - } else { - /* ARP packet directed to us? */ - for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); - } - - /* ARP message directed to us? - -> add IP address in ARP cache; assume requester wants to talk to us, - can result in directly sending the queued packets for this host. - ARP message not directed to us? - -> update the source IP address in the cache, if present */ - etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), - for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); - - /* now act on the message itself */ - switch (hdr->opcode) { - /* ARP request? */ - case PP_HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a - * reply. In any case, we time-stamp any existing ARP entry, - * and possiby send out an IP packet that was queued on it. */ - - LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); - /* ARP request for our address? */ - if (for_us) { - - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); - /* Re-use pbuf to send ARP reply. - Since we are re-using an existing pbuf, we can't call etharp_raw since - that would allocate a new pbuf. */ - hdr->opcode = htons(ARP_REPLY); - - IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); - IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); - - LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", - (netif->hwaddr_len == ETHARP_HWADDR_LEN)); -#if LWIP_AUTOIP - /* If we are using Link-Local, all ARP packets that contain a Link-Local - * 'sender IP address' MUST be sent using link-layer broadcast instead of - * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ - ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; -#endif /* LWIP_AUTOIP */ - - ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); -#if LWIP_AUTOIP - ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); -#else /* LWIP_AUTOIP */ - ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); -#endif /* LWIP_AUTOIP */ - ETHADDR16_COPY(&hdr->shwaddr, ethaddr); - ETHADDR16_COPY(ðhdr->src, ethaddr); - - /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header - are already correct, we tested that before */ - - /* return ARP reply */ - netif->linkoutput(netif, p); - /* we are not configured? */ - } else if (ip_addr_isany(&netif->ip_addr)) { - /* { for_us == 0 and netif->ip_addr.addr == 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); - /* request was not directed to us */ - } else { - /* { for_us == 0 and netif->ip_addr.addr != 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); - } - break; - case PP_HTONS(ARP_REPLY): - /* ARP reply. We already updated the ARP cache earlier. */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); -#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) - /* DHCP wants to know about ARP replies from any host with an - * IP address also offered to us by the DHCP server. We do not - * want to take a duplicate IP address on a single network. - * @todo How should we handle redundant (fail-over) interfaces? */ - dhcp_arp_reply(netif, &sipaddr); -#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ - break; - default: - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); - ETHARP_STATS_INC(etharp.err); - break; - } - /* free ARP packet */ - pbuf_free(p); -} - -/** Just a small helper function that sends a pbuf to an ethernet address - * in the arp_table specified by the index 'arp_idx'. - */ -static err_t -etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) -{ - LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", - arp_table[arp_idx].state >= ETHARP_STATE_STABLE); - /* if arp table entry is about to expire: re-request it, - but only if its state is ETHARP_STATE_STABLE to prevent flooding the - network with ARP requests if this address is used frequently. */ - if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && - (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { - if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { - arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; - } - } - - return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), - &arp_table[arp_idx].ethaddr); -} - -/** - * Resolve and fill-in Ethernet address header for outgoing IP packet. - * - * For IP multicast and broadcast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, the packet is submitted to etharp_query(). In - * case the IP address is outside the local network, the IP address of - * the gateway is used. - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ipaddr The IP address of the packet destination. - * - * @return - * - ERR_RTE No route to destination (no gateway to external networks), - * or the return type of either etharp_query() or etharp_send_ip(). - */ -err_t -etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) -{ - struct eth_addr *dest; - struct eth_addr mcastaddr; - ip_addr_t *dst_addr = ipaddr; - - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); - - /* make room for Ethernet header - should not fail */ - if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { - /* bail out */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("etharp_output: could not allocate room for header.\n")); - LINK_STATS_INC(link.lenerr); - return ERR_BUF; - } - - /* Determine on destination hardware address. Broadcasts and multicasts - * are special, other IP addresses are looked up in the ARP table. */ - - /* broadcast destination IP address? */ - if (ip_addr_isbroadcast(ipaddr, netif)) { - /* broadcast on Ethernet also */ - dest = (struct eth_addr *)ðbroadcast; - /* multicast destination IP address? */ - } else if (ip_addr_ismulticast(ipaddr)) { - /* Hash IP multicast address to MAC address.*/ - mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; - mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; - mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; - mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; - mcastaddr.addr[4] = ip4_addr3(ipaddr); - mcastaddr.addr[5] = ip4_addr4(ipaddr); - /* destination Ethernet address is multicast */ - dest = &mcastaddr; - /* unicast destination IP address? */ - } else { - s8_t i; - /* outside local network? if so, this can neither be a global broadcast nor - a subnet broadcast. */ - if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && - !ip_addr_islinklocal(ipaddr)) { -#if LWIP_AUTOIP - struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload + - sizeof(struct eth_hdr)); - /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with - a link-local source address must always be "directly to its destination - on the same physical link. The host MUST NOT send the packet to any - router for forwarding". */ - if (!ip_addr_islinklocal(&iphdr->src)) -#endif /* LWIP_AUTOIP */ - { - /* interface has default gateway? */ - if (!ip_addr_isany(&netif->gw)) { - /* send to hardware address of default gateway IP address */ - dst_addr = &(netif->gw); - /* no default gateway available */ - } else { - /* no route to destination error (default gateway missing) */ - return ERR_RTE; - } - } - } -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - u8_t etharp_cached_entry = *(netif->addr_hint); - if (etharp_cached_entry < ARP_TABLE_SIZE) { -#endif /* LWIP_NETIF_HWADDRHINT */ - if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && - (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { - /* the per-pcb-cached entry is stable and the right one! */ - ETHARP_STATS_INC(etharp.cachehit); - return etharp_output_to_arp_index(netif, q, etharp_cached_entry); - } -#if LWIP_NETIF_HWADDRHINT - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* find stable entry: do this here since this is a critical path for - throughput and etharp_find_entry() is kind of slow */ - for (i = 0; i < ARP_TABLE_SIZE; i++) { - if ((arp_table[i].state >= ETHARP_STATE_STABLE) && - (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { - /* found an existing, stable entry */ - ETHARP_SET_HINT(netif, i); - return etharp_output_to_arp_index(netif, q, i); - } - } - /* no stable entry found, use the (slower) query function: - queue on destination Ethernet address belonging to ipaddr */ - return etharp_query(netif, dst_addr, q); - } - - /* continuation for multicast/broadcast destinations */ - /* obtain source Ethernet address of the given interface */ - /* send packet directly on the link */ - return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); -} - -/** - * Send an ARP request for the given IP address and/or queue a packet. - * - * If the IP address was not yet in the cache, a pending ARP cache entry - * is added and an ARP request is sent for the given address. The packet - * is queued on this entry. - * - * If the IP address was already pending in the cache, a new ARP request - * is sent for the given address. The packet is queued on this entry. - * - * If the IP address was already stable in the cache, and a packet is - * given, it is directly sent and no ARP request is sent out. - * - * If the IP address was already stable in the cache, and no packet is - * given, an ARP request is sent out. - * - * @param netif The lwIP network interface on which ipaddr - * must be queried for. - * @param ipaddr The IP address to be resolved. - * @param q If non-NULL, a pbuf that must be delivered to the IP address. - * q is not freed by this function. - * - * @note q must only be ONE packet, not a packet queue! - * - * @return - * - ERR_BUF Could not make room for Ethernet header. - * - ERR_MEM Hardware address unknown, and no more ARP entries available - * to query for address or queue the packet. - * - ERR_MEM Could not queue packet due to memory shortage. - * - ERR_RTE No route to destination (no gateway to external networks). - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - */ -err_t -etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) -{ - struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; - err_t result = ERR_MEM; - s8_t i; /* ARP entry index */ - - /* non-unicast address? */ - if (ip_addr_isbroadcast(ipaddr, netif) || - ip_addr_ismulticast(ipaddr) || - ip_addr_isany(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - - /* find entry in ARP cache, ask to create entry if queueing packet */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); - - /* could not find or create entry? */ - if (i < 0) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); - if (q) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); - ETHARP_STATS_INC(etharp.memerr); - } - return (err_t)i; - } - - /* mark a fresh entry as pending (we just sent a request) */ - if (arp_table[i].state == ETHARP_STATE_EMPTY) { - arp_table[i].state = ETHARP_STATE_PENDING; - } - - /* { i is either a STABLE or (new or existing) PENDING entry } */ - LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", - ((arp_table[i].state == ETHARP_STATE_PENDING) || - (arp_table[i].state >= ETHARP_STATE_STABLE))); - - /* do we have a pending entry? or an implicit query request? */ - if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { - /* try to resolve it; send out ARP request */ - result = etharp_request(netif, ipaddr); - if (result != ERR_OK) { - /* ARP request couldn't be sent */ - /* We don't re-send arp request in etharp_tmr, but we still queue packets, - since this failure could be temporary, and the next packet calling - etharp_query again could lead to sending the queued packets. */ - } - if (q == NULL) { - return result; - } - } - - /* packet given? */ - LWIP_ASSERT("q != NULL", q != NULL); - /* stable entry? */ - if (arp_table[i].state >= ETHARP_STATE_STABLE) { - /* we have a valid IP->Ethernet address mapping */ - ETHARP_SET_HINT(netif, i); - /* send the packet */ - result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); - /* pending entry? (either just created or already pending */ - } else if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* entry is still pending, queue the given packet 'q' */ - struct pbuf *p; - int copy_needed = 0; - /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but - * to copy the whole queue into a new PBUF_RAM (see bug #11400) - * PBUF_ROMs can be left as they are, since ROM must not get changed. */ - p = q; - while (p) { - LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); - if(p->type != PBUF_ROM) { - copy_needed = 1; - break; - } - p = p->next; - } - if(copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(p != NULL) { - if (pbuf_copy(p, q) != ERR_OK) { - pbuf_free(p); - p = NULL; - } - } - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet could be taken over? */ - if (p != NULL) { - /* queue packet ... */ -#if ARP_QUEUEING - struct etharp_q_entry *new_entry; - /* allocate a new arp queue entry */ - new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); - if (new_entry != NULL) { - new_entry->next = 0; - new_entry->p = p; - if(arp_table[i].q != NULL) { - /* queue was already existent, append the new entry to the end */ - struct etharp_q_entry *r; - r = arp_table[i].q; - while (r->next != NULL) { - r = r->next; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - arp_table[i].q = new_entry; - } - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); - result = ERR_OK; - } else { - /* the pool MEMP_ARP_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } -#else /* ARP_QUEUEING */ - /* always queue one packet per ARP request only, freeing a previously queued packet */ - if (arp_table[i].q != NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); - pbuf_free(arp_table[i].q); - } - arp_table[i].q = p; - result = ERR_OK; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); -#endif /* ARP_QUEUEING */ - } else { - ETHARP_STATS_INC(etharp.memerr); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } - } - return result; -} - -/** - * Send a raw ARP packet (opcode and all addresses can be modified) - * - * @param netif the lwip network interface on which to send the ARP packet - * @param ethsrc_addr the source MAC address for the ethernet header - * @param ethdst_addr the destination MAC address for the ethernet header - * @param hwsrc_addr the source MAC address for the ARP protocol header - * @param ipsrc_addr the source IP address for the ARP protocol header - * @param hwdst_addr the destination MAC address for the ARP protocol header - * @param ipdst_addr the destination IP address for the ARP protocol header - * @param opcode the type of the ARP packet - * @return ERR_OK if the ARP packet has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -#if !LWIP_AUTOIP -static -#endif /* LWIP_AUTOIP */ -err_t -etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, - const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, - const u16_t opcode) -{ - struct pbuf *p; - err_t result = ERR_OK; - struct eth_hdr *ethhdr; - struct etharp_hdr *hdr; -#if LWIP_AUTOIP - const u8_t * ethdst_hwaddr; -#endif /* LWIP_AUTOIP */ - - LWIP_ASSERT("netif != NULL", netif != NULL); - - /* allocate a pbuf for the outgoing ARP request packet */ - p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); - /* could allocate a pbuf for an ARP request? */ - if (p == NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("etharp_raw: could not allocate pbuf for ARP request.\n")); - ETHARP_STATS_INC(etharp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", - (p->len >= SIZEOF_ETHARP_PACKET)); - - ethhdr = (struct eth_hdr *)p->payload; - hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); - hdr->opcode = htons(opcode); - - LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", - (netif->hwaddr_len == ETHARP_HWADDR_LEN)); -#if LWIP_AUTOIP - /* If we are using Link-Local, all ARP packets that contain a Link-Local - * 'sender IP address' MUST be sent using link-layer broadcast instead of - * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ - ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; -#endif /* LWIP_AUTOIP */ - /* Write the ARP MAC-Addresses */ - ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); - ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); - /* Write the Ethernet MAC-Addresses */ -#if LWIP_AUTOIP - ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); -#else /* LWIP_AUTOIP */ - ETHADDR16_COPY(ðhdr->dest, ethdst_addr); -#endif /* LWIP_AUTOIP */ - ETHADDR16_COPY(ðhdr->src, ethsrc_addr); - /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without - * structure packing. */ - IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); - IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); - - hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); - hdr->proto = PP_HTONS(ETHTYPE_IP); - /* set hwlen and protolen */ - hdr->hwlen = ETHARP_HWADDR_LEN; - hdr->protolen = sizeof(ip_addr_t); - - ethhdr->type = PP_HTONS(ETHTYPE_ARP); - /* send ARP query */ - result = netif->linkoutput(netif, p); - ETHARP_STATS_INC(etharp.xmit); - /* free ARP query packet */ - pbuf_free(p); - p = NULL; - /* could not allocate pbuf for ARP request */ - - return result; -} - -/** - * Send an ARP request packet asking for ipaddr. - * - * @param netif the lwip network interface on which to send the request - * @param ipaddr the IP address for which to ask - * @return ERR_OK if the request has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -err_t -etharp_request(struct netif *netif, ip_addr_t *ipaddr) -{ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); - return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, - (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, - ipaddr, ARP_REQUEST); -} -#endif /* LWIP_ARP */ - -/** - * Process received ethernet frames. Using this function instead of directly - * calling ip_input and passing ARP frames through etharp in ethernetif_input, - * the ARP cache is protected from concurrent access. - * - * @param p the recevied packet, p->payload pointing to the ethernet header - * @param netif the network interface on which the packet was received - */ -err_t -ethernet_input(struct pbuf *p, struct netif *netif) -{ - struct eth_hdr* ethhdr; - u16_t type; -#if LWIP_ARP || ETHARP_SUPPORT_VLAN - s16_t ip_hdr_offset = SIZEOF_ETH_HDR; -#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ - - if (p->len <= SIZEOF_ETH_HDR) { - /* a packet with only an ethernet header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - goto free_and_return; - } - - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = (struct eth_hdr *)p->payload; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, - ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", - (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], - (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], - (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], - (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], - (unsigned)htons(ethhdr->type))); - - type = ethhdr->type; -#if ETHARP_SUPPORT_VLAN - if (type == PP_HTONS(ETHTYPE_VLAN)) { - struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); - if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { - /* a packet with only an ethernet/vlan header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - goto free_and_return; - } -#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ -#ifdef ETHARP_VLAN_CHECK_FN - if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { -#elif defined(ETHARP_VLAN_CHECK) - if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { -#endif - /* silently ignore this packet: not for our VLAN */ - pbuf_free(p); - return ERR_OK; - } -#endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ - type = vlan->tpid; - ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; - } -#endif /* ETHARP_SUPPORT_VLAN */ - -#if LWIP_ARP_FILTER_NETIF - netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); -#endif /* LWIP_ARP_FILTER_NETIF*/ - - if (ethhdr->dest.addr[0] & 1) { - /* this might be a multicast or broadcast packet */ - if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { - if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && - (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { - /* mark the pbuf as link-layer multicast */ - p->flags |= PBUF_FLAG_LLMCAST; - } - } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { - /* mark the pbuf as link-layer broadcast */ - p->flags |= PBUF_FLAG_LLBCAST; - } - } - - switch (type) { -#if LWIP_ARP - /* IP packet? */ - case PP_HTONS(ETHTYPE_IP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } -#if ETHARP_TRUST_IP_MAC - /* update ARP table */ - etharp_ip_input(netif, p); -#endif /* ETHARP_TRUST_IP_MAC */ - /* skip Ethernet header */ - if(pbuf_header(p, -ip_hdr_offset)) { - LWIP_ASSERT("Can't move over header in packet", 0); - goto free_and_return; - } else { - /* pass to IP layer */ - ip_input(p, netif); - } - break; - - case PP_HTONS(ETHTYPE_ARP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } - /* pass p to ARP module */ - etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); - break; -#endif /* LWIP_ARP */ -#if PPPOE_SUPPORT - case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ - pppoe_disc_input(netif, p); - break; - - case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ - pppoe_data_input(netif, p); - break; -#endif /* PPPOE_SUPPORT */ - -#if LWIP_IPV6 - case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */ - /* skip Ethernet header */ - if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { - LWIP_ASSERT("Can't move over header in packet", 0); - goto free_and_return; - } else { - /* pass to IPv6 layer */ - ip6_input(p, netif); - } - break; -#endif /* LWIP_IPV6 */ - - default: - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - goto free_and_return; - } - - /* This means the pbuf is freed or consumed, - so the caller doesn't have to free it again */ - return ERR_OK; - -free_and_return: - pbuf_free(p); - return ERR_OK; -} -#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/external/badvpn_dns/lwip/src/netif/ethernetif.c b/external/badvpn_dns/lwip/src/netif/ethernetif.c deleted file mode 100644 index 46900bd..0000000 --- a/external/badvpn_dns/lwip/src/netif/ethernetif.c +++ /dev/null @@ -1,322 +0,0 @@ -/** - * @file - * Ethernet Interface Skeleton - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels adam@sics.se - * - */ - -/* - * This file is a skeleton for developing Ethernet network interface - * drivers for lwIP. Add code to the low_level functions and do a - * search-and-replace for the word "ethernetif" to replace it with - * something that better describes your network interface. - */ - -#include "lwip/opt.h" - -#if 0 /* don't build, this is only a skeleton, see previous comment */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/ethip6.h" -#include "netif/etharp.h" -#include "netif/ppp_oe.h" - -/* Define those to better describe your network interface. */ -#define IFNAME0 'e' -#define IFNAME1 'n' - -/** - * Helper struct to hold private data used to operate your ethernet interface. - * Keeping the ethernet address of the MAC in this struct is not necessary - * as it is already kept in the struct netif. - * But this is only an example, anyway... - */ -struct ethernetif { - struct eth_addr *ethaddr; - /* Add whatever per-interface state that is needed here. */ -}; - -/* Forward declarations. */ -static void ethernetif_input(struct netif *netif); - -/** - * In this function, the hardware should be initialized. - * Called from ethernetif_init(). - * - * @param netif the already initialized lwip network interface structure - * for this ethernetif - */ -static void -low_level_init(struct netif *netif) -{ - struct ethernetif *ethernetif = netif->state; - - /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; - - /* set MAC hardware address */ - netif->hwaddr[0] = ; - ... - netif->hwaddr[5] = ; - - /* maximum transfer unit */ - netif->mtu = 1500; - - /* device capabilities */ - /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; - - /* Do whatever else is needed to initialize interface. */ -} - -/** - * This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this ethernetif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent - * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become availale since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - */ - -static err_t -low_level_output(struct netif *netif, struct pbuf *p) -{ - struct ethernetif *ethernetif = netif->state; - struct pbuf *q; - - initiate transfer(); - -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - - for(q = p; q != NULL; q = q->next) { - /* Send the data from the pbuf to the interface, one pbuf at a - time. The size of the data in each pbuf is kept in the ->len - variable. */ - send data from(q->payload, q->len); - } - - signal that packet should be sent(); - -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.xmit); - - return ERR_OK; -} - -/** - * Should allocate a pbuf and transfer the bytes of the incoming - * packet from the interface into the pbuf. - * - * @param netif the lwip network interface structure for this ethernetif - * @return a pbuf filled with the received packet (including MAC header) - * NULL on memory error - */ -static struct pbuf * -low_level_input(struct netif *netif) -{ - struct ethernetif *ethernetif = netif->state; - struct pbuf *p, *q; - u16_t len; - - /* Obtain the size of the packet and put it into the "len" - variable. */ - len = ; - -#if ETH_PAD_SIZE - len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ -#endif - - /* We allocate a pbuf chain of pbufs from the pool. */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - - if (p != NULL) { - -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - - /* We iterate over the pbuf chain until we have read the entire - * packet into the pbuf. */ - for(q = p; q != NULL; q = q->next) { - /* Read enough bytes to fill this pbuf in the chain. The - * available data in the pbuf is given by the q->len - * variable. - * This does not necessarily have to be a memcpy, you can also preallocate - * pbufs for a DMA-enabled MAC and after receiving truncate it to the - * actually received size. In this case, ensure the tot_len member of the - * pbuf is the sum of the chained pbuf len members. - */ - read data into(q->payload, q->len); - } - acknowledge that packet has been read(); - -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.recv); - } else { - drop packet(); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - } - - return p; -} - -/** - * This function should be called when a packet is ready to be read - * from the interface. It uses the function low_level_input() that - * should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -static void -ethernetif_input(struct netif *netif) -{ - struct ethernetif *ethernetif; - struct eth_hdr *ethhdr; - struct pbuf *p; - - ethernetif = netif->state; - - /* move received packet into a new pbuf */ - p = low_level_input(netif); - /* no packet could be read, silently ignore this */ - if (p == NULL) return; - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = p->payload; - - switch (htons(ethhdr->type)) { - /* IP or ARP packet? */ - case ETHTYPE_IP: - case ETHTYPE_IPV6: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - /* PPPoE packet? */ - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif)!=ERR_OK) - { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - pbuf_free(p); - p = NULL; - } - break; - - default: - pbuf_free(p); - p = NULL; - break; - } -} - -/** - * Should be called at the beginning of the program to set up the - * network interface. It calls the function low_level_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t -ethernetif_init(struct netif *netif) -{ - struct ethernetif *ethernetif; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - - ethernetif = mem_malloc(sizeof(struct ethernetif)); - if (ethernetif == NULL) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); - return ERR_MEM; - } - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ - NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - - netif->state = ethernetif; - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - netif->output = etharp_output; -#if LWIP_IPV6 - netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - netif->linkoutput = low_level_output; - - ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); - - /* initialize the hardware */ - low_level_init(netif); - - return ERR_OK; -} - -#endif /* 0 */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/auth.c b/external/badvpn_dns/lwip/src/netif/ppp/auth.c deleted file mode 100644 index 0fd87a3..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/auth.c +++ /dev/null @@ -1,1334 +0,0 @@ -/***************************************************************************** -* auth.c - Network Authentication and Phase Control program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-08 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Ported from public pppd code. -*****************************************************************************/ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993 The Australian National University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the Australian National University. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "fsm.h" -#include "lcp.h" -#include "pap.h" -#include "chap.h" -#include "auth.h" -#include "ipcp.h" - -#if CBCP_SUPPORT -#include "cbcp.h" -#endif /* CBCP_SUPPORT */ - -#include "lwip/inet.h" - -#include <string.h> - -#if 0 /* UNUSED */ -/* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 - -#define ISWILD(word) (word[0] == '*' && word[1] == 0) -#endif /* UNUSED */ - -#if PAP_SUPPORT || CHAP_SUPPORT -/* The name by which the peer authenticated itself to us. */ -static char peer_authname[MAXNAMELEN]; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ - -/* Records which authentication operations haven't completed yet. */ -static int auth_pending[NUM_PPP]; - -/* Set if we have successfully called plogin() */ -static int logged_in; - -/* Set if we have run the /etc/ppp/auth-up script. */ -static int did_authup; /* @todo, we don't need this in lwip*/ - -/* List of addresses which the peer may use. */ -static struct wordlist *addresses[NUM_PPP]; - -#if 0 /* UNUSED */ -/* Wordlist giving addresses which the peer may use - without authenticating itself. */ -static struct wordlist *noauth_addrs; - -/* Extra options to apply, from the secrets file entry for the peer. */ -static struct wordlist *extra_options; -#endif /* UNUSED */ - -/* Number of network protocols which we have opened. */ -static int num_np_open; - -/* Number of network protocols which have come up. */ -static int num_np_up; - -#if PAP_SUPPORT || CHAP_SUPPORT -/* Set if we got the contents of passwd[] from the pap-secrets file. */ -static int passwd_from_file; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* Set if we require authentication only because we have a default route. */ -static bool default_auth; - -/* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; - -/* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook) __P((void)) = NULL; - -/* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)) = NULL; - -/* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) __P((void)) = NULL; - -/* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; - -/* - * This is used to ensure that we don't start an auth-up/down - * script while one is already running. - */ -enum script_state { - s_down, - s_up -}; - -static enum script_state auth_state = s_down; -static enum script_state auth_script_state = s_down; -static pid_t auth_script_pid = 0; - -/* - * Option variables. - * lwip: some of these are present in the ppp_settings structure - */ -bool uselogin = 0; /* Use /etc/passwd for checking PAP */ -bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ -bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ -bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ -bool usehostname = 0; /* Use hostname for our_name */ -bool auth_required = 0; /* Always require authentication from peer */ -bool allow_any_ip = 0; /* Allow peer to use any IP address */ -bool explicit_remote = 0; /* User specified explicit remote name */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ - -#endif /* UNUSED */ - -/* Bits in auth_pending[] */ -#define PAP_WITHPEER 1 -#define PAP_PEER 2 -#define CHAP_WITHPEER 4 -#define CHAP_PEER 8 - -/* @todo, move this somewhere */ -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char word[1]; -}; - - -extern char *crypt (const char *, const char *); - -/* Prototypes for procedures local to this file. */ - -static void network_phase (int); -static void check_idle (void *); -static void connect_time_expired (void *); -#if 0 -static int plogin (char *, char *, char **, int *); -#endif -static void plogout (void); -static int null_login (int); -static int get_pap_passwd (int, char *, char *); -static int have_pap_secret (void); -static int have_chap_secret (char *, char *, u32_t); -static int ip_addr_check (u32_t, struct wordlist *); - -#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ -static int scan_authfile (FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *); -static void free_wordlist (struct wordlist *); -static void auth_script (char *); -static void auth_script_done (void *); -static void set_allowed_addrs (int unit, struct wordlist *addrs); -static int some_ip_ok (struct wordlist *); -static int setupapfile (char **); -static int privgroup (char **); -static int set_noauth_addr (char **); -static void check_access (FILE *, char *); -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * Authentication-related options. - */ -option_t auth_options[] = { - { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required }, - { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required }, - { "refuse-pap", o_bool, &refuse_pap, - "Don't agree to auth to peer with PAP", 1 }, - { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", 1 }, - { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required }, - { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required }, - { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", 1 }, - { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", 1 }, - { "name", o_string, our_name, - "Set local name for authentication", - OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN }, - { "user", o_string, user, - "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN }, - { "usehostname", o_bool, &usehostname, - "Must use hostname for authentication", 1 }, - { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_STATIC, - &explicit_remote, MAXNAMELEN }, - { "auth", o_bool, &auth_required, - "Require authentication from peer", 1 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip }, - { "login", o_bool, &uselogin, - "Use system password database for PAP", 1 }, - { "papcrypt", o_bool, &cryptpap, - "PAP passwords are encrypted", 1 }, - { "+ua", o_special, (void *)setupapfile, - "Get PAP user and password from file" }, - { "password", o_string, passwd, - "Password for authenticating us to the peer", OPT_STATIC, - NULL, MAXSECRETLEN }, - { "privgroup", o_special, (void *)privgroup, - "Allow group members to use privileged options", OPT_PRIV }, - { "allow-ip", o_special, (void *)set_noauth_addr, - "Set IP address(es) which can be used without authentication", - OPT_PRIV }, - { NULL } -}; -#endif /* UNUSED */ -#if 0 /* UNUSED */ -/* - * setupapfile - specifies UPAP info for authenticating with peer. - */ -static int -setupapfile(char **argv) -{ - FILE * ufile; - int l; - - lcp_allowoptions[0].neg_upap = 1; - - /* open user info file */ - seteuid(getuid()); - ufile = fopen(*argv, "r"); - seteuid(0); - if (ufile == NULL) { - option_error("unable to open user login data file %s", *argv); - return 0; - } - check_access(ufile, *argv); - - /* get username */ - if (fgets(user, MAXNAMELEN - 1, ufile) == NULL - || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ - option_error("unable to read user login data file %s", *argv); - return 0; - } - fclose(ufile); - - /* get rid of newlines */ - l = strlen(user); - if (l > 0 && user[l-1] == '\n') - user[l-1] = 0; - l = strlen(passwd); - if (l > 0 && passwd[l-1] == '\n') - passwd[l-1] = 0; - - return (1); -} -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* - * privgroup - allow members of the group to have privileged access. - */ -static int -privgroup(char **argv) -{ - struct group *g; - int i; - - g = getgrnam(*argv); - if (g == 0) { - option_error("group %s is unknown", *argv); - return 0; - } - for (i = 0; i < ngroups; ++i) { - if (groups[i] == g->gr_gid) { - privileged = 1; - break; - } - } - return 1; -} -#endif - -#if 0 /* UNUSED */ -/* - * set_noauth_addr - set address(es) that can be used without authentication. - * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. - */ -static int -set_noauth_addr(char **argv) -{ - char *addr = *argv; - int l = strlen(addr); - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1); - if (wp == NULL) - novm("allow-ip argument"); - wp->word = (char *) (wp + 1); - wp->next = noauth_addrs; - BCOPY(addr, wp->word, l); - noauth_addrs = wp; - return 1; -} -#endif /* UNUSED */ - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - * Do what's necessary to bring the physical layer up. - */ -void -link_required(int unit) -{ - LWIP_UNUSED_ARG(unit); - - AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit)); -} - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void -link_terminated(int unit) -{ - AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit)); - if (lcp_phase[unit] == PHASE_DEAD) { - return; - } - if (logged_in) { - plogout(); - } - lcp_phase[unit] = PHASE_DEAD; - AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n")); - pppLinkTerminated(unit); -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void -link_down(int unit) -{ - int i; - struct protent *protp; - - AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit)); - - if (did_authup) { - /* XXX Do link down processing. */ - did_authup = 0; - } - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (!protp->enabled_flag) { - continue; - } - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) { - (*protp->lowerdown)(unit); - } - if (protp->protocol < 0xC000 && protp->close != NULL) { - (*protp->close)(unit, "LCP down"); - } - } - num_np_open = 0; /* number of network protocols we have opened */ - num_np_up = 0; /* Number of network protocols which have come up */ - - if (lcp_phase[unit] != PHASE_DEAD) { - lcp_phase[unit] = PHASE_TERMINATE; - } - pppLinkDown(unit); -} - -/* - * The link is established. - * Proceed to the Dead, Authenticate or Network phase as appropriate. - */ -void -link_established(int unit) -{ - int auth; - int i; - struct protent *protp; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *go = &lcp_gotoptions[unit]; -#if PAP_SUPPORT || CHAP_SUPPORT - lcp_options *ho = &lcp_hisoptions[unit]; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ - - AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit)); - /* - * Tell higher-level protocols that LCP is up. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) { - (*protp->lowerup)(unit); - } - } - if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) { - /* - * We wanted the peer to authenticate itself, and it refused: - * treat it as though it authenticated with PAP using a username - * of "" and a password of "". If that's not OK, boot it out. - */ - if (!wo->neg_upap || !null_login(unit)) { - AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n")); - lcp_close(unit, "peer refused to authenticate"); - return; - } - } - - lcp_phase[unit] = PHASE_AUTHENTICATE; - auth = 0; -#if CHAP_SUPPORT - if (go->neg_chap) { - ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype); - auth |= CHAP_PEER; - } -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT && CHAP_SUPPORT - else -#endif /* PAP_SUPPORT && CHAP_SUPPORT */ -#if PAP_SUPPORT - if (go->neg_upap) { - upap_authpeer(unit); - auth |= PAP_PEER; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (ho->neg_chap) { - ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype); - auth |= CHAP_WITHPEER; - } -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT && CHAP_SUPPORT - else -#endif /* PAP_SUPPORT && CHAP_SUPPORT */ -#if PAP_SUPPORT - if (ho->neg_upap) { - if (ppp_settings.passwd[0] == 0) { - passwd_from_file = 1; - if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) { - AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n")); - } - } - upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); - auth |= PAP_WITHPEER; - } -#endif /* PAP_SUPPORT */ - auth_pending[unit] = auth; - - if (!auth) { - network_phase(unit); - } -} - -/* - * Proceed to the network phase. - */ -static void -network_phase(int unit) -{ - int i; - struct protent *protp; - lcp_options *go = &lcp_gotoptions[unit]; - - /* - * If the peer had to authenticate, run the auth-up script now. - */ - if ((go->neg_chap || go->neg_upap) && !did_authup) { - /* XXX Do setup for peer authentication. */ - did_authup = 1; - } - -#if CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - lcp_phase[unit] = PHASE_CALLBACK; - (*cbcp_protent.open)(unit); - return; - } -#endif /* CBCP_SUPPORT */ - - lcp_phase[unit] = PHASE_NETWORK; - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) { - (*protp->open)(unit); - if (protp->protocol != PPP_CCP) { - ++num_np_open; - } - } - } - - if (num_np_open == 0) { - /* nothing to do */ - lcp_close(0, "No network protocols running"); - } -} -/* @todo: add void start_networks(void) here (pppd 2.3.11) */ - -/* - * The peer has failed to authenticate himself using `protocol'. - */ -void -auth_peer_fail(int unit, u16_t protocol) -{ - LWIP_UNUSED_ARG(protocol); - - AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol)); - /* - * Authentication failure: take the link down - */ - lcp_close(unit, "Authentication failed"); -} - - -#if PAP_SUPPORT || CHAP_SUPPORT -/* - * The peer has been successfully authenticated using `protocol'. - */ -void -auth_peer_success(int unit, u16_t protocol, char *name, int namelen) -{ - int pbit; - - AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol)); - switch (protocol) { - case PPP_CHAP: - pbit = CHAP_PEER; - break; - case PPP_PAP: - pbit = PAP_PEER; - break; - default: - AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); - return; - } - - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > (int)sizeof(peer_authname) - 1) { - namelen = sizeof(peer_authname) - 1; - } - BCOPY(name, peer_authname, namelen); - peer_authname[namelen] = 0; - - /* - * If there is no more authentication still to be done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~pbit) == 0) { - network_phase(unit); - } -} - -/* - * We have failed to authenticate ourselves to the peer using `protocol'. - */ -void -auth_withpeer_fail(int unit, u16_t protocol) -{ - int errCode = PPPERR_AUTHFAIL; - - LWIP_UNUSED_ARG(protocol); - - AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol)); - if (passwd_from_file) { - BZERO(ppp_settings.passwd, MAXSECRETLEN); - } - - /* - * We've failed to authenticate ourselves to our peer. - * He'll probably take the link down, and there's not much - * we can do except wait for that. - */ - pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); - lcp_close(unit, "Failed to authenticate ourselves to peer"); -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void -auth_withpeer_success(int unit, u16_t protocol) -{ - int pbit; - - AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol)); - switch (protocol) { - case PPP_CHAP: - pbit = CHAP_WITHPEER; - break; - case PPP_PAP: - if (passwd_from_file) { - BZERO(ppp_settings.passwd, MAXSECRETLEN); - } - pbit = PAP_WITHPEER; - break; - default: - AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); - pbit = 0; - } - - /* - * If there is no more authentication still being done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~pbit) == 0) { - network_phase(unit); - } -} -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ - - -/* - * np_up - a network protocol has come up. - */ -void -np_up(int unit, u16_t proto) -{ - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); - - AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto)); - if (num_np_up == 0) { - AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit)); - /* - * At this point we consider that the link has come up successfully. - */ - if (ppp_settings.idle_time_limit > 0) { - TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit); - } - - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (ppp_settings.maxconnect > 0) { - TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); - } - } - ++num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void -np_down(int unit, u16_t proto) -{ - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); - - AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto)); - if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) { - UNTIMEOUT(check_idle, NULL); - } -} - -/* - * np_finished - a network protocol has finished using the link. - */ -void -np_finished(int unit, u16_t proto) -{ - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); - - AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto)); - if (--num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(0, "No network protocols running"); - } -} - -/* - * check_idle - check whether the link has been idle for long - * enough that we can shut it down. - */ -static void -check_idle(void *arg) -{ - struct ppp_idle idle; - u_short itime; - - LWIP_UNUSED_ARG(arg); - if (!get_idle_time(0, &idle)) { - return; - } - itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - if (itime >= ppp_settings.idle_time_limit) { - /* link is idle: shut it down. */ - AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n")); - lcp_close(0, "Link inactive"); - } else { - TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime); - } -} - -/* - * connect_time_expired - log a message and close the connection. - */ -static void -connect_time_expired(void *arg) -{ - LWIP_UNUSED_ARG(arg); - - AUTHDEBUG(LOG_INFO, ("Connect time expired\n")); - lcp_close(0, "Connect time expired"); /* Close connection */ -} - -#if 0 /* UNUSED */ -/* - * auth_check_options - called to check authentication options. - */ -void -auth_check_options(void) -{ - lcp_options *wo = &lcp_wantoptions[0]; - int can_auth; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u32_t remote; - - /* Default our_name to hostname, and user to our_name */ - if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) { - strcpy(ppp_settings.our_name, ppp_settings.hostname); - } - - if (ppp_settings.user[0] == 0) { - strcpy(ppp_settings.user, ppp_settings.our_name); - } - - /* If authentication is required, ask peer for CHAP or PAP. */ - if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) { - wo->neg_chap = 1; - wo->neg_upap = 1; - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. - */ - can_auth = wo->neg_upap && have_pap_secret(); - if (!can_auth && wo->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote); - } - - if (ppp_settings.auth_required && !can_auth) { - ppp_panic("No auth secret"); - } -} -#endif /* UNUSED */ - -/* - * auth_reset - called when LCP is starting negotiations to recheck - * authentication options, i.e. whether we have appropriate secrets - * to use for authenticating ourselves and/or the peer. - */ -void -auth_reset(int unit) -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[0]; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u32_t remote; - - AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit)); - ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL)); - ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/; - - if (go->neg_upap && !have_pap_secret()) { - go->neg_upap = 0; - } - if (go->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) { - go->neg_chap = 0; - } - } -} - -#if PAP_SUPPORT -/* - * check_passwd - Check the user name and passwd against the PAP secrets - * file. If requested, also check against the system password database, - * and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Authentication failed. - * UPAP_AUTHACK: Authentication succeeded. - * In either case, msg points to an appropriate message. - */ -u_char -check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen) -{ -#if 1 /* XXX Assume all entries OK. */ - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(auser); - LWIP_UNUSED_ARG(userlen); - LWIP_UNUSED_ARG(apasswd); - LWIP_UNUSED_ARG(passwdlen); - LWIP_UNUSED_ARG(msglen); - *msg = (char *) 0; - return UPAP_AUTHACK; /* XXX Assume all entries OK. */ -#else - u_char ret = 0; - struct wordlist *addrs = NULL; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static u_short attempts = 0; - - /* - * Make copies of apasswd and auser, then null-terminate them. - */ - BCOPY(apasswd, passwd, passwdlen); - passwd[passwdlen] = '\0'; - BCOPY(auser, user, userlen); - user[userlen] = '\0'; - *msg = (char *) 0; - - /* XXX Validate user name and password. */ - ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */ - - if (ret == UPAP_AUTHNAK) { - if (*msg == (char *) 0) { - *msg = "Login incorrect"; - } - *msglen = strlen(*msg); - /* - * Frustrate passwd stealer programs. - * Allow 10 tries, but start backing off after 3 (stolen from login). - * On 10'th, drop the connection. - */ - if (attempts++ >= 10) { - AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user)); - /*ppp_panic("Excess Bad Logins");*/ - } - if (attempts > 3) { - /* @todo: this was sleep(), i.e. seconds, not milliseconds - * I don't think we really need this in lwIP - we would block tcpip_thread! - */ - /*sys_msleep((attempts - 3) * 5);*/ - } - if (addrs != NULL) { - free_wordlist(addrs); - } - } else { - attempts = 0; /* Reset count */ - if (*msg == (char *) 0) { - *msg = "Login ok"; - } - *msglen = strlen(*msg); - set_allowed_addrs(unit, addrs); - } - - BZERO(passwd, sizeof(passwd)); - BZERO(secret, sizeof(secret)); - - return ret; -#endif -} -#endif /* PAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * This function is needed for PAM. - */ - -#ifdef USE_PAM - -/* lwip does not support PAM*/ - -#endif /* USE_PAM */ - -#endif /* UNUSED */ - - -#if 0 /* UNUSED */ -/* - * plogin - Check the user name and password against the system - * password database, and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Login failed. - * UPAP_AUTHACK: Login succeeded. - * In either case, msg points to an appropriate message. - */ -static int -plogin(char *user, char *passwd, char **msg, int *msglen) -{ - - LWIP_UNUSED_ARG(user); - LWIP_UNUSED_ARG(passwd); - LWIP_UNUSED_ARG(msg); - LWIP_UNUSED_ARG(msglen); - - - /* The new lines are here align the file when - * compared against the pppd 2.3.11 code */ - - - - - - - - - - - - - - - - - /* XXX Fail until we decide that we want to support logins. */ - return (UPAP_AUTHNAK); -} -#endif - - - -/* - * plogout - Logout the user. - */ -static void -plogout(void) -{ - logged_in = 0; -} - -/* - * null_login - Check if a username of "" and a password of "" are - * acceptable, and iff so, set the list of acceptable IP addresses - * and return 1. - */ -static int -null_login(int unit) -{ - LWIP_UNUSED_ARG(unit); - /* XXX Fail until we decide that we want to support logins. */ - return 0; -} - - -/* - * get_pap_passwd - get a password for authenticating ourselves with - * our peer using PAP. Returns 1 on success, 0 if no suitable password - * could be found. - */ -static int -get_pap_passwd(int unit, char *user, char *passwd) -{ - LWIP_UNUSED_ARG(unit); -/* normally we would reject PAP if no password is provided, - but this causes problems with some providers (like CHT in Taiwan) - who incorrectly request PAP and expect a bogus/empty password, so - always provide a default user/passwd of "none"/"none" - - @todo: This should be configured by the user, instead of being hardcoded here! -*/ - if(user) { - strcpy(user, "none"); - } - if(passwd) { - strcpy(passwd, "none"); - } - return 1; -} - -/* - * have_pap_secret - check whether we have a PAP file with any - * secrets that we could possibly use for authenticating the peer. - */ -static int -have_pap_secret(void) -{ - /* XXX Fail until we set up our passwords. */ - return 0; -} - -/* - * have_chap_secret - check whether we have a CHAP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_chap_secret(char *client, char *server, u32_t remote) -{ - LWIP_UNUSED_ARG(client); - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(remote); - - /* XXX Fail until we set up our passwords. */ - return 0; -} -#if CHAP_SUPPORT - -/* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int -get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs) -{ -#if 1 - int len; - struct wordlist *addrs; - - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(save_addrs); - - addrs = NULL; - - if(!client || !client[0] || strcmp(client, ppp_settings.user)) { - return 0; - } - - len = (int)strlen(ppp_settings.passwd); - if (len > MAXSECRETLEN) { - AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); - len = MAXSECRETLEN; - } - - BCOPY(ppp_settings.passwd, secret, len); - *secret_len = len; - - return 1; -#else - int ret = 0, len; - struct wordlist *addrs; - char secbuf[MAXWORDLEN]; - - addrs = NULL; - secbuf[0] = 0; - - /* XXX Find secret. */ - if (ret < 0) { - return 0; - } - - if (save_addrs) { - set_allowed_addrs(unit, addrs); - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); - len = MAXSECRETLEN; - } - - BCOPY(secbuf, secret, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -#endif -} -#endif /* CHAP_SUPPORT */ - - -#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ -/* - * set_allowed_addrs() - set the list of allowed addresses. - */ -static void -set_allowed_addrs(int unit, struct wordlist *addrs) -{ - if (addresses[unit] != NULL) { - free_wordlist(addresses[unit]); - } - addresses[unit] = addrs; - -#if 0 - /* - * If there's only one authorized address we might as well - * ask our peer for that one right away - */ - if (addrs != NULL && addrs->next == NULL) { - char *p = addrs->word; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u32_t a; - struct hostent *hp; - - if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) { - hp = gethostbyname(p); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u32_t *)hp->h_addr; - } else { - a = inet_addr(p); - } - if (a != (u32_t) -1) { - wo->hisaddr = a; - } - } - } -#endif -} -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ - -/* - * auth_ip_addr - check whether the peer is authorized to use - * a given IP address. Returns 1 if authorized, 0 otherwise. - */ -int -auth_ip_addr(int unit, u32_t addr) -{ - return ip_addr_check(addr, addresses[unit]); -} - -static int /* @todo: integrate this funtion into auth_ip_addr()*/ -ip_addr_check(u32_t addr, struct wordlist *addrs) -{ - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) { - return 0; - } - - if (addrs == NULL) { - return !ppp_settings.auth_required; /* no addresses authorized */ - } - - /* XXX All other addresses allowed. */ - return 1; -} - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs(u32_t addr) -{ - addr = ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -#if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */ -/* - * some_ip_ok - check a wordlist to see if it authorizes any - * IP address(es). - */ -static int -some_ip_ok(struct wordlist *addrs) -{ - for (; addrs != 0; addrs = addrs->next) { - if (addrs->word[0] == '-') - break; - if (addrs->word[0] != '!') - return 1; /* some IP address is allowed */ - } - return 0; -} - -/* - * check_access - complain if a secret file has too-liberal permissions. - */ -static void -check_access(FILE *f, char *filename) -{ - struct stat sbuf; - - if (fstat(fileno(f), &sbuf) < 0) { - warn("cannot stat secret file %s: %m", filename); - } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - warn("Warning - secret file %s has world and/or group access", - filename); - } -} - - -/* - * scan_authfile - Scan an authorization file for a secret suitable - * for authenticating `client' on `server'. The return value is -1 - * if no secret is found, otherwise >= 0. The return value has - * NONWILD_CLIENT set if the secret didn't have "*" for the client, and - * NONWILD_SERVER set if the secret didn't have "*" for the server. - * Any following words on the line up to a "--" (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. Any - * following words (extra options) are placed in a wordlist and - * returned in *opts. - * We assume secret is NULL or points to MAXWORDLEN bytes of space. - */ -static int -scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename) -{ - /* We do not (currently) need this in lwip */ - return 0; /* dummy */ -} -/* - * free_wordlist - release memory allocated for a wordlist. - */ -static void -free_wordlist(struct wordlist *wp) -{ - struct wordlist *next; - - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } -} - -/* - * auth_script_done - called when the auth-up or auth-down script - * has finished. - */ -static void -auth_script_done(void *arg) -{ - auth_script_pid = 0; - switch (auth_script_state) { - case s_up: - if (auth_state == s_down) { - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - break; - case s_down: - if (auth_state == s_up) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } - break; - } -} - -/* - * auth_script - execute a script with arguments - * interface-name peer-name real-user tty speed - */ -static void -auth_script(char *script) -{ - char strspeed[32]; - struct passwd *pw; - char struid[32]; - char *user_name; - char *argv[8]; - - if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) - user_name = pw->pw_name; - else { - slprintf(struid, sizeof(struid), "%d", getuid()); - user_name = struid; - } - slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); - - argv[0] = script; - argv[1] = ifname; - argv[2] = peer_authname; - argv[3] = user_name; - argv[4] = devnam; - argv[5] = strspeed; - argv[6] = NULL; - - auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL); -} -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/auth.h b/external/badvpn_dns/lwip/src/netif/ppp/auth.h deleted file mode 100644 index a8069ec..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/auth.h +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** -* auth.h - PPP Authentication and phase control header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original derived from BSD pppd.h. -*****************************************************************************/ -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef AUTH_H -#define AUTH_H - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* we are starting to use the link */ -void link_required (int); - -/* we are finished with the link */ -void link_terminated (int); - -/* the LCP layer has left the Opened state */ -void link_down (int); - -/* the link is up; authenticate now */ -void link_established (int); - -/* a network protocol has come up */ -void np_up (int, u16_t); - -/* a network protocol has gone down */ -void np_down (int, u16_t); - -/* a network protocol no longer needs link */ -void np_finished (int, u16_t); - -/* peer failed to authenticate itself */ -void auth_peer_fail (int, u16_t); - -/* peer successfully authenticated itself */ -void auth_peer_success (int, u16_t, char *, int); - -/* we failed to authenticate ourselves */ -void auth_withpeer_fail (int, u16_t); - -/* we successfully authenticated ourselves */ -void auth_withpeer_success (int, u16_t); - -/* check authentication options supplied */ -void auth_check_options (void); - -/* check what secrets we have */ -void auth_reset (int); - -/* Check peer-supplied username/password */ -u_char check_passwd (int, char *, int, char *, int, char **, int *); - -/* get "secret" for chap */ -int get_secret (int, char *, char *, char *, int *, int); - -/* check if IP address is authorized */ -int auth_ip_addr (int, u32_t); - -/* check if IP address is unreasonable */ -int bad_ip_adrs (u32_t); - -#endif /* AUTH_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/chap.c b/external/badvpn_dns/lwip/src/netif/ppp/chap.c deleted file mode 100644 index f10e27d..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/chap.c +++ /dev/null @@ -1,908 +0,0 @@ -/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/ -/***************************************************************************** -* chap.c - Network Challenge Handshake Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original based on BSD chap.c. -*****************************************************************************/ -/* - * chap.c - Challenge Handshake Authentication Protocol. - * - * Copyright (c) 1993 The Australian National University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the Australian National University. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Copyright (c) 1991 Gregory M. Christy. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Gregory M. Christy. The name of the author may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "magic.h" -#include "randm.h" -#include "auth.h" -#include "md5.h" -#include "chap.h" -#include "chpms.h" - -#include <string.h> - -#if 0 /* UNUSED */ -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap[0].timeouttime, - "Set timeout for CHAP" }, - { "chap-max-challenge", o_int, &chap[0].max_transmits, - "Set max #xmits for challenge" }, - { "chap-interval", o_int, &chap[0].chal_interval, - "Set interval for rechallenge" }, -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif - { NULL } -}; -#endif /* UNUSED */ - -/* - * Protocol entry points. - */ -static void ChapInit (int); -static void ChapLowerUp (int); -static void ChapLowerDown (int); -static void ChapInput (int, u_char *, int); -static void ChapProtocolReject (int); -#if PPP_ADDITIONAL_CALLBACKS -static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *); -#endif - -struct protent chap_protent = { - PPP_CHAP, - ChapInit, - ChapInput, - ChapProtocolReject, - ChapLowerUp, - ChapLowerDown, - NULL, - NULL, -#if PPP_ADDITIONAL_CALLBACKS - ChapPrintPkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "CHAP", -#if PPP_ADDITIONAL_CALLBACKS - NULL, - NULL, - NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ - -static void ChapChallengeTimeout (void *); -static void ChapResponseTimeout (void *); -static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int); -static void ChapRechallenge (void *); -static void ChapReceiveResponse (chap_state *, u_char *, int, int); -static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len); -static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len); -static void ChapSendStatus (chap_state *, int); -static void ChapSendChallenge (chap_state *); -static void ChapSendResponse (chap_state *); -static void ChapGenChallenge (chap_state *); - -/* - * ChapInit - Initialize a CHAP unit. - */ -static void -ChapInit(int unit) -{ - chap_state *cstate = &chap[unit]; - - BZERO(cstate, sizeof(*cstate)); - cstate->unit = unit; - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; - cstate->timeouttime = CHAP_DEFTIMEOUT; - cstate->max_transmits = CHAP_DEFTRANSMITS; - /* random number generator is initialized in magic_init */ -} - - -/* - * ChapAuthWithPeer - Authenticate us with our peer (start client). - * - */ -void -ChapAuthWithPeer(int unit, char *our_name, u_char digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->resp_name = our_name; - cstate->resp_type = digest; - - if (cstate->clientstate == CHAPCS_INITIAL || - cstate->clientstate == CHAPCS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->clientstate = CHAPCS_PENDING; - return; - } - - /* - * We get here as a result of LCP coming up. - * So even if CHAP was open before, we will - * have to re-authenticate ourselves. - */ - cstate->clientstate = CHAPCS_LISTEN; -} - - -/* - * ChapAuthPeer - Authenticate our peer (start server). - */ -void -ChapAuthPeer(int unit, char *our_name, u_char digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->chal_name = our_name; - cstate->chal_type = digest; - - if (cstate->serverstate == CHAPSS_INITIAL || - cstate->serverstate == CHAPSS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->serverstate = CHAPSS_PENDING; - return; - } - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); /* crank it up dude! */ - cstate->serverstate = CHAPSS_INITIAL_CHAL; -} - - -/* - * ChapChallengeTimeout - Timeout expired on sending challenge. - */ -static void -ChapChallengeTimeout(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending challenges, don't worry. then again we */ - /* probably shouldn't be here either */ - if (cstate->serverstate != CHAPSS_INITIAL_CHAL && - cstate->serverstate != CHAPSS_RECHALLENGE) { - return; - } - - if (cstate->chal_transmits >= cstate->max_transmits) { - /* give up on peer */ - CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n")); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - return; - } - - ChapSendChallenge(cstate); /* Re-send challenge */ -} - - -/* - * ChapResponseTimeout - Timeout expired on sending response. - */ -static void -ChapResponseTimeout(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->clientstate != CHAPCS_RESPONSE) { - return; - } - - ChapSendResponse(cstate); /* re-send response */ -} - - -/* - * ChapRechallenge - Time to challenge the peer again. - */ -static void -ChapRechallenge(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->serverstate != CHAPSS_OPEN) { - return; - } - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_RECHALLENGE; -} - - -/* - * ChapLowerUp - The lower layer is up. - * - * Start up if we have pending requests. - */ -static void -ChapLowerUp(int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->clientstate == CHAPCS_INITIAL) { - cstate->clientstate = CHAPCS_CLOSED; - } else if (cstate->clientstate == CHAPCS_PENDING) { - cstate->clientstate = CHAPCS_LISTEN; - } - - if (cstate->serverstate == CHAPSS_INITIAL) { - cstate->serverstate = CHAPSS_CLOSED; - } else if (cstate->serverstate == CHAPSS_PENDING) { - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_INITIAL_CHAL; - } -} - - -/* - * ChapLowerDown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -ChapLowerDown(int unit) -{ - chap_state *cstate = &chap[unit]; - - /* Timeout(s) pending? Cancel if so. */ - if (cstate->serverstate == CHAPSS_INITIAL_CHAL || - cstate->serverstate == CHAPSS_RECHALLENGE) { - UNTIMEOUT(ChapChallengeTimeout, cstate); - } else if (cstate->serverstate == CHAPSS_OPEN - && cstate->chal_interval != 0) { - UNTIMEOUT(ChapRechallenge, cstate); - } - if (cstate->clientstate == CHAPCS_RESPONSE) { - UNTIMEOUT(ChapResponseTimeout, cstate); - } - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; -} - - -/* - * ChapProtocolReject - Peer doesn't grok CHAP. - */ -static void -ChapProtocolReject(int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->serverstate != CHAPSS_INITIAL && - cstate->serverstate != CHAPSS_CLOSED) { - auth_peer_fail(unit, PPP_CHAP); - } - if (cstate->clientstate != CHAPCS_INITIAL && - cstate->clientstate != CHAPCS_CLOSED) { - auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ - } - ChapLowerDown(unit); /* shutdown chap */ -} - - -/* - * ChapInput - Input CHAP packet. - */ -static void -ChapInput(int unit, u_char *inpacket, int packet_len) -{ - chap_state *cstate = &chap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (packet_len < CHAP_HEADERLEN) { - CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < CHAP_HEADERLEN) { - CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n")); - return; - } - if (len > packet_len) { - CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n")); - return; - } - len -= CHAP_HEADERLEN; - - /* - * Action depends on code (as in fact it usually does :-). - */ - switch (code) { - case CHAP_CHALLENGE: - ChapReceiveChallenge(cstate, inp, id, len); - break; - - case CHAP_RESPONSE: - ChapReceiveResponse(cstate, inp, id, len); - break; - - case CHAP_FAILURE: - ChapReceiveFailure(cstate, inp, id, len); - break; - - case CHAP_SUCCESS: - ChapReceiveSuccess(cstate, inp, id, len); - break; - - default: /* Need code reject? */ - CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code)); - break; - } -} - - -/* - * ChapReceiveChallenge - Receive Challenge and send Response. - */ -static void -ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len) -{ - int rchallenge_len; - u_char *rchallenge; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id)); - if (cstate->clientstate == CHAPCS_CLOSED || - cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n", - cstate->clientstate)); - return; - } - - if (len < 2) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); - return; - } - - GETCHAR(rchallenge_len, inp); - len -= sizeof (u_char) + rchallenge_len; /* now name field length */ - if (len < 0) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); - return; - } - rchallenge = inp; - INCPTR(rchallenge_len, inp); - - if (len >= (int)sizeof(rhostname)) { - len = sizeof(rhostname) - 1; - } - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n", - rhostname)); - - /* Microsoft doesn't send their name back in the PPP packet */ - if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) { - strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname)); - rhostname[sizeof(rhostname) - 1] = 0; - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n", - rhostname)); - } - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(cstate->unit, cstate->resp_name, rhostname, - secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n", - rhostname)); - } - - /* cancel response send timeout if necessary */ - if (cstate->clientstate == CHAPCS_RESPONSE) { - UNTIMEOUT(ChapResponseTimeout, cstate); - } - - cstate->resp_id = id; - cstate->resp_transmits = 0; - - /* generate MD based on negotiated type */ - switch (cstate->resp_type) { - - case CHAP_DIGEST_MD5: - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->resp_id, 1); - MD5Update(&mdContext, (u_char*)secret, secret_len); - MD5Update(&mdContext, rchallenge, rchallenge_len); - MD5Final(hash, &mdContext); - BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); - cstate->resp_length = MD5_SIGNATURE_SIZE; - break; - -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); - break; -#endif - - default: - CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type)); - return; - } - - BZERO(secret, sizeof(secret)); - ChapSendResponse(cstate); -} - - -/* - * ChapReceiveResponse - Receive and process response. - */ -static void -ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len) -{ - u_char *remmd, remmd_len; - int secret_len, old_state; - int code; - char rhostname[256]; - MD5_CTX mdContext; - char secret[MAXSECRETLEN]; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id)); - - if (cstate->serverstate == CHAPSS_CLOSED || - cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n", - cstate->serverstate)); - return; - } - - if (id != cstate->chal_id) { - return; /* doesn't match ID of last challenge */ - } - - /* - * If we have received a duplicate or bogus Response, - * we have to send the same answer (Success/Failure) - * as we did for the first Response we saw. - */ - if (cstate->serverstate == CHAPSS_OPEN) { - ChapSendStatus(cstate, CHAP_SUCCESS); - return; - } - if (cstate->serverstate == CHAPSS_BADAUTH) { - ChapSendStatus(cstate, CHAP_FAILURE); - return; - } - - if (len < 2) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); - return; - } - GETCHAR(remmd_len, inp); /* get length of MD */ - remmd = inp; /* get pointer to MD */ - INCPTR(remmd_len, inp); - - len -= sizeof (u_char) + remmd_len; - if (len < 0) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); - return; - } - - UNTIMEOUT(ChapChallengeTimeout, cstate); - - if (len >= (int)sizeof(rhostname)) { - len = sizeof(rhostname) - 1; - } - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n", - rhostname)); - - /* - * Get secret for authenticating them with us, - * do the hash ourselves, and compare the result. - */ - code = CHAP_FAILURE; - if (!get_secret(cstate->unit, rhostname, cstate->chal_name, - secret, &secret_len, 1)) { - CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n", - rhostname)); - } else { - /* generate MD based on negotiated type */ - switch (cstate->chal_type) { - - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ - if (remmd_len != MD5_SIGNATURE_SIZE) { - break; /* it's not even the right length */ - } - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->chal_id, 1); - MD5Update(&mdContext, (u_char*)secret, secret_len); - MD5Update(&mdContext, cstate->challenge, cstate->chal_len); - MD5Final(hash, &mdContext); - - /* compare local and remote MDs and send the appropriate status */ - if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) { - code = CHAP_SUCCESS; /* they are the same! */ - } - break; - - default: - CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type)); - } - } - - BZERO(secret, sizeof(secret)); - ChapSendStatus(cstate, code); - - if (code == CHAP_SUCCESS) { - old_state = cstate->serverstate; - cstate->serverstate = CHAPSS_OPEN; - if (old_state == CHAPSS_INITIAL_CHAL) { - auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); - } - if (cstate->chal_interval != 0) { - TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); - } - } else { - CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n")); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - } -} - -/* - * ChapReceiveSuccess - Receive Success - */ -static void -ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len) -{ - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(inp); - - CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id)); - - if (cstate->clientstate == CHAPCS_OPEN) { - /* presumably an answer to a duplicate response */ - return; - } - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n", - cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) { - PRINTMSG(inp, len); - } - - cstate->clientstate = CHAPCS_OPEN; - - auth_withpeer_success(cstate->unit, PPP_CHAP); -} - - -/* - * ChapReceiveFailure - Receive failure. - */ -static void -ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len) -{ - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(inp); - - CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id)); - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n", - cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) { - PRINTMSG(inp, len); - } - - CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n")); - auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ -} - - -/* - * ChapSendChallenge - Send an Authenticate challenge. - */ -static void -ChapSendChallenge(chap_state *cstate) -{ - u_char *outp; - int chal_len, name_len; - int outlen; - - chal_len = cstate->chal_len; - name_len = (int)strlen(cstate->chal_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; - outp = outpacket_buf[cstate->unit]; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ - - PUTCHAR(CHAP_CHALLENGE, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - - PUTCHAR(chal_len, outp); /* put length of challenge */ - BCOPY(cstate->challenge, outp, chal_len); - INCPTR(chal_len, outp); - - BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ - - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id)); - - TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); - ++cstate->chal_transmits; -} - - -/* - * ChapSendStatus - Send a status response (ack or nak). - */ -static void -ChapSendStatus(chap_state *cstate, int code) -{ - u_char *outp; - int outlen, msglen; - char msg[256]; /* @todo: this can be a char*, no strcpy needed */ - - if (code == CHAP_SUCCESS) { - strcpy(msg, "Welcome!"); - } else { - strcpy(msg, "I don't like you. Go 'way."); - } - msglen = (int)strlen(msg); - - outlen = CHAP_HEADERLEN + msglen; - outp = outpacket_buf[cstate->unit]; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - - PUTCHAR(code, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - BCOPY(msg, outp, msglen); - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code, - cstate->chal_id)); -} - -/* - * ChapGenChallenge is used to generate a pseudo-random challenge string of - * a pseudo-random length between min_len and max_len. The challenge - * string and its length are stored in *cstate, and various other fields of - * *cstate are initialized. - */ - -static void -ChapGenChallenge(chap_state *cstate) -{ - int chal_len; - u_char *ptr = cstate->challenge; - int i; - - /* pick a random challenge length between MIN_CHALLENGE_LENGTH and - MAX_CHALLENGE_LENGTH */ - chal_len = (unsigned) - ((((magic() >> 16) * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16) - + MIN_CHALLENGE_LENGTH); - LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff); - cstate->chal_len = (u_char)chal_len; - cstate->chal_id = ++cstate->id; - cstate->chal_transmits = 0; - - /* generate a random string */ - for (i = 0; i < chal_len; i++ ) { - *ptr++ = (char) (magic() & 0xff); - } -} - -/* - * ChapSendResponse - send a response packet with values as specified - * in *cstate. - */ -/* ARGSUSED */ -static void -ChapSendResponse(chap_state *cstate) -{ - u_char *outp; - int outlen, md_len, name_len; - - md_len = cstate->resp_length; - name_len = (int)strlen(cstate->resp_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; - outp = outpacket_buf[cstate->unit]; - - MAKEHEADER(outp, PPP_CHAP); - - PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ - PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ - PUTSHORT(outlen, outp); /* packet length */ - - PUTCHAR(md_len, outp); /* length of MD */ - BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ - INCPTR(md_len, outp); - - BCOPY(cstate->resp_name, outp, name_len); /* append our name */ - - /* send the packet */ - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); - ++cstate->resp_transmits; -} - -#if PPP_ADDITIONAL_CALLBACKS -static char *ChapCodenames[] = { - "Challenge", "Response", "Success", "Failure" -}; -/* - * ChapPrintPkt - print the contents of a CHAP packet. - */ -static int -ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) -{ - int code, id, len; - int clen, nlen; - u_char x; - - if (plen < CHAP_HEADERLEN) { - return 0; - } - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HEADERLEN || len > plen) { - return 0; - } - - if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) { - printer(arg, " %s", ChapCodenames[code-1]); - } else { - printer(arg, " code=0x%x", code); - } - printer(arg, " id=0x%x", id); - len -= CHAP_HEADERLEN; - switch (code) { - case CHAP_CHALLENGE: - case CHAP_RESPONSE: - if (len < 1) { - break; - } - clen = p[0]; - if (len < clen + 1) { - break; - } - ++p; - nlen = len - clen - 1; - printer(arg, " <"); - for (; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, "%.2x", x); - } - printer(arg, ">, name = %.*Z", nlen, p); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " %.*Z", len, p); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - } - - return len + CHAP_HEADERLEN; -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* CHAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/chap.h b/external/badvpn_dns/lwip/src/netif/ppp/chap.h deleted file mode 100644 index fedcab8..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/chap.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************** -* chap.h - Network Challenge Handshake Authentication Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-03 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original built from BSD network code. -******************************************************************************/ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1993 The Australian National University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the Australian National University. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Copyright (c) 1991 Gregory M. Christy - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the author. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: chap.h,v 1.6 2010/01/24 13:19:34 goldsimon Exp $ - */ - -#ifndef CHAP_H -#define CHAP_H - -/* Code + ID + length */ -#define CHAP_HEADERLEN 4 - -/* - * CHAP codes. - */ - -#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ -#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ -#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ - -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * Challenge lengths (for challenges we send) and other limits. - */ -#define MIN_CHALLENGE_LENGTH 32 -#define MAX_CHALLENGE_LENGTH 64 -#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ - -/* - * Each interface is described by a chap structure. - */ - -typedef struct chap_state { - int unit; /* Interface unit number */ - int clientstate; /* Client state */ - int serverstate; /* Server state */ - u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ - u_char chal_len; /* challenge length */ - u_char chal_id; /* ID of last challenge */ - u_char chal_type; /* hash algorithm for challenges */ - u_char id; /* Current id */ - char *chal_name; /* Our name to use with challenge */ - int chal_interval; /* Time until we challenge peer again */ - int timeouttime; /* Timeout time in seconds */ - int max_transmits; /* Maximum # of challenge transmissions */ - int chal_transmits; /* Number of transmissions of challenge */ - int resp_transmits; /* Number of transmissions of response */ - u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ - u_char resp_length; /* length of response */ - u_char resp_id; /* ID for response messages */ - u_char resp_type; /* hash algorithm for responses */ - char *resp_name; /* Our name to send with response */ -} chap_state; - - -/* - * Client (peer) states. - */ -#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ -#define CHAPCS_LISTEN 3 /* Listening for a challenge */ -#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ -#define CHAPCS_OPEN 5 /* We've received Success */ - -/* - * Server (authenticator) states. - */ -#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPSS_PENDING 2 /* Auth peer when lower up */ -#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ -#define CHAPSS_OPEN 4 /* We've sent a Success msg */ -#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ -#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ - -extern chap_state chap[]; - -void ChapAuthWithPeer (int, char *, u_char); -void ChapAuthPeer (int, char *, u_char); - -extern struct protent chap_protent; - -#endif /* CHAP_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/chpms.c b/external/badvpn_dns/lwip/src/netif/ppp/chpms.c deleted file mode 100644 index 81a887b..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/chpms.c +++ /dev/null @@ -1,396 +0,0 @@ -/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/ -/*** The original PPPD code is written in a way to require either the UNIX DES - encryption functions encrypt(3) and setkey(3) or the DES library libdes. - Since both is not included in lwIP, MSCHAP currently does not work! */ -/***************************************************************************** -* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-08 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original based on BSD chap_ms.c. -*****************************************************************************/ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Eric Rosenquist. The name of the author may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 - * - * Implemented LANManager type password response to MS-CHAP challenges. - * Now pppd provides both NT style and LANMan style blocks, and the - * prefered is set by option "ms-lanman". Default is to use NT. - * The hash text (StdText) was taken from Win95 RASAPI32.DLL. - * - * You should also use DOMAIN\USERNAME as described in README.MSCHAP80 - */ - -#define USE_CRYPT - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "md4.h" -#ifndef USE_CRYPT -#include "des.h" -#endif -#include "chap.h" -#include "chpms.h" - -#include <string.h> - - -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ - - -/************************/ -/*** LOCAL DATA TYPES ***/ -/************************/ -typedef struct { - u_char LANManResp[24]; - u_char NTResp[24]; - u_char UseNT; /* If 1, ignore the LANMan response field */ -} MS_ChapResponse; -/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), - in case this struct gets padded. */ - - - -/***********************************/ -/*** LOCAL FUNCTION DECLARATIONS ***/ -/***********************************/ - -/* XXX Don't know what to do with these. */ -extern void setkey(const char *); -extern void encrypt(char *, int); - -static void DesEncrypt (u_char *, u_char *, u_char *); -static void MakeKey (u_char *, u_char *); - -#ifdef USE_CRYPT -static void Expand (u_char *, u_char *); -static void Collapse (u_char *, u_char *); -#endif - -static void ChallengeResponse( - u_char *challenge, /* IN 8 octets */ - u_char *pwHash, /* IN 16 octets */ - u_char *response /* OUT 24 octets */ -); -static void ChapMS_NT( - char *rchallenge, - int rchallenge_len, - char *secret, - int secret_len, - MS_ChapResponse *response -); -static u_char Get7Bits( - u_char *input, - int startBit -); - -static void -ChallengeResponse( u_char *challenge, /* IN 8 octets */ - u_char *pwHash, /* IN 16 octets */ - u_char *response /* OUT 24 octets */) -{ - u_char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(pwHash, ZPasswordHash, 16); - -#if 0 - log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG); -#endif - - DesEncrypt(challenge, ZPasswordHash + 0, response + 0); - DesEncrypt(challenge, ZPasswordHash + 7, response + 8); - DesEncrypt(challenge, ZPasswordHash + 14, response + 16); - -#if 0 - log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG); -#endif -} - - -#ifdef USE_CRYPT -static void -DesEncrypt( u_char *clear, /* IN 8 octets */ - u_char *key, /* IN 7 octets */ - u_char *cipher /* OUT 8 octets */) -{ - u_char des_key[8]; - u_char crypt_key[66]; - u_char des_input[66]; - - MakeKey(key, des_key); - - Expand(des_key, crypt_key); - setkey((char*)crypt_key); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - Expand(clear, des_input); - encrypt((char*)des_input, 0); - Collapse(des_input, cipher); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#else /* USE_CRYPT */ - -static void -DesEncrypt( u_char *clear, /* IN 8 octets */ - u_char *key, /* IN 7 octets */ - u_char *cipher /* OUT 8 octets */) -{ - des_cblock des_key; - des_key_schedule key_schedule; - - MakeKey(key, des_key); - - des_set_key(&des_key, key_schedule); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#endif /* USE_CRYPT */ - - -static u_char -Get7Bits( u_char *input, int startBit) -{ - register unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -#ifdef USE_CRYPT - -/* in == 8-byte string (expanded version of the 56-bit key) - * out == 64-byte string where each byte is either 1 or 0 - * Note that the low-order "bit" is always ignored by by setkey() - */ -static void -Expand(u_char *in, u_char *out) -{ - int j, c; - int i; - - for(i = 0; i < 64; in++){ - c = *in; - for(j = 7; j >= 0; j--) { - *out++ = (c >> j) & 01; - } - i += 8; - } -} - -/* The inverse of Expand - */ -static void -Collapse(u_char *in, u_char *out) -{ - int j; - int i; - unsigned int c; - - for (i = 0; i < 64; i += 8, out++) { - c = 0; - for (j = 7; j >= 0; j--, in++) { - c |= *in << j; - } - *out = c & 0xff; - } -} -#endif - -static void -MakeKey( u_char *key, /* IN 56 bit DES key missing parity bits */ - u_char *des_key /* OUT 64 bit DES key with parity bits added */) -{ - des_key[0] = Get7Bits(key, 0); - des_key[1] = Get7Bits(key, 7); - des_key[2] = Get7Bits(key, 14); - des_key[3] = Get7Bits(key, 21); - des_key[4] = Get7Bits(key, 28); - des_key[5] = Get7Bits(key, 35); - des_key[6] = Get7Bits(key, 42); - des_key[7] = Get7Bits(key, 49); - -#ifndef USE_CRYPT - des_set_odd_parity((des_cblock *)des_key); -#endif - -#if 0 - CHAPDEBUG(LOG_INFO, ("MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n", - key[0], key[1], key[2], key[3], key[4], key[5], key[6])); - CHAPDEBUG(LOG_INFO, ("MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7])); -#endif -} - -static void -ChapMS_NT( char *rchallenge, - int rchallenge_len, - char *secret, - int secret_len, - MS_ChapResponse *response) -{ - int i; - MDstruct md4Context; - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - static int low_byte_first = -1; - - LWIP_UNUSED_ARG(rchallenge_len); - - /* Initialize the Unicode version of the secret (== password). */ - /* This implicitly supports 8-bit ISO8859/1 characters. */ - BZERO(unicodePassword, sizeof(unicodePassword)); - for (i = 0; i < secret_len; i++) { - unicodePassword[i * 2] = (u_char)secret[i]; - } - MDbegin(&md4Context); - MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */ - - if (low_byte_first == -1) { - low_byte_first = (PP_HTONS((unsigned short int)1) != 1); - } - if (low_byte_first == 0) { - /* @todo: arg type - u_long* or u_int* ? */ - MDreverse((unsigned int*)&md4Context); /* sfb 961105 */ - } - - MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */ - - ChallengeResponse((u_char*)rchallenge, (u_char*)md4Context.buffer, response->NTResp); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan( char *rchallenge, - int rchallenge_len, - char *secret, - int secret_len, - MS_ChapResponse *response) -{ - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[16]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) { - UcasePassword[i] = (u_char)toupper(secret[i]); - } - DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); - DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); -} -#endif - -void -ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len) -{ - MS_ChapResponse response; -#ifdef MSLANMAN - extern int ms_lanman; -#endif - -#if 0 - CHAPDEBUG(LOG_INFO, ("ChapMS: secret is '%.*s'\n", secret_len, secret)); -#endif - BZERO(&response, sizeof(response)); - - /* Calculate both always */ - ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); - - /* prefered method is set by option */ - response.UseNT = !ms_lanman; -#else - response.UseNT = 1; -#endif - - BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); - cstate->resp_length = MS_CHAP_RESPONSE_LEN; -} - -#endif /* MSCHAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/chpms.h b/external/badvpn_dns/lwip/src/netif/ppp/chpms.h deleted file mode 100644 index df070fb..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/chpms.h +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************** -* chpms.h - Network Microsoft Challenge Handshake Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 98-01-30 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original built from BSD network code. -******************************************************************************/ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Eric Rosenquist. The name of the author may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: chpms.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $ - */ - -#ifndef CHPMS_H -#define CHPMS_H - -#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ - -void ChapMS (chap_state *, char *, int, char *, int); - -#endif /* CHPMS_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/fsm.c b/external/badvpn_dns/lwip/src/netif/ppp/fsm.c deleted file mode 100644 index e8a254e..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/fsm.c +++ /dev/null @@ -1,890 +0,0 @@ -/***************************************************************************** -* fsm.c - Network Control Protocol Finite State Machine program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-01 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original based on BSD fsm.c. -*****************************************************************************/ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * TODO: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "fsm.h" - -#include <string.h> - -#if PPP_DEBUG -static const char *ppperr_strerr[] = { - "LS_INITIAL", /* LS_INITIAL 0 */ - "LS_STARTING", /* LS_STARTING 1 */ - "LS_CLOSED", /* LS_CLOSED 2 */ - "LS_STOPPED", /* LS_STOPPED 3 */ - "LS_CLOSING", /* LS_CLOSING 4 */ - "LS_STOPPING", /* LS_STOPPING 5 */ - "LS_REQSENT", /* LS_REQSENT 6 */ - "LS_ACKRCVD", /* LS_ACKRCVD 7 */ - "LS_ACKSENT", /* LS_ACKSENT 8 */ - "LS_OPENED" /* LS_OPENED 9 */ -}; -#endif /* PPP_DEBUG */ - -static void fsm_timeout (void *); -static void fsm_rconfreq (fsm *, u_char, u_char *, int); -static void fsm_rconfack (fsm *, int, u_char *, int); -static void fsm_rconfnakrej (fsm *, int, int, u_char *, int); -static void fsm_rtermreq (fsm *, int, u_char *, int); -static void fsm_rtermack (fsm *); -static void fsm_rcoderej (fsm *, u_char *, int); -static void fsm_sconfreq (fsm *, int); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -int peer_mru[NUM_PPP]; - - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void -fsm_init(fsm *f) -{ - f->state = LS_INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->timeouttime = FSM_DEFTIMEOUT; - f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; - f->maxtermtransmits = FSM_DEFMAXTERMREQS; - f->maxnakloops = FSM_DEFMAXNAKLOOPS; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void -fsm_lowerup(fsm *f) -{ - int oldState = f->state; - - LWIP_UNUSED_ARG(oldState); - - switch( f->state ) { - case LS_INITIAL: - f->state = LS_CLOSED; - break; - - case LS_STARTING: - if( f->flags & OPT_SILENT ) { - f->state = LS_STOPPED; - } else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - } - break; - - default: - FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } - - FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void -fsm_lowerdown(fsm *f) -{ - int oldState = f->state; - - LWIP_UNUSED_ARG(oldState); - - switch( f->state ) { - case LS_CLOSED: - f->state = LS_INITIAL; - break; - - case LS_STOPPED: - f->state = LS_STARTING; - if( f->callbacks->starting ) { - (*f->callbacks->starting)(f); - } - break; - - case LS_CLOSING: - f->state = LS_INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case LS_STOPPING: - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - f->state = LS_STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case LS_OPENED: - if( f->callbacks->down ) { - (*f->callbacks->down)(f); - } - f->state = LS_STARTING; - break; - - default: - FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } - - FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void -fsm_open(fsm *f) -{ - int oldState = f->state; - - LWIP_UNUSED_ARG(oldState); - - switch( f->state ) { - case LS_INITIAL: - f->state = LS_STARTING; - if( f->callbacks->starting ) { - (*f->callbacks->starting)(f); - } - break; - - case LS_CLOSED: - if( f->flags & OPT_SILENT ) { - f->state = LS_STOPPED; - } else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - } - break; - - case LS_CLOSING: - f->state = LS_STOPPING; - /* fall through */ - case LS_STOPPED: - case LS_OPENED: - if( f->flags & OPT_RESTART ) { - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - } - - FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); -} - -#if 0 /* backport pppd 2.4.4b1; */ -/* - * terminate_layer - Start process of shutting down the FSM - * - * Cancel any timeout running, notify upper layers we're done, and - * send a terminate-request message as configured. - */ -static void -terminate_layer(fsm *f, int nextstate) -{ - /* @todo */ -} -#endif - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the LS_CLOSED state. - */ -void -fsm_close(fsm *f, char *reason) -{ - int oldState = f->state; - - LWIP_UNUSED_ARG(oldState); - - f->term_reason = reason; - f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason)); - switch( f->state ) { - case LS_STARTING: - f->state = LS_INITIAL; - break; - case LS_STOPPED: - f->state = LS_CLOSED; - break; - case LS_STOPPING: - f->state = LS_CLOSING; - break; - - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - case LS_OPENED: - if( f->state != LS_OPENED ) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - } else if( f->callbacks->down ) { - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - } - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = LS_CLOSING; - break; - } - - FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void -fsm_timeout(void *arg) -{ - fsm *f = (fsm *) arg; - - switch (f->state) { - case LS_CLOSING: - case LS_STOPPING: - if( f->retransmits <= 0 ) { - FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - } else { - FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - } - break; - - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - if (f->retransmits <= 0) { - FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - f->state = LS_STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - } else { - FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) { - (*f->callbacks->retransmit)(f); - } - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == LS_ACKRCVD ) { - f->state = LS_REQSENT; - } - } - break; - - default: - FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } -} - - -/* - * fsm_input - Input packet. - */ -void -fsm_input(fsm *f, u_char *inpacket, int l) -{ - u_char *inp = inpacket; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - if (l < HEADERLEN) { - FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n", - f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n", - f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n", - f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == LS_INITIAL || f->state == LS_STARTING ) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n", - f->protocol, f->state, ppperr_strerr[f->state])); - return; - } - FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l)); - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f))); - if( !f->callbacks->extcode || - !(*f->callbacks->extcode)(f, code, id, inp, len) ) { - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - } - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void -fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) -{ - int code, reject_if_disagree; - - FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - switch( f->state ) { - case LS_CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case LS_CLOSING: - case LS_STOPPING: - return; - - case LS_OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - break; - - case LS_STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = LS_REQSENT; - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci) { /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) { - code = CONFREJ; /* Reject all CI */ - } else { - code = CONFACK; - } - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, (u_char)code, id, inp, len); - - if (code == CONFACK) { - if (f->state == LS_ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = LS_OPENED; - if (f->callbacks->up) { - (*f->callbacks->up)(f); /* Inform upper layers */ - } - } else { - f->state = LS_ACKSENT; - } - f->nakloops = 0; - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != LS_ACKRCVD) { - f->state = LS_REQSENT; - } - if( code == CONFNAK ) { - ++f->nakloops; - } - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void -fsm_rconfack(fsm *f, int id, u_char *inp, int len) -{ - FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - - if (id != f->reqid || f->seen_ack) { /* Expected id? */ - return; /* Nope, toss... */ - } - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) { - /* Ack is bad - ignore it */ - FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n", - PROTO_NAME(f), len)); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case LS_CLOSED: - case LS_STOPPED: - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); - break; - - case LS_REQSENT: - f->state = LS_ACKRCVD; - f->retransmits = f->maxconfreqtransmits; - break; - - case LS_ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - break; - - case LS_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = LS_OPENED; - f->retransmits = f->maxconfreqtransmits; - if (f->callbacks->up) { - (*f->callbacks->up)(f); /* Inform upper layers */ - } - break; - - case LS_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = LS_REQSENT; - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void -fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) -{ - int (*proc) (fsm *, u_char *, int); - int ret; - - FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - - if (id != f->reqid || f->seen_ack) { /* Expected id? */ - return; /* Nope, toss... */ - } - proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; - if (!proc || !((ret = proc(f, inp, len)))) { - /* Nak/reject is bad - ignore it */ - FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n", - PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len)); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case LS_CLOSED: - case LS_STOPPED: - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); - break; - - case LS_REQSENT: - case LS_ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) { - f->state = LS_STOPPED; /* kludge for stopping CCP */ - } else { - fsm_sconfreq(f, 0); /* Send Configure-Request */ - } - break; - - case LS_ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - break; - - case LS_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = LS_REQSENT; - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void -fsm_rtermreq(fsm *f, int id, u_char *p, int len) -{ - LWIP_UNUSED_ARG(p); - - FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - - switch (f->state) { - case LS_ACKRCVD: - case LS_ACKSENT: - f->state = LS_REQSENT; /* Start over but keep trying */ - break; - - case LS_OPENED: - if (len > 0) { - FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p)); - } else { - FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f))); - } - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - f->retransmits = 0; - f->state = LS_STOPPING; - TIMEOUT(fsm_timeout, f, f->timeouttime); - break; - } - - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void -fsm_rtermack(fsm *f) -{ - FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - - switch (f->state) { - case LS_CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = LS_CLOSED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_ACKRCVD: - f->state = LS_REQSENT; - break; - - case LS_OPENED: - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - fsm_sconfreq(f, 0); - break; - default: - FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void -fsm_rcoderej(fsm *f, u_char *inp, int len) -{ - u_char code, id; - - FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - - if (len < HEADERLEN) { - FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n", - PROTO_NAME(f), code, id)); - - if( f->state == LS_ACKRCVD ) { - f->state = LS_REQSENT; - } -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void -fsm_protreject(fsm *f) -{ - switch( f->state ) { - case LS_CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case LS_CLOSED: - f->state = LS_CLOSED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_STOPPING: - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case LS_STOPPED: - f->state = LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_OPENED: - if( f->callbacks->down ) { - (*f->callbacks->down)(f); - } - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = LS_STOPPING; - break; - - default: - FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void -fsm_sconfreq(fsm *f, int retransmit) -{ - u_char *outp; - int cilen; - - if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) { - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) { - (*f->callbacks->resetci)(f); - } - f->nakloops = 0; - } - - if( !retransmit ) { - /* New request - reset retransmission counter, use new ID */ - f->retransmits = f->maxconfreqtransmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ) { - cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) { - cilen = peer_mru[f->unit] - HEADERLEN; - } - if (f->callbacks->addci) { - (*f->callbacks->addci)(f, outp, &cilen); - } - } else { - cilen = 0; - } - - /* send the request to our peer */ - fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, f->timeouttime); - - FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n", - PROTO_NAME(f), f->reqid)); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void -fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen) -{ - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - outp = outpacket_buf[f->unit]; - if (datalen > peer_mru[f->unit] - (int)HEADERLEN) { - datalen = peer_mru[f->unit] - HEADERLEN; - } - if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) { - BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); - } - outlen = datalen + HEADERLEN; - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN); - FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n", - PROTO_NAME(f), code, id, outlen)); -} - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/fsm.h b/external/badvpn_dns/lwip/src/netif/ppp/fsm.h deleted file mode 100644 index 8d41b5f..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/fsm.h +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************************** -* fsm.h - Network Control Protocol Finite State Machine header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-11-05 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original based on BSD code. -*****************************************************************************/ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: fsm.h,v 1.5 2009/12/31 17:08:08 goldsimon Exp $ - */ - -#ifndef FSM_H -#define FSM_H - -/* - * LCP Packet header = Code, id, length. - */ -#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) - - -/* - * CP (LCP, IPCP, etc.) codes. - */ -#define CONFREQ 1 /* Configuration Request */ -#define CONFACK 2 /* Configuration Ack */ -#define CONFNAK 3 /* Configuration Nak */ -#define CONFREJ 4 /* Configuration Reject */ -#define TERMREQ 5 /* Termination Request */ -#define TERMACK 6 /* Termination Ack */ -#define CODEREJ 7 /* Code Reject */ - - -/* - * Each FSM is described by an fsm structure and fsm callbacks. - */ -typedef struct fsm { - int unit; /* Interface unit number */ - u_short protocol; /* Data Link Layer Protocol field value */ - int state; /* State */ - int flags; /* Contains option bits */ - u_char id; /* Current id */ - u_char reqid; /* Current request id */ - u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ - int timeouttime; /* Timeout time in milliseconds */ - int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ - int retransmits; /* Number of retransmissions left */ - int maxtermtransmits; /* Maximum Terminate-Request transmissions */ - int nakloops; /* Number of nak loops since last ack */ - int maxnakloops; /* Maximum number of nak loops tolerated */ - struct fsm_callbacks* callbacks; /* Callback routines */ - char* term_reason; /* Reason for closing protocol */ - int term_reason_len; /* Length of term_reason */ -} fsm; - - -typedef struct fsm_callbacks { - void (*resetci)(fsm*); /* Reset our Configuration Information */ - int (*cilen)(fsm*); /* Length of our Configuration Information */ - void (*addci)(fsm*, u_char*, int*); /* Add our Configuration Information */ - int (*ackci)(fsm*, u_char*, int); /* ACK our Configuration Information */ - int (*nakci)(fsm*, u_char*, int); /* NAK our Configuration Information */ - int (*rejci)(fsm*, u_char*, int); /* Reject our Configuration Information */ - int (*reqci)(fsm*, u_char*, int*, int); /* Request peer's Configuration Information */ - void (*up)(fsm*); /* Called when fsm reaches LS_OPENED state */ - void (*down)(fsm*); /* Called when fsm leaves LS_OPENED state */ - void (*starting)(fsm*); /* Called when we want the lower layer */ - void (*finished)(fsm*); /* Called when we don't want the lower layer */ - void (*protreject)(int); /* Called when Protocol-Reject received */ - void (*retransmit)(fsm*); /* Retransmission is necessary */ - int (*extcode)(fsm*, int, u_char, u_char*, int); /* Called when unknown code received */ - char *proto_name; /* String name for protocol (for messages) */ -} fsm_callbacks; - - -/* - * Link states. - */ -#define LS_INITIAL 0 /* Down, hasn't been opened */ -#define LS_STARTING 1 /* Down, been opened */ -#define LS_CLOSED 2 /* Up, hasn't been opened */ -#define LS_STOPPED 3 /* Open, waiting for down event */ -#define LS_CLOSING 4 /* Terminating the connection, not open */ -#define LS_STOPPING 5 /* Terminating, but open */ -#define LS_REQSENT 6 /* We've sent a Config Request */ -#define LS_ACKRCVD 7 /* We've received a Config Ack */ -#define LS_ACKSENT 8 /* We've sent a Config Ack */ -#define LS_OPENED 9 /* Connection available */ - -/* - * Flags - indicate options controlling FSM operation - */ -#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ -#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ -#define OPT_SILENT 4 /* Wait for peer to speak first */ - - -/* - * Prototypes - */ -void fsm_init (fsm*); -void fsm_lowerup (fsm*); -void fsm_lowerdown (fsm*); -void fsm_open (fsm*); -void fsm_close (fsm*, char*); -void fsm_input (fsm*, u_char*, int); -void fsm_protreject (fsm*); -void fsm_sdata (fsm*, u_char, u_char, u_char*, int); - - -/* - * Variables - */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ - -#endif /* FSM_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ipcp.c b/external/badvpn_dns/lwip/src/netif/ppp/ipcp.c deleted file mode 100644 index f0ab2e0..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ipcp.c +++ /dev/null @@ -1,1411 +0,0 @@ -/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and - dial-on-demand has been stripped. */ -/***************************************************************************** -* ipcp.c - Network PPP IP Control Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-08 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original. -*****************************************************************************/ -/* - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "auth.h" -#include "fsm.h" -#include "vj.h" -#include "ipcp.h" - -#include "lwip/inet.h" - -#include <string.h> - -/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */ - -/* global vars */ -ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -/* local vars */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ - - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipcp_resetci (fsm *); /* Reset our CI */ -static int ipcp_cilen (fsm *); /* Return length of our CI */ -static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ -static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ -static int ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */ -static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ -static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ -static void ipcp_up (fsm *); /* We're UP */ -static void ipcp_down (fsm *); /* We're DOWN */ -#if PPP_ADDITIONAL_CALLBACKS -static void ipcp_script (fsm *, char *); /* Run an up/down script */ -#endif -static void ipcp_finished (fsm *); /* Don't need lower layer */ - - -fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ - - -static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ - ipcp_resetci, /* Reset our Configuration Information */ - ipcp_cilen, /* Length of our Configuration Information */ - ipcp_addci, /* Add our Configuration Information */ - ipcp_ackci, /* ACK our Configuration Information */ - ipcp_nakci, /* NAK our Configuration Information */ - ipcp_rejci, /* Reject our Configuration Information */ - ipcp_reqci, /* Request peer's Configuration Information */ - ipcp_up, /* Called when fsm reaches LS_OPENED state */ - ipcp_down, /* Called when fsm leaves LS_OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPCP" /* String name of protocol */ -}; - -/* - * Protocol entry points from main code. - */ -static void ipcp_init (int); -static void ipcp_open (int); -static void ipcp_close (int, char *); -static void ipcp_lowerup (int); -static void ipcp_lowerdown (int); -static void ipcp_input (int, u_char *, int); -static void ipcp_protrej (int); - - -struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, -#if PPP_ADDITIONAL_CALLBACKS - ipcp_printpkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "IPCP", -#if PPP_ADDITIONAL_CALLBACKS - ip_check_options, - NULL, - ip_active_pkt -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -static void ipcp_clear_addrs (int); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ -#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ -#define CILEN_ADDR 6 /* new-style single address option */ -#define CILEN_ADDRS 10 /* old-style dual address option */ - - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - - -/* - * ipcp_init - Initialize IPCP. - */ -static void -ipcp_init(int unit) -{ - fsm *f = &ipcp_fsm[unit]; - ipcp_options *wo = &ipcp_wantoptions[unit]; - ipcp_options *ao = &ipcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_IPCP; - f->callbacks = &ipcp_callbacks; - fsm_init(&ipcp_fsm[unit]); - - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); - - wo->neg_addr = 1; - wo->ouraddr = 0; -#if VJ_SUPPORT - wo->neg_vj = 1; -#else /* VJ_SUPPORT */ - wo->neg_vj = 0; -#endif /* VJ_SUPPORT */ - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_SLOTS - 1; - wo->cflag = 0; - wo->default_route = 1; - - ao->neg_addr = 1; -#if VJ_SUPPORT - ao->neg_vj = 1; -#else /* VJ_SUPPORT */ - ao->neg_vj = 0; -#endif /* VJ_SUPPORT */ - ao->maxslotindex = MAX_SLOTS - 1; - ao->cflag = 1; - ao->default_route = 1; -} - - -/* - * ipcp_open - IPCP is allowed to come up. - */ -static void -ipcp_open(int unit) -{ - fsm_open(&ipcp_fsm[unit]); -} - - -/* - * ipcp_close - Take IPCP down. - */ -static void -ipcp_close(int unit, char *reason) -{ - fsm_close(&ipcp_fsm[unit], reason); -} - - -/* - * ipcp_lowerup - The lower layer is up. - */ -static void -ipcp_lowerup(int unit) -{ - fsm_lowerup(&ipcp_fsm[unit]); -} - - -/* - * ipcp_lowerdown - The lower layer is down. - */ -static void -ipcp_lowerdown(int unit) -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_input - Input IPCP packet. - */ -static void -ipcp_input(int unit, u_char *p, int len) -{ - fsm_input(&ipcp_fsm[unit], p, len); -} - - -/* - * ipcp_protrej - A Protocol-Reject was received for IPCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipcp_protrej(int unit) -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_resetci - Reset our CI. - */ -static void -ipcp_resetci(fsm *f) -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; - if (wo->ouraddr == 0) { - wo->accept_local = 1; - } - if (wo->hisaddr == 0) { - wo->accept_remote = 1; - } - /* Request DNS addresses from the peer */ - wo->req_dns1 = ppp_settings.usepeerdns; - wo->req_dns2 = ppp_settings.usepeerdns; - ipcp_gotoptions[f->unit] = *wo; - cis_received[f->unit] = 0; -} - - -/* - * ipcp_cilen - Return length of our CI. - */ -static int -ipcp_cilen(fsm *f) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - -#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) -#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { - /* use the old style of address negotiation */ - go->neg_addr = 1; - go->old_addrs = 1; - } - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - if (cis_received[f->unit] == 0) { - /* keep trying the new style until we see some CI from the peer */ - go->neg_vj = 1; - } else { - /* use the old style only if the peer did */ - if (ho->neg_vj && ho->old_vj) { - go->neg_vj = 1; - go->old_vj = 1; - go->vj_protocol = ho->vj_protocol; - } - } - } - - return (LENCIADDR(go->neg_addr, go->old_addrs) + - LENCIVJ(go->neg_vj, go->old_vj) + - LENCIDNS(go->req_dns1) + - LENCIDNS(go->req_dns2)); -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - */ -static void -ipcp_addci(fsm *f, u_char *ucp, int *lenp) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - int len = *lenp; - -#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - if (!old) { \ - PUTCHAR(maxslotindex, ucp); \ - PUTCHAR(cflag, ucp); \ - } \ - len -= vjlen; \ - } else { \ - neg = 0; \ - } \ - } - -#define ADDCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - if (len >= addrlen) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(addrlen, ucp); \ - l = ntohl(val1); \ - PUTLONG(l, ucp); \ - if (old) { \ - l = ntohl(val2); \ - PUTLONG(l, ucp); \ - } \ - len -= addrlen; \ - } else { \ - neg = 0; \ - } \ - } - -#define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else { \ - neg = 0; \ - } \ - } - - ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipcp_ackci(fsm *f, u_char *p, int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_short cilen, citype, cishort; - u32_t cilong; - u_char cimaxslotindex, cicflag; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if ((len -= vjlen) < 0) { \ - goto bad; \ - } \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) { \ - goto bad; \ - } \ - GETSHORT(cishort, p); \ - if (cishort != val) { \ - goto bad; \ - } \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslotindex) { \ - goto bad; \ - } \ - GETCHAR(cicflag, p); \ - if (cicflag != cflag) { \ - goto bad; \ - } \ - } \ - } - -#define ACKCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - u32_t l; \ - if ((len -= addrlen) < 0) { \ - goto bad; \ - } \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != addrlen || \ - citype != opt) { \ - goto bad; \ - } \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val1 != cilong) { \ - goto bad; \ - } \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val2 != cilong) { \ - goto bad; \ - } \ - } \ - } - -#define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) { \ - goto bad; \ - } \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || \ - citype != opt) { \ - goto bad; \ - } \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (addr != cilong) { \ - goto bad; \ - } \ - } - - ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - return (1); - -bad: - IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n")); - return (0); -} - -/* - * ipcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPCP is in the LS_OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -ipcp_nakci(fsm *f, u_char *p, int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, cicflag; - u_char citype, cilen, *next; - u_short cishort; - u32_t ciaddr1, ciaddr2, l, cidnsaddr; - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIADDR(opt, neg, old, code) \ - if (go->neg && \ - len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = htonl(l); \ - if (old) { \ - GETLONG(l, p); \ - ciaddr2 = htonl(l); \ - no.old_addrs = 1; \ - } else { \ - ciaddr2 = 0; \ - } \ - no.neg = 1; \ - code \ - } - -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } - -#define NAKCIDNS(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cidnsaddr = htonl(l); \ - no.neg = 1; \ - code \ - } - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, - if (go->accept_local && ciaddr1) { /* Do we know our address? */ - try.ouraddr = ciaddr1; - IPCPDEBUG(LOG_INFO, ("local IP address %s\n", - inet_ntoa(ciaddr1))); - } - if (go->accept_remote && ciaddr2) { /* Does he know his? */ - try.hisaddr = ciaddr2; - IPCPDEBUG(LOG_INFO, ("remote IP address %s\n", - inet_ntoa(ciaddr2))); - } - ); - - /* - * Accept the peer's value of maxslotindex provided that it - * is less than what we asked for. Turn off slot-ID compression - * if the peer wants. Send old-style compress-type option if - * the peer wants. - */ - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - if (cilen == CILEN_VJ) { - GETCHAR(cimaxslotindex, p); - GETCHAR(cicflag, p); - if (cishort == IPCP_VJ_COMP) { - try.old_vj = 0; - if (cimaxslotindex < go->maxslotindex) { - try.maxslotindex = cimaxslotindex; - } - if (!cicflag) { - try.cflag = 0; - } - } else { - try.neg_vj = 0; - } - } else { - if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { - try.old_vj = 1; - try.vj_protocol = cishort; - } else { - try.neg_vj = 0; - } - } - ); - - NAKCIDNS(CI_MS_DNS1, req_dns1, - try.dnsaddr[0] = cidnsaddr; - IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr))); - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - try.dnsaddr[1] = cidnsaddr; - IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr))); - ); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about IP addresses, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if( (len -= cilen) < 0 ) { - goto bad; - } - next = p + cilen - 2; - - switch (citype) { - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - goto bad; - } - no.neg_vj = 1; - break; - case CI_ADDRS: - if ((go->neg_addr && go->old_addrs) || no.old_addrs - || cilen != CILEN_ADDRS) { - goto bad; - } - try.neg_addr = 1; - try.old_addrs = 1; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) { - try.ouraddr = ciaddr1; - } - GETLONG(l, p); - ciaddr2 = htonl(l); - if (ciaddr2 && go->accept_remote) { - try.hisaddr = ciaddr2; - } - no.old_addrs = 1; - break; - case CI_ADDR: - if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) { - goto bad; - } - try.old_addrs = 0; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) { - try.ouraddr = ciaddr1; - } - if (try.ouraddr != 0) { - try.neg_addr = 1; - } - no.neg_addr = 1; - break; - } - p = next; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) { - goto bad; - } - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != LS_OPENED) { - *go = try; - } - - return 1; - -bad: - IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - */ -static int -ipcp_rejci(fsm *f, u_char *p, int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, ciflag, cilen; - u_short cishort; - u32_t cilong; - ipcp_options try; /* options to request next time */ - - try = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIADDR(opt, neg, old, val1, val2) \ - if (go->neg && \ - len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ - p[1] == cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val1) { \ - goto bad; \ - } \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) { \ - goto bad; \ - } \ - } \ - try.neg = 0; \ - } - -#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ - if (go->neg && \ - p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) { \ - goto bad; \ - } \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslot) { \ - goto bad; \ - } \ - GETCHAR(ciflag, p); \ - if (ciflag != cflag) { \ - goto bad; \ - } \ - } \ - try.neg = 0; \ - } - -#define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) { \ - goto bad; \ - } \ - try.neg = 0; \ - } - - REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); - - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - /* - * Now we can update state. - */ - if (f->state != LS_OPENED) { - *go = try; - } - return 1; - -bad: - IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n")); - return 0; -} - - -/* - * ipcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree) -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *ao = &ipcp_allowoptions[f->unit]; -#ifdef OLD_CI_ADDRS - ipcp_options *go = &ipcp_gotoptions[f->unit]; -#endif - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - u32_t tl, ciaddr1; /* Parsed address values */ -#ifdef OLD_CI_ADDRS - u32_t ciaddr2; /* Parsed address values */ -#endif - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - u_char maxslotindex, cflag; - int d; - - cis_received[f->unit] = 1; - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n")); - orc = CONFREJ; /* Reject bad CI */ - cilen = (u_short)l;/* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ -#ifdef OLD_CI_ADDRS /* Need to save space... */ - case CI_ADDRS: - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n")); - if (!ao->neg_addr || - cilen != CILEN_ADDRS) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1))); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * If neither we nor he knows his address, reject the option. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - /* - * If he doesn't know our address, or if we both have our address - * but disagree about it, then NAK it with our idea. - */ - GETLONG(tl, p); /* Parse desination address (ours) */ - ciaddr2 = htonl(tl); - IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2))); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - go->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->neg_addr = 1; - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; -#endif - - case CI_ADDR: - if (!ao->neg_addr) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n")); - orc = CONFREJ; /* Reject CI */ - break; - } else if (cilen != CILEN_ADDR) { /* Check CI length */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n")); - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1))); - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1))); - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1))); - break; - - case CI_MS_DNS1: - case CI_MS_DNS2: - /* Microsoft primary or secondary DNS request */ - d = citype == CI_MS_DNS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->dnsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1)); - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->dnsaddr[d]) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n", - d+1, inet_ntoa(tl))); - DECPTR(sizeof(u32_t), p); - tl = ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1)); - break; - - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1)); - - /* If we do not have a DNS address then we cannot send it */ - if (ao->winsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(u32_t), p); - tl = ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_COMPRESSTYPE: - if (!ao->neg_vj) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen)); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort)); - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex)); - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag)); - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(1, p); - PUTCHAR(wo->cflag, p); - } - } - ho->maxslotindex = maxslotindex; - ho->cflag = cflag; - } else { - ho->old_vj = 1; - ho->maxslotindex = MAX_SLOTS - 1; - ho->cflag = 1; - } - IPCPDEBUG(LOG_INFO, ( - "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n", - ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag)); - break; - - default: - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype)); - orc = CONFREJ; - break; - } - -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) { /* but prior CI wasnt? */ - continue; /* Don't send this one */ - } - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) { /* Getting fed up with sending NAKs? */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n")); - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) { /* Rejecting prior CI? */ - continue; /* Don't send this one */ - } - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) { - BCOPY(cip, ucp, cilen); /* Move it */ - } - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a CI_ADDR option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_addr && - wo->req_addr && !reject_if_disagree) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n")); - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ - } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - - *len = (int)(ucp - inp); /* Compute output length */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -#if 0 -/* - * ip_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ip_check_options(u_long localAddr) -{ - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * Load our default IP address but allow the remote host to give us - * a new address. - */ - if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) { - wo->accept_local = 1; /* don't insist on this default value */ - wo->ouraddr = htonl(localAddr); - } -} -#endif - - -/* - * ipcp_up - IPCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ -static void -ipcp_up(fsm *f) -{ - u32_t mask; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - np_up(f->unit, PPP_IP); - IPCPDEBUG(LOG_INFO, ("ipcp: up\n")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr) { - ho->hisaddr = wo->hisaddr; - } - - if (ho->hisaddr == 0) { - IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n")); - ipcp_close(f->unit, "Could not determine remote IP address"); - return; - } - if (go->ouraddr == 0) { - IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n")); - ipcp_close(f->unit, "Could not determine local IP address"); - return; - } - - if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/ - } - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (!auth_ip_addr(f->unit, ho->hisaddr)) { - IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n", - inet_ntoa(ho->hisaddr))); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } - - /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); - - /* - * Set IP addresses and (if specified) netmask. - */ - mask = GetMask(go->ouraddr); - - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) { - IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* bring the interface up for IP */ - if (!sifup(f->unit)) { - IPCPDEBUG(LOG_WARNING, ("sifup failed\n")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) { - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) { - default_route_set[f->unit] = 1; - } - } - - IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr))); - IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr))); - if (go->dnsaddr[0]) { - IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0]))); - } - if (go->dnsaddr[1]) { - IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1]))); - } -} - - -/* - * ipcp_down - IPCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ -static void -ipcp_down(fsm *f) -{ - IPCPDEBUG(LOG_INFO, ("ipcp: down\n")); - np_down(f->unit, PPP_IP); - sifvjcomp(f->unit, 0, 0, 0); - - sifdown(f->unit); - ipcp_clear_addrs(f->unit); -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, etc. - */ -static void -ipcp_clear_addrs(int unit) -{ - u32_t ouraddr, hisaddr; - - ouraddr = ipcp_gotoptions[unit].ouraddr; - hisaddr = ipcp_hisoptions[unit].hisaddr; - if (default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); - default_route_set[unit] = 0; - } - cifaddr(unit, ouraddr, hisaddr); -} - - -/* - * ipcp_finished - possibly shut down the lower layers. - */ -static void -ipcp_finished(fsm *f) -{ - np_finished(f->unit, PPP_IP); -} - -#if PPP_ADDITIONAL_CALLBACKS -static int -ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) -{ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(plen); - LWIP_UNUSED_ARG(printer); - LWIP_UNUSED_ARG(arg); - return 0; -} - -/* - * ip_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP_HDRLEN 20 /* bytes */ -#define IP_OFFMASK 0x1fff -#define IPPROTO_TCP 6 -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define net_short(x) (((x)[0] << 8) + (x)[1]) -#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) -#define get_ipoff(x) net_short((unsigned char *)(x) + 6) -#define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ip_active_pkt(u_char *pkt, int len) -{ - u_char *tcp; - int hlen; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP_HDRLEN) { - return 0; - } - if ((get_ipoff(pkt) & IP_OFFMASK) != 0) { - return 0; - } - if (get_ipproto(pkt) != IPPROTO_TCP) { - return 1; - } - hlen = get_iphl(pkt) * 4; - if (len < hlen + TCP_HDRLEN) { - return 0; - } - tcp = pkt + hlen; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) { - return 0; - } - return 1; -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ipcp.h b/external/badvpn_dns/lwip/src/netif/ppp/ipcp.h deleted file mode 100644 index de03f46..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ipcp.h +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************** -* ipcp.h - PPP IP NCP: Internet Protocol Network Control Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -/* - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: ipcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ - */ - -#ifndef IPCP_H -#define IPCP_H - -/* - * Options. - */ -#define CI_ADDRS 1 /* IP Addresses */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#define CI_ADDR 3 - -#define CI_MS_DNS1 129 /* Primary DNS value */ -#define CI_MS_WINS1 128 /* Primary WINS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#define CI_MS_WINS2 130 /* Secondary WINS value */ - -#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ -#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ -#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ - /* maxslot and slot number compression) */ - -#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option */ -#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ - /* compression option */ - -typedef struct ipcp_options { - u_int neg_addr : 1; /* Negotiate IP Address? */ - u_int old_addrs : 1; /* Use old (IP-Addresses) option? */ - u_int req_addr : 1; /* Ask peer to send IP address? */ - u_int default_route : 1; /* Assign default route through interface? */ - u_int proxy_arp : 1; /* Make proxy ARP entry for peer? */ - u_int neg_vj : 1; /* Van Jacobson Compression? */ - u_int old_vj : 1; /* use old (short) form of VJ option? */ - u_int accept_local : 1; /* accept peer's value for ouraddr */ - u_int accept_remote : 1; /* accept peer's value for hisaddr */ - u_int req_dns1 : 1; /* Ask peer to send primary DNS address? */ - u_int req_dns2 : 1; /* Ask peer to send secondary DNS address? */ - u_short vj_protocol; /* protocol value to use in VJ option */ - u_char maxslotindex; /* VJ slots - 1. */ - u_char cflag; /* VJ slot compression flag. */ - u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ -} ipcp_options; - -extern fsm ipcp_fsm[]; -extern ipcp_options ipcp_wantoptions[]; -extern ipcp_options ipcp_gotoptions[]; -extern ipcp_options ipcp_allowoptions[]; -extern ipcp_options ipcp_hisoptions[]; - -extern struct protent ipcp_protent; - -#endif /* IPCP_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/lcp.c b/external/badvpn_dns/lwip/src/netif/ppp/lcp.c deleted file mode 100644 index 54f758a..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/lcp.c +++ /dev/null @@ -1,2066 +0,0 @@ -/***************************************************************************** -* lcp.c - Network Link Control Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-01 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original. -*****************************************************************************/ - -/* - * lcp.c - PPP Link Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "fsm.h" -#include "chap.h" -#include "magic.h" -#include "auth.h" -#include "lcp.h" - -#include <string.h> - -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#else -#define PPPOE_MAXMTU PPP_MAXMRU -#endif - -#if 0 /* UNUSED */ -/* - * LCP-related command-line options. - */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -bool lax_recv = 0; /* accept control chars in asyncmap */ - -static int setescape (char **); - -static option_t lcp_option_list[] = { - /* LCP options */ - /* list stripped for simplicity */ - {NULL} -}; -#endif /* UNUSED */ - -/* options */ -LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ -static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ -static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ - -/* global vars */ -static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ -lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ -ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ - -static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static u32_t lcp_echo_number = 0; /* ID number of next echo frame */ -static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ - -/* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */ -static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void lcp_resetci (fsm*); /* Reset our CI */ -static int lcp_cilen (fsm*); /* Return length of our CI */ -static void lcp_addci (fsm*, u_char*, int*); /* Add our CI to pkt */ -static int lcp_ackci (fsm*, u_char*, int); /* Peer ack'd our CI */ -static int lcp_nakci (fsm*, u_char*, int); /* Peer nak'd our CI */ -static int lcp_rejci (fsm*, u_char*, int); /* Peer rej'd our CI */ -static int lcp_reqci (fsm*, u_char*, int*, int); /* Rcv peer CI */ -static void lcp_up (fsm*); /* We're UP */ -static void lcp_down (fsm*); /* We're DOWN */ -static void lcp_starting (fsm*); /* We need lower layer up */ -static void lcp_finished (fsm*); /* We need lower layer down */ -static int lcp_extcode (fsm*, int, u_char, u_char*, int); -static void lcp_rprotrej (fsm*, u_char*, int); - -/* - * routines to send LCP echos to peer - */ - -static void lcp_echo_lowerup (int); -static void lcp_echo_lowerdown (int); -static void LcpEchoTimeout (void*); -static void lcp_received_echo_reply (fsm*, int, u_char*, int); -static void LcpSendEchoRequest (fsm*); -static void LcpLinkFailure (fsm*); -static void LcpEchoCheck (fsm*); - -static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ - lcp_resetci, /* Reset our Configuration Information */ - lcp_cilen, /* Length of our Configuration Information */ - lcp_addci, /* Add our Configuration Information */ - lcp_ackci, /* ACK our Configuration Information */ - lcp_nakci, /* NAK our Configuration Information */ - lcp_rejci, /* Reject our Configuration Information */ - lcp_reqci, /* Request peer's Configuration Information */ - lcp_up, /* Called when fsm reaches LS_OPENED state */ - lcp_down, /* Called when fsm leaves LS_OPENED state */ - lcp_starting, /* Called when we want the lower layer up */ - lcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - lcp_extcode, /* Called to handle LCP-specific codes */ - "LCP" /* String name of protocol */ -}; - -/* - * Protocol entry points. - * Some of these are called directly. - */ - -static void lcp_input (int, u_char *, int); -static void lcp_protrej (int); - -struct protent lcp_protent = { - PPP_LCP, - lcp_init, - lcp_input, - lcp_protrej, - lcp_lowerup, - lcp_lowerdown, - lcp_open, - lcp_close, -#if PPP_ADDITIONAL_CALLBACKS - lcp_printpkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "LCP", -#if PPP_ADDITIONAL_CALLBACKS - NULL, - NULL, - NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -int lcp_loopbackfail = DEFLOOPBACKFAIL; - -/* - * Length of each type of configuration option (in octets) - */ -#define CILEN_VOID 2 -#define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ -#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ -#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ") - -#if 0 /* UNUSED */ -/* - * setescape - add chars to the set we escape on transmission. - */ -static int -setescape(argv) - char **argv; -{ - int n, ret; - char *p, *endp; - - p = *argv; - ret = 1; - while (*p) { - n = strtol(p, &endp, 16); - if (p == endp) { - option_error("escape parameter contains invalid hex number '%s'", p); - return 0; - } - p = endp; - if (n < 0 || n == 0x5E || n > 0xFF) { - option_error("can't escape character 0x%x", n); - ret = 0; - } else - xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); - while (*p == ',' || *p == ' ') - ++p; - } - return ret; -} -#endif /* UNUSED */ - -/* - * lcp_init - Initialize LCP. - */ -void -lcp_init(int unit) -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_LCP; - f->callbacks = &lcp_callbacks; - - fsm_init(f); - - wo->passive = 0; - wo->silent = 0; - wo->restart = 0; /* Set to 1 in kernels or multi-line implementations */ - wo->neg_mru = 1; - wo->mru = PPP_DEFMRU; - wo->neg_asyncmap = 1; - wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ - wo->neg_chap = 0; /* Set to 1 on server */ - wo->neg_upap = 0; /* Set to 1 on server */ - wo->chap_mdtype = CHAP_DIGEST_MD5; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - wo->neg_lqr = 0; /* no LQR implementation yet */ - wo->neg_cbcp = 0; - - ao->neg_mru = 1; - ao->mru = PPP_MAXMRU; - ao->neg_asyncmap = 1; - ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ - ao->neg_chap = (CHAP_SUPPORT != 0); - ao->chap_mdtype = CHAP_DIGEST_MD5; - ao->neg_upap = (PAP_SUPPORT != 0); - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_lqr = 0; /* no LQR implementation yet */ - ao->neg_cbcp = (CBCP_SUPPORT != 0); - - /* - * Set transmit escape for the flag and escape characters plus anything - * set for the allowable options. - */ - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); - xmit_accm[unit][15] = 0x60; - xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); - xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); - xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); - xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); - LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n", - xmit_accm[unit][0], - xmit_accm[unit][1], - xmit_accm[unit][2], - xmit_accm[unit][3])); - - lcp_phase[unit] = PHASE_INITIALIZE; -} - - -/* - * lcp_open - LCP is allowed to come up. - */ -void -lcp_open(int unit) -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - - f->flags = 0; - if (wo->passive) { - f->flags |= OPT_PASSIVE; - } - if (wo->silent) { - f->flags |= OPT_SILENT; - } - fsm_open(f); - - lcp_phase[unit] = PHASE_ESTABLISH; -} - - -/* - * lcp_close - Take LCP down. - */ -void -lcp_close(int unit, char *reason) -{ - fsm *f = &lcp_fsm[unit]; - - if (lcp_phase[unit] != PHASE_DEAD) { - lcp_phase[unit] = PHASE_TERMINATE; - } - if (f->state == LS_STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { - /* - * This action is not strictly according to the FSM in RFC1548, - * but it does mean that the program terminates if you do an - * lcp_close() in passive/silent mode when a connection hasn't - * been established. - */ - f->state = LS_CLOSED; - lcp_finished(f); - } else { - fsm_close(f, reason); - } -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void -lcp_lowerup(int unit) -{ - lcp_options *wo = &lcp_wantoptions[unit]; - - /* - * Don't use A/C or protocol compression on transmission, - * but accept A/C and protocol compressed packets - * if we are going to ask for A/C and protocol compression. - */ - ppp_set_xaccm(unit, &xmit_accm[unit]); - ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0); - ppp_recv_config(unit, PPP_MRU, 0x00000000l, - wo->neg_pcompression, wo->neg_accompression); - peer_mru[unit] = PPP_MRU; - lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] - | ((u_long)xmit_accm[unit][1] << 8) - | ((u_long)xmit_accm[unit][2] << 16) - | ((u_long)xmit_accm[unit][3] << 24); - LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n", - xmit_accm[unit][3], - xmit_accm[unit][2], - xmit_accm[unit][1], - xmit_accm[unit][0])); - - fsm_lowerup(&lcp_fsm[unit]); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void -lcp_lowerdown(int unit) -{ - fsm_lowerdown(&lcp_fsm[unit]); -} - - -/* - * lcp_input - Input LCP packet. - */ -static void -lcp_input(int unit, u_char *p, int len) -{ - fsm *f = &lcp_fsm[unit]; - - fsm_input(f, p, len); -} - - -/* - * lcp_extcode - Handle a LCP-specific code. - */ -static int -lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len) -{ - u_char *magp; - - switch( code ){ - case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - - case ECHOREQ: - if (f->state != LS_OPENED) { - break; - } - LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id)); - magp = inp; - PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - - case ECHOREP: - lcp_received_echo_reply(f, id, inp, len); - break; - - case DISCREQ: - break; - - default: - return 0; - } - return 1; -} - - -/* - * lcp_rprotrej - Receive an Protocol-Reject. - * - * Figure out which protocol is rejected and inform it. - */ -static void -lcp_rprotrej(fsm *f, u_char *inp, int len) -{ - int i; - struct protent *protp; - u_short prot; - - if (len < (int)sizeof (u_short)) { - LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n")); - return; - } - - GETSHORT(prot, inp); - - LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot)); - - /* - * Protocol-Reject packets received in any state other than the LCP - * LS_OPENED state SHOULD be silently discarded. - */ - if( f->state != LS_OPENED ) { - LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state)); - return; - } - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == prot && protp->enabled_flag) { - (*protp->protrej)(f->unit); - return; - } - } - - LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot)); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -static void -lcp_protrej(int unit) -{ - LWIP_UNUSED_ARG(unit); - /* - * Can't reject LCP! - */ - LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n")); - fsm_protreject(&lcp_fsm[unit]); -} - - -/* - * lcp_sprotrej - Send a Protocol-Reject for some protocol. - */ -void -lcp_sprotrej(int unit, u_char *p, int len) -{ - /* - * Send back the protocol and the information field of the - * rejected packet. We only get here if LCP is in the LS_OPENED state. - */ - - fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len); -} - - -/* - * lcp_resetci - Reset our CI. - */ -static void -lcp_resetci(fsm *f) -{ - lcp_wantoptions[f->unit].magicnumber = magic(); - lcp_wantoptions[f->unit].numloops = 0; - lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; - peer_mru[f->unit] = PPP_MRU; - auth_reset(f->unit); -} - - -/* - * lcp_cilen - Return length of our CI. - */ -static int -lcp_cilen(fsm *f) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - -#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) -#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) -#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) -#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) -#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) -#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) - /* - * NB: we only ask for one of CHAP and UPAP, even if we will - * accept either. - */ - return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + - LENCICHAP(go->neg_chap) + - LENCISHORT(!go->neg_chap && go->neg_upap) + - LENCILQR(go->neg_lqr) + - LENCICBCP(go->neg_cbcp) + - LENCILONG(go->neg_magicnumber) + - LENCIVOID(go->neg_pcompression) + - LENCIVOID(go->neg_accompression)); -} - - -/* - * lcp_addci - Add our desired CIs to a packet. - */ -static void -lcp_addci(fsm *f, u_char *ucp, int *lenp) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char *start_ucp = ucp; - -#define ADDCIVOID(opt, neg) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } -#define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#define ADDCICHAP(opt, neg, val, digest) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, ucp); \ - } -#define ADDCILONG(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCILQR(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n")); - } -} - - -/* - * lcp_ackci - Ack our CIs. - * This should not modify any state if the Ack is bad. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -lcp_ackci(fsm *f, u_char *p, int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cilen, citype, cichar; - u_short cishort; - u32_t cilong; - - /* - * CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || citype != opt) \ - goto bad; \ - } -#define ACKCISHORT(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_SHORT) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_SHORT || citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#define ACKCICHAR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR || citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != val) \ - goto bad; \ - } -#define ACKCICHAP(opt, neg, val, digest) \ - if (neg) { \ - if ((len -= CILEN_CHAP) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAP || citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != digest) \ - goto bad; \ - } -#define ACKCILONG(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LONG) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LONG || citype != opt) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#define ACKCILQR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LQR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LQR || citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_LQR) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n")); - return (1); -bad: - LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n")); - return (0); -} - - -/* - * lcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if LCP is in the LS_OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -lcp_nakci(fsm *f, u_char *p, int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; - u_char citype, cichar, *next; - u_short cishort; - u32_t cilong; - lcp_options no; /* options we've seen Naks for */ - lcp_options try; /* options to request next time */ - int looped_back = 0; - int cilen; - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIVOID(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - code \ - } -#define NAKCICHAP(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCICHAR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[1] == CILEN_CHAR && \ - p[0] == opt) { \ - len -= CILEN_CHAR; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCISHORT(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILONG(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILQR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } - - /* - * We don't care if they want to send us smaller packets than - * we want. Therefore, accept any MRU less than what we asked for, - * but then ignore the new value when setting the MRU in the kernel. - * If they send us a bigger MRU than what we asked, accept it, up to - * the limit of the default MRU we'd get if we didn't negotiate. - */ - if (go->neg_mru && go->mru != PPP_DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort < PPP_DEFMRU) { - try.mru = cishort; - } - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) { - NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try.asyncmap = go->asyncmap | cilong; - ); - } - - /* - * If they've nak'd our authentication-protocol, check whether - * they are proposing a different protocol, or a different - * hash algorithm for CHAP. - */ - if ((go->neg_chap || go->neg_upap) - && len >= CILEN_SHORT - && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { - cilen = p[1]; - len -= cilen; - no.neg_chap = go->neg_chap; - no.neg_upap = go->neg_upap; - INCPTR(2, p); - GETSHORT(cishort, p); - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { - /* - * If we were asking for CHAP, they obviously don't want to do it. - * If we weren't asking for CHAP, then we were asking for PAP, - * in which case this Nak is bad. - */ - if (!go->neg_chap) { - goto bad; - } - try.neg_chap = 0; - - } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); - if (go->neg_chap) { - /* - * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we'll have to stop - * asking for CHAP. - */ - if (cichar != go->chap_mdtype) { - try.neg_chap = 0; - } - } else { - /* - * Stop asking for PAP if we were asking for it. - */ - try.neg_upap = 0; - } - - } else { - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - if (go->neg_chap) { - try.neg_chap = 0; - } else { - try.neg_upap = 0; - } - p += cilen - CILEN_SHORT; - } - } - - /* - * If they can't cope with our link quality protocol, we'll have - * to stop asking for LQR. We haven't got any other protocol. - * If they Nak the reporting period, take their value XXX ? - */ - NAKCILQR(CI_QUALITY, neg_lqr, - if (cishort != PPP_LQR) { - try.neg_lqr = 0; - } else { - try.lqr_period = cilong; - } - ); - - /* - * Only implementing CBCP...not the rest of the callback options - */ - NAKCICHAR(CI_CALLBACK, neg_cbcp, - try.neg_cbcp = 0; - ); - - /* - * Check for a looped-back line. - */ - NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try.magicnumber = magic(); - looped_back = 1; - ); - - /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - NAKCIVOID(CI_PCOMPRESSION, neg_pcompression, - try.neg_pcompression = 0; - ); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, - try.neg_accompression = 0; - ); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If we see an option that we requested, or one we've already seen - * in this packet, then this packet is bad. - * If we wanted to respond by starting to negotiate on the requested - * option(s), we could, but we don't, because except for the - * authentication type and quality protocol, if we are not negotiating - * an option, it is because we were told not to. - * For the authentication type, the Nak from the peer means - * `let me authenticate myself with you' which is a bit pointless. - * For the quality protocol, the Nak means `ask me to send you quality - * reports', but if we didn't ask for them, we don't want them. - * An option we don't recognize represents the peer asking to - * negotiate some option we don't support, so ignore it. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if (cilen < CILEN_VOID || (len -= cilen) < 0) { - goto bad; - } - next = p + cilen - 2; - - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != PPP_DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) { - goto bad; - } - GETSHORT(cishort, p); - if (cishort < PPP_DEFMRU) { - try.mru = cishort; - } - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) - || no.neg_asyncmap || cilen != CILEN_LONG) { - goto bad; - } - break; - case CI_AUTHTYPE: - if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) { - goto bad; - } - break; - case CI_MAGICNUMBER: - if (go->neg_magicnumber || no.neg_magicnumber || - cilen != CILEN_LONG) { - goto bad; - } - break; - case CI_PCOMPRESSION: - if (go->neg_pcompression || no.neg_pcompression - || cilen != CILEN_VOID) { - goto bad; - } - break; - case CI_ACCOMPRESSION: - if (go->neg_accompression || no.neg_accompression - || cilen != CILEN_VOID) { - goto bad; - } - break; - case CI_QUALITY: - if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) { - goto bad; - } - break; - } - p = next; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) { - goto bad; - } - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != LS_OPENED) { - if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { - LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n")); - lcp_close(f->unit, "Loopback detected"); - } - } else { - try.numloops = 0; - } - *go = try; - } - - return 1; - -bad: - LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n")); - return 0; -} - - -/* - * lcp_rejci - Peer has Rejected some of our CIs. - * This should not modify any state if the Reject is bad - * or if LCP is in the LS_OPENED state. - * - * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. - */ -static int -lcp_rejci(fsm *f, u_char *p, int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cichar; - u_short cishort; - u32_t cilong; - lcp_options try; /* options to request next time */ - - try = *go; - - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - try.neg = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \ - } -#define REJCISHORT(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) { \ - goto bad; \ - } \ - try.neg = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \ - } -#define REJCICHAP(opt, neg, val, digest) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cishort != val || cichar != digest) { \ - goto bad; \ - } \ - try.neg = 0; \ - try.neg_upap = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \ - } -#define REJCILONG(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cilong != val) { \ - goto bad; \ - } \ - try.neg = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \ - } -#define REJCILQR(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cishort != PPP_LQR || cilong != val) { \ - goto bad; \ - } \ - try.neg = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \ - } -#define REJCICBCP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CBCP && \ - p[1] == CILEN_CBCP && \ - p[0] == opt) { \ - len -= CILEN_CBCP; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cichar != val) { \ - goto bad; \ - } \ - try.neg = 0; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); - REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); - if (!go->neg_chap) { - REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); - } - REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); - REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); - REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); - REJCIVOID(CI_PCOMPRESSION, neg_pcompression); - REJCIVOID(CI_ACCOMPRESSION, neg_accompression); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - /* - * Now we can update state. - */ - if (f->state != LS_OPENED) { - *go = try; - } - return 1; - -bad: - LCPDEBUG(LOG_WARNING, ("lcp_rejci: received bad Reject!\n")); - return 0; -} - - -/* - * lcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -lcp_reqci(fsm *f, - u_char *inp, /* Requested CIs */ - int *lenp, /* Length of requested CIs */ - int reject_if_disagree) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype; /* Parsed len, type */ - u_char cichar; /* Parsed char value */ - u_short cishort; /* Parsed short value */ - u32_t cilong; /* Parse long value */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *rejp; /* Pointer to next char in reject frame */ - u_char *nakp; /* Pointer to next char in Nak frame */ - int l = *lenp; /* Length left */ -#if TRACELCP > 0 - char traceBuf[80]; - size_t traceNdx = 0; -#endif - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - nakp = nak_buffer; - rejp = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: bad CI length!\n")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - citype = 0; - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_MRU: - if (!ao->neg_mru) { /* Allow option? */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n")); - orc = CONFREJ; /* Reject CI */ - break; - } else if (cilen != CILEN_SHORT) { /* Check CI length */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n")); - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - - /* - * He must be able to receive at least our minimum. - * No need to check a maximum. If he sends a large number, - * we'll just ignore it. - */ - if (cishort < PPP_MINMRU) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n")); - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort); - traceNdx = strlen(traceBuf); -#endif - break; - - case CI_ASYNCMAP: - if (!ao->neg_asyncmap) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_LONG) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n")); - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * Asyncmap must have set at least the bits - * which are set in lcp_allowoptions[unit].asyncmap. - */ - if ((ao->asyncmap & ~cilong) != 0) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", - cilong, ao->asyncmap)); - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(ao->asyncmap | cilong, nakp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong); - traceNdx = strlen(traceBuf); -#endif - break; - - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n")); - orc = CONFREJ; - break; - } else if (!(ao->neg_upap || ao->neg_chap)) { - /* - * Reject the option if we're not willing to authenticate. - */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n")); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be UPAP or CHAP. - * - * Note: if both ao->neg_upap and ao->neg_chap are set, - * and the peer sends a Configure-Request with two - * authenticate-protocol requests, one for CHAP and one - * for UPAP, then we will reject the second request. - * Whether we end up doing CHAP or UPAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - - if (cishort == PPP_PAP) { - if (ho->neg_chap) { /* we've already accepted CHAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_SHORT) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n")); - orc = CONFNAK; /* NAK it and suggest CHAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->neg_upap = 1; -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort); - traceNdx = strlen(traceBuf); -#endif - break; - } - if (cishort == PPP_CHAP) { - if (ho->neg_upap) { /* we've already accepted PAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_CHAP) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n")); - orc = CONFNAK; /* NAK it and suggest PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - break; - } - GETCHAR(cichar, p); /* get digest type*/ - if (cichar != CHAP_DIGEST_MD5 -#if MSCHAP_SUPPORT - && cichar != CHAP_MICROSOFT -#endif - ) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar)); - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar); - traceNdx = strlen(traceBuf); -#endif - ho->chap_mdtype = cichar; /* save md type */ - ho->neg_chap = 1; - break; - } - - /* - * We don't recognize the protocol they're asking for. - * Nak it with something we're willing to do. - * (At this point we know ao->neg_upap || ao->neg_chap.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - if (ao->neg_chap) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort)); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - } else { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort)); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - } - break; - - case CI_QUALITY: - GETSHORT(cishort, p); - GETLONG(cilong, p); -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong); - traceNdx = strlen(traceBuf); -#endif - - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - /* - * Check the protocol and the reporting period. - * XXX When should we Nak this, and what with? - */ - if (cishort != PPP_LQR) { - orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakp); - PUTCHAR(CILEN_LQR, nakp); - PUTSHORT(PPP_LQR, nakp); - PUTLONG(ao->lqr_period, nakp); - break; - } - break; - - case CI_MAGICNUMBER: - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong); - traceNdx = strlen(traceBuf); -#endif - - /* - * He must have a different magic number. - */ - if (go->neg_magicnumber && - cilong == go->magicnumber) { - cilong = magic(); /* Don't put magic() inside macro! */ - orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(cilong, nakp); - break; - } - ho->neg_magicnumber = 1; - ho->magicnumber = cilong; - break; - - - case CI_PCOMPRESSION: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION"); - traceNdx = strlen(traceBuf); -#endif - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION"); - traceNdx = strlen(traceBuf); -#endif - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - - case CI_MRRU: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - case CI_SSNHF: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - case CI_EPDISC: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - default: -#if TRACELCP - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - } - - endswitch: -#if TRACELCP - if (traceNdx >= 80 - 32) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf)); - traceNdx = 0; - } -#endif - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) { /* but prior CI wasnt? */ - continue; /* Don't send this one */ - } - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree /* Getting fed up with sending NAKs? */ - && citype != CI_MAGICNUMBER) { - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) { /* Rejecting prior CI? */ - continue; /* Don't send this one */ - } - rc = CONFNAK; - } - } - if (orc == CONFREJ) { /* Reject this CI */ - rc = CONFREJ; - if (cip != rejp) { /* Need to move rejected CI? */ - BCOPY(cip, rejp, cilen); /* Move it */ - } - INCPTR(cilen, rejp); /* Update output pointer */ - } - } - - /* - * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakp. - * At present there are no cases where we want to ask the - * peer to negotiate an option. - */ - - switch (rc) { - case CONFACK: - *lenp = (int)(next - inp); - break; - case CONFNAK: - /* - * Copy the Nak'd options from the nak_buffer to the caller's buffer. - */ - *lenp = (int)(nakp - nak_buffer); - BCOPY(nak_buffer, inp, *lenp); - break; - case CONFREJ: - *lenp = (int)(rejp - inp); - break; - } - -#if TRACELCP > 0 - if (traceNdx > 0) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf)); - } -#endif - LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * lcp_up - LCP has come UP. - */ -static void -lcp_up(fsm *f) -{ - lcp_options *wo = &lcp_wantoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - - if (!go->neg_magicnumber) { - go->magicnumber = 0; - } - if (!ho->neg_magicnumber) { - ho->magicnumber = 0; - } - - /* - * Set our MTU to the smaller of the MTU we wanted and - * the MRU our peer wanted. If we negotiated an MRU, - * set our MRU to the larger of value we wanted and - * the value we got in the negotiation. - */ - ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), - (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl), - ho->neg_pcompression, ho->neg_accompression); - /* - * If the asyncmap hasn't been negotiated, we really should - * set the receive asyncmap to ffffffff, but we set it to 0 - * for backwards contemptibility. - */ - ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU), - (go->neg_asyncmap? go->asyncmap: 0x00000000), - go->neg_pcompression, go->neg_accompression); - - if (ho->neg_mru) { - peer_mru[f->unit] = ho->mru; - } - - lcp_echo_lowerup(f->unit); /* Enable echo messages */ - - link_established(f->unit); /* The link is up; authenticate now */ -} - - -/* - * lcp_down - LCP has gone DOWN. - * - * Alert other protocols. - */ -static void -lcp_down(fsm *f) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - - lcp_echo_lowerdown(f->unit); - - link_down(f->unit); - - ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0); - ppp_recv_config(f->unit, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0x00000000), - go->neg_pcompression, go->neg_accompression); - peer_mru[f->unit] = PPP_MRU; -} - - -/* - * lcp_starting - LCP needs the lower layer up. - */ -static void -lcp_starting(fsm *f) -{ - link_required(f->unit); /* lwip: currently does nothing */ -} - - -/* - * lcp_finished - LCP has finished with the lower layer. - */ -static void -lcp_finished(fsm *f) -{ - link_terminated(f->unit); /* we are finished with the link */ -} - - -#if PPP_ADDITIONAL_CALLBACKS -/* - * print_string - print a readable representation of a string using - * printer. - */ -static void -print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg) -{ - int c; - - printer(arg, """); - for (; len > 0; --len) { - c = *p++; - if (' ' <= c && c <= '~') { - if (c == '\' || c == '"') { - printer(arg, "\"); - } - printer(arg, "%c", c); - } else { - switch (c) { - case '\n': - printer(arg, "\n"); - break; - case '\r': - printer(arg, "\r"); - break; - case '\t': - printer(arg, "\t"); - break; - default: - printer(arg, "\%.3o", c); - } - } - } - printer(arg, """); -} - - -/* - * lcp_printpkt - print the contents of an LCP packet. - */ -static char *lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq" -}; - -static int -lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - u32_t cilong; - - if (plen < HEADERLEN) { - return 0; - } - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) { - return 0; - } - - if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) { - printer(arg, " %s", lcp_codenames[code-1]); - } else { - printer(arg, " code=0x%x", code); - } - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_MRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mru %d", cishort); - } - break; - case CI_ASYNCMAP: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "asyncmap 0x%lx", cilong); - } - break; - case CI_AUTHTYPE: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "auth "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_PAP: - printer(arg, "pap"); - break; - case PPP_CHAP: - printer(arg, "chap"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_QUALITY: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "quality "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_LQR: - printer(arg, "lqr"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_CALLBACK: - if (olen >= CILEN_CHAR) { - p += 2; - printer(arg, "callback "); - GETSHORT(cishort, p); - switch (cishort) { - case CBCP_OPT: - printer(arg, "CBCP"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_MAGICNUMBER: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "magic 0x%x", cilong); - } - break; - case CI_PCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "pcomp"); - } - break; - case CI_ACCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "accomp"); - } - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string((char*)p, len, printer, arg); - p += len; - len = 0; - } - break; - - case ECHOREQ: - case ECHOREP: - case DISCREQ: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - p += 4; - len -= 4; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return (int)(p - pstart); -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -/* - * Time to shut down the link because there is nothing out there. - */ -static void -LcpLinkFailure (fsm *f) -{ - if (f->state == LS_OPENED) { - LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending)); - LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n")); - lcp_close(f->unit, "Peer not responding"); - } -} - -/* - * Timer expired for the LCP echo requests from this process. - */ -static void -LcpEchoCheck (fsm *f) -{ - LcpSendEchoRequest (f); - - /* - * Start the timer for the next interval. - */ - LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0); - - TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); - lcp_echo_timer_running = 1; -} - -/* - * LcpEchoTimeout - Timer expired on the LCP echo - */ -static void -LcpEchoTimeout (void *arg) -{ - if (lcp_echo_timer_running != 0) { - lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) arg); - } -} - -/* - * LcpEchoReply - LCP has received a reply to the echo - */ -static void -lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len) -{ - u32_t magic; - - LWIP_UNUSED_ARG(id); - - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len)); - return; - } - GETLONG(magic, inp); - if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { - LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n")); - return; - } - - /* Reset the number of outstanding echo frames */ - lcp_echos_pending = 0; -} - -/* - * LcpSendEchoRequest - Send an echo request frame to the peer - */ -static void -LcpSendEchoRequest (fsm *f) -{ - u32_t lcp_magic; - u_char pkt[4], *pktp; - - /* - * Detect the failure of the peer at this point. - */ - if (lcp_echo_fails != 0) { - if (lcp_echos_pending >= lcp_echo_fails) { - LcpLinkFailure(f); - lcp_echos_pending = 0; - } - } - - /* - * Make and send the echo request frame. - */ - if (f->state == LS_OPENED) { - lcp_magic = lcp_gotoptions[f->unit].magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); - ++lcp_echos_pending; - } -} - -/* - * lcp_echo_lowerup - Start the timer for the LCP frame - */ - -static void -lcp_echo_lowerup (int unit) -{ - fsm *f = &lcp_fsm[unit]; - - /* Clear the parameters for generating echo frames */ - lcp_echos_pending = 0; - lcp_echo_number = 0; - lcp_echo_timer_running = 0; - - /* If a timeout interval is specified then start the timer */ - if (lcp_echo_interval != 0) { - LcpEchoCheck (f); - } -} - -/* - * lcp_echo_lowerdown - Stop the timer for the LCP frame - */ - -static void -lcp_echo_lowerdown (int unit) -{ - fsm *f = &lcp_fsm[unit]; - - if (lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - lcp_echo_timer_running = 0; - } -} - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/lcp.h b/external/badvpn_dns/lwip/src/netif/ppp/lcp.h deleted file mode 100644 index b9201ee..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/lcp.h +++ /dev/null @@ -1,151 +0,0 @@ -/***************************************************************************** -* lcp.h - Network Link Control Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-11-05 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -/* - * lcp.h - Link Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: lcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ - */ - -#ifndef LCP_H -#define LCP_H -/* - * Options. - */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGICNUMBER 5 /* Magic Number */ -#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ -#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ -#define CI_CALLBACK 13 /* callback */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ - -/* - * LCP-specific packet types (code numbers). - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - u_int passive : 1; /* Don't die if we don't get a response */ - u_int silent : 1; /* Wait for the other end to start first */ - u_int restart : 1; /* Restart vs. exit after close */ - u_int neg_mru : 1; /* Negotiate the MRU? */ - u_int neg_asyncmap : 1; /* Negotiate the async map? */ - u_int neg_upap : 1; /* Ask for UPAP authentication? */ - u_int neg_chap : 1; /* Ask for CHAP authentication? */ - u_int neg_magicnumber : 1; /* Ask for magic number? */ - u_int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ - u_int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ - u_int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ - u_int neg_cbcp : 1; /* Negotiate use of CBCP */ -#ifdef PPP_MULTILINK - u_int neg_mrru : 1; /* Negotiate multilink MRRU */ - u_int neg_ssnhf : 1; /* Negotiate short sequence numbers */ - u_int neg_endpoint : 1; /* Negotiate endpoint discriminator */ -#endif - u_short mru; /* Value of MRU */ -#ifdef PPP_MULTILINK - u_short mrru; /* Value of MRRU, and multilink enable */ -#endif - u_char chap_mdtype; /* which MD type (hashing algorithm) */ - u32_t asyncmap; /* Value of async map */ - u32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ - u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#ifdef PPP_MULTILINK - struct epdisc endpoint; /* endpoint discriminator */ -#endif -} lcp_options; - -/* - * Values for phase from BSD pppd.h based on RFC 1661. - */ -typedef enum { - PHASE_DEAD = 0, - PHASE_INITIALIZE, - PHASE_ESTABLISH, - PHASE_AUTHENTICATE, - PHASE_CALLBACK, - PHASE_NETWORK, - PHASE_TERMINATE -} LinkPhase; - - - -extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ -extern lcp_options lcp_wantoptions[]; -extern lcp_options lcp_gotoptions[]; -extern lcp_options lcp_allowoptions[]; -extern lcp_options lcp_hisoptions[]; -extern ext_accm xmit_accm[]; - - -void lcp_init (int); -void lcp_open (int); -void lcp_close (int, char *); -void lcp_lowerup (int); -void lcp_lowerdown(int); -void lcp_sprotrej (int, u_char *, int); /* send protocol reject */ - -extern struct protent lcp_protent; - -/* Default number of times we receive our magic number from the peer - before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 10 - -#endif /* LCP_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/magic.c b/external/badvpn_dns/lwip/src/netif/ppp/magic.c deleted file mode 100644 index 3732a42..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/magic.c +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* magic.c - Network Random Number Generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original based on BSD magic.c. -*****************************************************************************/ -/* - * magic.c - PPP Magic Number routines. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT - -#include "ppp_impl.h" -#include "randm.h" -#include "magic.h" - - -/* - * magicInit - Initialize the magic number generator. - * - * Since we use another random number generator that has its own - * initialization, we do nothing here. - */ -void magicInit() -{ - return; -} - -/* - * magic - Returns the next magic number. - */ -u32_t magic() -{ - return avRandom(); -} - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/magic.h b/external/badvpn_dns/lwip/src/netif/ppp/magic.h deleted file mode 100644 index eba70d2..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/magic.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** -* magic.h - Network Random Number Generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -/* - * magic.h - PPP Magic Number definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id: magic.h,v 1.3 2010/01/18 20:49:43 goldsimon Exp $ - */ - -#ifndef MAGIC_H -#define MAGIC_H - -/* Initialize the magic number generator */ -void magicInit(void); - -/* Returns the next magic number */ -u32_t magic(void); - -#endif /* MAGIC_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/md5.c b/external/badvpn_dns/lwip/src/netif/ppp/md5.c deleted file mode 100644 index dc3cc75..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/md5.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - *********************************************************************** - ** md5.c -- the source code for MD5 routines ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if CHAP_SUPPORT || MD5_SUPPORT - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "md5.h" - -#include <string.h> - -/* - *********************************************************************** - ** Message-digest routines: ** - ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5Init ** - ** (2) Call MD5Update on mdContext and M ** - ** (3) Call MD5Final on mdContext ** - ** The message digest is now in mdContext->digest[0...15] ** - *********************************************************************** - */ - -/* forward declaration */ -static void Transform (u32_t *buf, u32_t *in); - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G, H and I are basic MD5 functions */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#ifdef __STDC__ -#define UL(x) x##UL -#else -#ifdef WIN32 -#define UL(x) x##UL -#else -#define UL(x) x -#endif -#endif - -/* The routine MD5Init initializes the message-digest context - mdContext. All fields are set to zero. - */ -void -MD5Init (MD5_CTX *mdContext) -{ - mdContext->i[0] = mdContext->i[1] = (u32_t)0; - - /* Load magic initialization constants. */ - mdContext->buf[0] = (u32_t)0x67452301UL; - mdContext->buf[1] = (u32_t)0xefcdab89UL; - mdContext->buf[2] = (u32_t)0x98badcfeUL; - mdContext->buf[3] = (u32_t)0x10325476UL; -} - -/* The routine MD5Update updates the message-digest context to - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ -void -MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) -{ - u32_t in[16]; - int mdi; - unsigned int i, ii; - -#if 0 - PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf)); - PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf)); -#endif - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) { - mdContext->i[1]++; - } - mdContext->i[0] += ((u32_t)inLen << 3); - mdContext->i[1] += ((u32_t)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) { - in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | - (((u32_t)mdContext->in[ii+2]) << 16) | - (((u32_t)mdContext->in[ii+1]) << 8) | - ((u32_t)mdContext->in[ii]); - } - Transform (mdContext->buf, in); - mdi = 0; - } - } -} - -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ -void -MD5Final (unsigned char hash[], MD5_CTX *mdContext) -{ - u32_t in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) { - in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | - (((u32_t)mdContext->in[ii+2]) << 16) | - (((u32_t)mdContext->in[ii+1]) << 8) | - ((u32_t)mdContext->in[ii]); - } - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } - SMEMCPY(hash, mdContext->digest, 16); -} - -/* Basic MD5 step. Transforms buf based on in. - */ -static void -Transform (u32_t *buf, u32_t *in) -{ - u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ - FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ - FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ - FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ - FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ - FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ - FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ - GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ - GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ - GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ - GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ - GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ - GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ - HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ - HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ - HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ - HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ - HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ - HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ - II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ - II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ - II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ - II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ - II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ - II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ - II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ - II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ - II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ - II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ - II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ - II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ - II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ - II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ - II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif /* CHAP_SUPPORT || MD5_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/md5.h b/external/badvpn_dns/lwip/src/netif/ppp/md5.h deleted file mode 100644 index e129533..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/md5.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#ifndef MD5_H -#define MD5_H - -/* Data structure for MD5 (Message-Digest) computation */ -typedef struct { - u32_t i[2]; /* number of _bits_ handled mod 2^64 */ - u32_t buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ -} MD5_CTX; - -void MD5Init ( MD5_CTX *mdContext); -void MD5Update( MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); -void MD5Final ( unsigned char hash[], MD5_CTX *mdContext); - -#endif /* MD5_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/pap.c b/external/badvpn_dns/lwip/src/netif/ppp/pap.c deleted file mode 100644 index 5fb9f88..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/pap.c +++ /dev/null @@ -1,628 +0,0 @@ -/***************************************************************************** -* pap.c - Network Password Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-12 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original. -*****************************************************************************/ -/* - * upap.c - User/Password Authentication Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "auth.h" -#include "pap.h" - -#include <string.h> - -#if 0 /* UNUSED */ -static bool hide_password = 1; - -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", 1 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", 0 }, - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP" }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs" }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication" }, - { NULL } -}; -#endif - -/* - * Protocol entry points. - */ -static void upap_init (int); -static void upap_lowerup (int); -static void upap_lowerdown (int); -static void upap_input (int, u_char *, int); -static void upap_protrej (int); -#if PPP_ADDITIONAL_CALLBACKS -static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *); -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, -#if PPP_ADDITIONAL_CALLBACKS - upap_printpkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "PAP", -#if PPP_ADDITIONAL_CALLBACKS - NULL, - NULL, - NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ - -static void upap_timeout (void *); -static void upap_reqtimeout(void *); -static void upap_rauthreq (upap_state *, u_char *, u_char, int); -static void upap_rauthack (upap_state *, u_char *, int, int); -static void upap_rauthnak (upap_state *, u_char *, int, int); -static void upap_sauthreq (upap_state *); -static void upap_sresp (upap_state *, u_char, u_char, char *, int); - - -/* - * upap_init - Initialize a UPAP unit. - */ -static void -upap_init(int unit) -{ - upap_state *u = &upap[unit]; - - UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit)); - u->us_unit = unit; - u->us_user = NULL; - u->us_userlen = 0; - u->us_passwd = NULL; - u->us_passwdlen = 0; - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; - u->us_id = 0; - u->us_timeouttime = UPAP_DEFTIMEOUT; - u->us_maxtransmits = 10; - u->us_reqtimeout = UPAP_DEFREQTIME; -} - -/* - * upap_authwithpeer - Authenticate us with our peer (start client). - * - * Set new state and send authenticate's. - */ -void -upap_authwithpeer(int unit, char *user, char *password) -{ - upap_state *u = &upap[unit]; - - UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n", - unit, user, password, u->us_clientstate)); - - /* Save the username and password we're given */ - u->us_user = user; - u->us_userlen = (int)strlen(user); - u->us_passwd = password; - u->us_passwdlen = (int)strlen(password); - - u->us_transmits = 0; - - /* Lower layer up yet? */ - if (u->us_clientstate == UPAPCS_INITIAL || - u->us_clientstate == UPAPCS_PENDING) { - u->us_clientstate = UPAPCS_PENDING; - return; - } - - upap_sauthreq(u); /* Start protocol */ -} - - -/* - * upap_authpeer - Authenticate our peer (start server). - * - * Set new state. - */ -void -upap_authpeer(int unit) -{ - upap_state *u = &upap[unit]; - - /* Lower layer up yet? */ - if (u->us_serverstate == UPAPSS_INITIAL || - u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_PENDING; - return; - } - - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) { - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); - } -} - -/* - * upap_timeout - Retransmission timer for sending auth-reqs expired. - */ -static void -upap_timeout(void *arg) -{ - upap_state *u = (upap_state *) arg; - - UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n", - u->us_unit, u->us_timeouttime, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { - UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n")); - return; - } - - if (u->us_transmits >= u->us_maxtransmits) { - /* give up in disgust */ - UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n")); - u->us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(u->us_unit, PPP_PAP); - return; - } - - upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/ -} - - -/* - * upap_reqtimeout - Give up waiting for the peer to send an auth-req. - */ -static void -upap_reqtimeout(void *arg) -{ - upap_state *u = (upap_state *) arg; - - if (u->us_serverstate != UPAPSS_LISTEN) { - return; /* huh?? */ - } - - auth_peer_fail(u->us_unit, PPP_PAP); - u->us_serverstate = UPAPSS_BADAUTH; -} - - -/* - * upap_lowerup - The lower layer is up. - * - * Start authenticating if pending. - */ -static void -upap_lowerup(int unit) -{ - upap_state *u = &upap[unit]; - - UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate)); - - if (u->us_clientstate == UPAPCS_INITIAL) { - u->us_clientstate = UPAPCS_CLOSED; - } else if (u->us_clientstate == UPAPCS_PENDING) { - upap_sauthreq(u); /* send an auth-request */ - /* now client state is UPAPCS__AUTHREQ */ - } - - if (u->us_serverstate == UPAPSS_INITIAL) { - u->us_serverstate = UPAPSS_CLOSED; - } else if (u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) { - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); - } - } -} - - -/* - * upap_lowerdown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -upap_lowerdown(int unit) -{ - upap_state *u = &upap[unit]; - - UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate)); - - if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */ - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ - } - if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) { - UNTIMEOUT(upap_reqtimeout, u); - } - - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; -} - - -/* - * upap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. In any case, pretend lower layer went down. - */ -static void -upap_protrej(int unit) -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_AUTHREQ) { - UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n")); - auth_withpeer_fail(unit, PPP_PAP); - } - if (u->us_serverstate == UPAPSS_LISTEN) { - UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n")); - auth_peer_fail(unit, PPP_PAP); - } - upap_lowerdown(unit); -} - - -/* - * upap_input - Input UPAP packet. - */ -static void -upap_input(int unit, u_char *inpacket, int l) -{ - upap_state *u = &upap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < (int)UPAP_HEADERLEN) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < (int)UPAP_HEADERLEN) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n")); - return; - } - if (len > l) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n")); - return; - } - len -= UPAP_HEADERLEN; - - /* - * Action depends on code. - */ - switch (code) { - case UPAP_AUTHREQ: - upap_rauthreq(u, inp, id, len); - break; - - case UPAP_AUTHACK: - upap_rauthack(u, inp, id, len); - break; - - case UPAP_AUTHNAK: - upap_rauthnak(u, inp, id, len); - break; - - default: /* XXX Need code reject */ - UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len)); - break; - } -} - - -/* - * upap_rauth - Receive Authenticate. - */ -static void -upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len) -{ - u_char ruserlen, rpasswdlen; - char *ruser, *rpasswd; - u_char retcode; - char *msg; - int msglen; - - UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id)); - - if (u->us_serverstate < UPAPSS_LISTEN) { - return; - } - - /* - * If we receive a duplicate authenticate-request, we are - * supposed to return the same status as for the first request. - */ - if (u->us_serverstate == UPAPSS_OPEN) { - upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ - return; - } - if (u->us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ - return; - } - - /* - * Parse user/passwd. - */ - if (len < (int)sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen); - /* lwip: currently retcode is always UPAP_AUTHACK */ - BZERO(rpasswd, rpasswdlen); - - upap_sresp(u, retcode, id, msg, msglen); - - if (retcode == UPAP_AUTHACK) { - u->us_serverstate = UPAPSS_OPEN; - auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); - } else { - u->us_serverstate = UPAPSS_BADAUTH; - auth_peer_fail(u->us_unit, PPP_PAP); - } - - if (u->us_reqtimeout > 0) { - UNTIMEOUT(upap_reqtimeout, u); - } -} - - -/* - * upap_rauthack - Receive Authenticate-Ack. - */ -static void -upap_rauthack(upap_state *u, u_char *inp, int id, int len) -{ - u_char msglen; - char *msg; - - LWIP_UNUSED_ARG(id); - - UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ - UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n")); - return; - } - - /* - * Parse message. - */ - if (len < (int)sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ - u->us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(u->us_unit, PPP_PAP); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nak. - */ -static void -upap_rauthnak(upap_state *u, u_char *inp, int id, int len) -{ - u_char msglen; - char *msg; - - LWIP_UNUSED_ARG(id); - - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ - return; - } - - /* - * Parse message. - */ - if (len < sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n")); - } else { - GETCHAR(msglen, inp); - if(msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_BADAUTH; - - UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n")); - auth_withpeer_fail(u->us_unit, PPP_PAP); -} - - -/* - * upap_sauthreq - Send an Authenticate-Request. - */ -static void -upap_sauthreq(upap_state *u) -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) - + u->us_userlen + u->us_passwdlen; - outp = outpacket_buf[u->us_unit]; - - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++u->us_id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(u->us_userlen, outp); - BCOPY(u->us_user, outp, u->us_userlen); - INCPTR(u->us_userlen, outp); - PUTCHAR(u->us_passwdlen, outp); - BCOPY(u->us_passwd, outp, u->us_passwdlen); - - pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); - - UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id)); - - TIMEOUT(upap_timeout, u, u->us_timeouttime); - ++u->us_transmits; - u->us_clientstate = UPAPCS_AUTHREQ; -} - - -/* - * upap_sresp - Send a response (ack or nak). - */ -static void -upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen) -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - outp = outpacket_buf[u->us_unit]; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - BCOPY(msg, outp, msglen); - pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); - - UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate)); -} - -#if PPP_ADDITIONAL_CALLBACKS -static char *upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static int upap_printpkt( - u_char *p, - int plen, - void (*printer) (void *, char *, ...), - void *arg -) -{ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(plen); - LWIP_UNUSED_ARG(printer); - LWIP_UNUSED_ARG(arg); - return 0; -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* PAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/pap.h b/external/badvpn_dns/lwip/src/netif/ppp/pap.h deleted file mode 100644 index c99a204..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/pap.h +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************** -* pap.h - PPP Password Authentication Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-12-04 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef PAP_H -#define PAP_H - -#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) - - -/* - * UPAP codes. - */ -#define UPAP_AUTHREQ 1 /* Authenticate-Request */ -#define UPAP_AUTHACK 2 /* Authenticate-Ack */ -#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ - -/* - * Each interface is described by upap structure. - */ -typedef struct upap_state { - int us_unit; /* Interface unit number */ - const char *us_user; /* User */ - int us_userlen; /* User length */ - const char *us_passwd; /* Password */ - int us_passwdlen; /* Password length */ - int us_clientstate; /* Client state */ - int us_serverstate; /* Server state */ - u_char us_id; /* Current id */ - int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ - int us_transmits; /* Number of auth-reqs sent */ - int us_maxtransmits; /* Maximum number of auth-reqs to send */ - int us_reqtimeout; /* Time to wait for auth-req from peer */ -} upap_state; - -/* - * Client states. - */ -#define UPAPCS_INITIAL 0 /* Connection down */ -#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ -#define UPAPCS_OPEN 4 /* We've received an Ack */ -#define UPAPCS_BADAUTH 5 /* We've received a Nak */ - -/* - * Server states. - */ -#define UPAPSS_INITIAL 0 /* Connection down */ -#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ -#define UPAPSS_OPEN 4 /* We've sent an Ack */ -#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ - - -extern upap_state upap[]; - -void upap_authwithpeer (int, char *, char *); -void upap_authpeer (int); - -extern struct protent pap_protent; - -#endif /* PAP_SUPPORT */ - -#endif /* PAP_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ppp.c b/external/badvpn_dns/lwip/src/netif/ppp/ppp.c deleted file mode 100644 index 2a34657..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ppp.c +++ /dev/null @@ -1,2052 +0,0 @@ -/***************************************************************************** -* ppp.c - Network Point to Point Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-11-05 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original. -*****************************************************************************/ - -/* - * ppp_defs.h - PPP definitions. - * - * if_pppvar.h - private structures and declarations for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "lwip/ip.h" /* for ip_input() */ - -#include "pppdebug.h" - -#include "randm.h" -#include "fsm.h" -#if PAP_SUPPORT -#include "pap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "chap.h" -#endif /* CHAP_SUPPORT */ -#include "ipcp.h" -#include "lcp.h" -#include "magic.h" -#include "auth.h" -#if VJ_SUPPORT -#include "vj.h" -#endif /* VJ_SUPPORT */ -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ - -#include "lwip/tcpip.h" -#include "lwip/api.h" -#include "lwip/snmp.h" - -#include <string.h> - -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ - -/** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback(). - * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1. - * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). - */ -#ifndef PPP_INPROC_MULTITHREADED -#define PPP_INPROC_MULTITHREADED (NO_SYS==0) -#endif - -/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. - * Default is 0: call pppos_input() for received raw characters, charcater - * reception is up to the port */ -#ifndef PPP_INPROC_OWNTHREAD -#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED -#endif - -#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED - #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" -#endif - -/* - * The basic PPP frame. - */ -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -typedef enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -} PPPDevStates; - -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) - -/************************/ -/*** LOCAL DATA TYPES ***/ -/************************/ - -/** RX buffer size: this may be configured smaller! */ -#ifndef PPPOS_RX_BUFSIZE -#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) -#endif - -typedef struct PPPControlRx_s { - /** unit number / ppp descriptor */ - int pd; - /** the rx file descriptor */ - sio_fd_t fd; - /** receive buffer - encoded data is stored here */ -#if PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPP_INPROC_OWNTHREAD */ - - /* The input packet. */ - struct pbuf *inHead, *inTail; - -#if PPPOS_SUPPORT - u16_t inProtocol; /* The input protocol code. */ - u16_t inFCS; /* Input Frame Check Sequence value. */ -#endif /* PPPOS_SUPPORT */ - PPPDevStates inState; /* The input process state. */ - char inEscaped; /* Escape next character. */ - ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ -} PPPControlRx; - -/* - * PPP interface control block. - */ -typedef struct PPPControl_s { - PPPControlRx rx; - char openFlag; /* True when in use. */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int errCode; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long lastXMit; /* Time of last transmission. */ - ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vjEnabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vjComp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - struct netif netif; - - struct ppp_addrs addrs; - - void (*linkStatusCB)(void *ctx, int errCode, void *arg); - void *linkStatusCtx; - -} PPPControl; - - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP procotol, e.g. PPP_IP */ - enum NPmode mode; -}; - - - -/***********************************/ -/*** LOCAL FUNCTION DECLARATIONS ***/ -/***********************************/ -#if PPPOS_SUPPORT -#if PPP_INPROC_OWNTHREAD -static void pppInputThread(void *arg); -#endif /* PPP_INPROC_OWNTHREAD */ -static void pppDrop(PPPControlRx *pcrx); -static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); -static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); -#endif /* PPPOS_SUPPORT */ - - -/******************************/ -/*** PUBLIC DATA STRUCTURES ***/ -/******************************/ -static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -struct protent *ppp_protocols[] = { - &lcp_protent, -#if PAP_SUPPORT - &pap_protent, -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - &chap_protent, -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT - &cbcp_protent, -#endif /* CBCP_SUPPORT */ - &ipcp_protent, -#if CCP_SUPPORT - &ccp_protent, -#endif /* CCP_SUPPORT */ - NULL -}; - - -/* - * Buffers for outgoing packets. This must be accessed only from the appropriate - * PPP task so that it doesn't need to be protected to avoid collisions. - */ -u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; - - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ - -#if PPPOS_SUPPORT -/* - * FCS lookup table as calculated by genfcstab. - * @todo: smaller, slower implementation for lower memory footprint? - */ -static const u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -/* PPP's Asynchronous-Control-Character-Map. The mask array is used - * to select the specific bit for a character. */ -static u_char pppACCMMask[] = { - 0x01, - 0x02, - 0x04, - 0x08, - 0x10, - 0x20, - 0x40, - 0x80 -}; - -#if PPP_INPROC_OWNTHREAD -/** Wake up the task blocked in reading from serial line (if any) */ -static void -pppRecvWakeup(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); - if (pppControl[pd].openFlag != 0) { - sio_read_abort(pppControl[pd].fd); - } -} -#endif /* PPP_INPROC_OWNTHREAD */ -#endif /* PPPOS_SUPPORT */ - -void -pppLinkTerminated(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd)); - -#if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT - PPPControl* pc; -#if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPP_INPROC_OWNTHREAD */ - pc = &pppControl[pd]; - - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - } - - pc->openFlag = 0;/**/ -#endif /* PPPOS_SUPPORT */ - } - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n")); -} - -void -pppLinkDown(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd)); - -#if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ - } -} - -/** Initiate LCP open request */ -static void -pppStart(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); - lcp_lowerup(pd); - lcp_open(pd); /* Start protocol */ - PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); -} - -/** LCP close request */ -static void -pppStop(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd)); - lcp_close(pd, "User request"); -} - -/** Called when carrier/link is lost */ -static void -pppHup(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd)); - lcp_lowerdown(pd); - link_terminated(pd); -} - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* Initialize the PPP subsystem. */ - -struct ppp_settings ppp_settings; - -void -pppInit(void) -{ - struct protent *protp; - int i, j; - - memset(&ppp_settings, 0, sizeof(ppp_settings)); - ppp_settings.usepeerdns = 1; - pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); - - magicInit(); - - for (i = 0; i < NUM_PPP; i++) { - /* Initialize each protocol to the standard option set. */ - for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) { - (*protp->init)(i); - } - } -} - -void -pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) -{ - switch(authType) { - case PPPAUTHTYPE_NONE: - default: -#ifdef LWIP_PPP_STRICT_PAP_REJECT - ppp_settings.refuse_pap = 1; -#else /* LWIP_PPP_STRICT_PAP_REJECT */ - /* some providers request pap and accept an empty login/pw */ - ppp_settings.refuse_pap = 0; -#endif /* LWIP_PPP_STRICT_PAP_REJECT */ - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_ANY: - /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 0; - break; - - case PPPAUTHTYPE_PAP: - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_CHAP: - ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 0; - break; - } - - if(user) { - strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); - ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; - } else { - ppp_settings.user[0] = '\0'; - } - - if(passwd) { - strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); - ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; - } else { - ppp_settings.passwd[0] = '\0'; - } -} - -#if PPPOS_SUPPORT -/** Open a new PPP connection using the given I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. If this port - * connects to a modem, the modem connection must be - * established before calling this. - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. - * - * pppOpen() is directly defined to this function. - */ -int -pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ - PPPControl *pc; - int pd; - - if (linkStatusCB == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - return PPPERR_PARAM; - } - - /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); - - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &pppControl[pd]; - /* input pbuf left over from last session? */ - pppFreeCurrentInputPacket(&pc->rx); - /* @todo: is this correct or do I overwrite something? */ - memset(pc, 0, sizeof(PPPControl)); - pc->rx.pd = pd; - pc->rx.fd = fd; - - pc->openFlag = 1; - pc->fd = fd; - -#if VJ_SUPPORT - vj_compress_init(&pc->vjComp); -#endif /* VJ_SUPPORT */ - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ - pc->outACCM[15] = 0x60; - - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; - - /* - * Start the connection and handle incoming events (packet or timeout). - */ - PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd)); - pppStart(pd); -#if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); -#endif /* PPP_INPROC_OWNTHREAD */ - } - - return pd; -} -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -static void pppOverEthernetLinkStatusCB(int pd, int up); - -void -pppOverEthernetClose(int pd) -{ - PPPControl* pc = &pppControl[pd]; - - /* *TJL* There's no lcp_deinit */ - lcp_close(pd, NULL); - - pppoe_destroy(&pc->netif); -} - -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ - PPPControl *pc; - int pd; - - LWIP_UNUSED_ARG(service_name); - LWIP_UNUSED_ARG(concentrator_name); - - if (linkStatusCB == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - return PPPERR_PARAM; - } - - /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &pppControl[pd]; - memset(pc, 0, sizeof(PPPControl)); - pc->openFlag = 1; - pc->ethif = ethif; - - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; - - lcp_wantoptions[pd].mru = PPPOE_MAXMTU; - lcp_wantoptions[pd].neg_asyncmap = 0; - lcp_wantoptions[pd].neg_pcompression = 0; - lcp_wantoptions[pd].neg_accompression = 0; - - lcp_allowoptions[pd].mru = PPPOE_MAXMTU; - lcp_allowoptions[pd].neg_asyncmap = 0; - lcp_allowoptions[pd].neg_pcompression = 0; - lcp_allowoptions[pd].neg_accompression = 0; - - if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { - pc->openFlag = 0; - return PPPERR_OPEN; - } - - pppoe_connect(pc->pppoe_sc); - } - - return pd; -} -#endif /* PPPOE_SUPPORT */ - - -/* Close a PPP connection and release the descriptor. - * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. */ -int -pppClose(int pd) -{ - PPPControl *pc = &pppControl[pd]; - int st = 0; - - PPPDEBUG(LOG_DEBUG, ("pppClose() called\n")); - - /* Disconnect */ -#if PPPOE_SUPPORT - if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; - /* This will leave us at PHASE_DEAD. */ - pppStop(pd); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; - /* This will leave us at PHASE_DEAD. */ - pppStop(pd); -#if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPP_INPROC_OWNTHREAD */ -#endif /* PPPOS_SUPPORT */ - } - - return st; -} - -/* This function is called when carrier is lost on the PPP channel. */ -void -pppSigHUP(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); - pppHup(pd); -} - -#if PPPOS_SUPPORT -static void -nPut(PPPControl *pc, struct pbuf *nb) -{ - struct pbuf *b; - int c; - - for(b = nb; b != NULL; b = b->next) { - if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { - PPPDEBUG(LOG_WARNING, - ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); - LINK_STATS_INC(link.err); - pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ - snmp_inc_ifoutdiscards(&pc->netif); - pbuf_free(nb); - return; - } - } - - snmp_add_ifoutoctets(&pc->netif, nb->tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - pbuf_free(nb); - LINK_STATS_INC(link.xmit); -} - -/* - * pppAppend - append given character to end of given pbuf. If outACCM - * is not NULL and the character needs to be escaped, do so. - * If pbuf is full, append another. - * Return the current pbuf. - */ -static struct pbuf * -pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) -{ - struct pbuf *tb = nb; - - /* Make sure there is room for the character and an escape code. - * Sure we don't quite fill the buffer if the character doesn't - * get escaped but is one character worth complicating this? */ - /* Note: We assume no packet header. */ - if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { - tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (tb) { - nb->next = tb; - } else { - LINK_STATS_INC(link.memerr); - } - nb = tb; - } - - if (nb) { - if (outACCM && ESCAPE_P(*outACCM, c)) { - *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; - *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; - } else { - *((u_char*)nb->payload + nb->len++) = c; - } - } - - return tb; -} -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -static err_t -pppifOutputOverEthernet(int pd, struct pbuf *p) -{ - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - u_short protocol = PPP_IP; - int i=0; - u16_t tot_len; - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return ERR_MEM; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - if (!pc->pcomp || protocol > 0xFF) { - *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; - } - *((u_char*)pb->payload + i) = protocol & 0xFF; - - pbuf_chain(pb, p); - tot_len = pb->tot_len; - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} -#endif /* PPPOE_SUPPORT */ - -/* Send a packet on the given connection. */ -static err_t -pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) -{ - int pd = (int)(size_t)netif->state; - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_short protocol = PPP_IP; - u_int fcsOut = PPP_INITFCS; - struct pbuf *headMB = NULL, *tailMB = NULL, *p; - u_char c; -#endif /* PPPOS_SUPPORT */ - - LWIP_UNUSED_ARG(ipaddr); - - /* Validate parameters. */ - /* We let any protocol value go through - it can't hurt us - * and the peer will just drop it if it's not accepting it. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", - pd, PPP_IP, pb)); - LINK_STATS_INC(link.opterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_ARG; - } - - /* Check that the link is up. */ - if (lcp_phase[pd] == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); - LINK_STATS_INC(link.rterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_RTE; - } - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppifOutputOverEthernet(pd, pb); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - /* Grab an output buffer. */ - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - -#if VJ_SUPPORT - /* - * Attempt Van Jacobson header compression if VJ is configured and - * this is an IP packet. - */ - if (protocol == PPP_IP && pc->vjEnabled) { - switch (vj_compress_tcp(&pc->vjComp, pb)) { - case TYPE_IP: - /* No change... - protocol = PPP_IP_PROTOCOL; */ - break; - case TYPE_COMPRESSED_TCP: - protocol = PPP_VJC_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - protocol = PPP_VJC_UNCOMP; - break; - default: - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); - LINK_STATS_INC(link.proterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - pbuf_free(headMB); - return ERR_VAL; - } - } -#endif /* VJ_SUPPORT */ - - tailMB = headMB; - - /* Build the PPP header. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - - pc->lastXMit = sys_jiffies(); - if (!pc->accomp) { - fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); - tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); - fcsOut = PPP_FCS(fcsOut, PPP_UI); - tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); - } - if (!pc->pcomp || protocol > 0xFF) { - c = (protocol >> 8) & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - c = protocol & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - - /* Load packet. */ - for(p = pb; p; p = p->next) { - int n; - u_char *sPtr; - - sPtr = (u_char*)p->payload; - n = p->len; - while (n-- > 0) { - c = *sPtr++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", - pd, protocol)); - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - - /* Send it. */ - PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); - - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return ERR_OK; -} - -/* Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. */ -int -pppIOCtl(int pd, int cmd, void *arg) -{ - PPPControl *pc = &pppControl[pd]; - int st = 0; - - if (pd < 0 || pd >= NUM_PPP) { - st = PPPERR_PARAM; - } else { - switch(cmd) { - case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ - if (arg) { - *(int *)arg = (int)(pc->if_up); - } else { - st = PPPERR_PARAM; - } - break; - case PPPCTLS_ERRCODE: /* Set the PPP error code. */ - if (arg) { - pc->errCode = *(int *)arg; - } else { - st = PPPERR_PARAM; - } - break; - case PPPCTLG_ERRCODE: /* Get the PPP error code. */ - if (arg) { - *(int *)arg = (int)(pc->errCode); - } else { - st = PPPERR_PARAM; - } - break; -#if PPPOS_SUPPORT - case PPPCTLG_FD: /* Get the fd associated with the ppp */ - if (arg) { - *(sio_fd_t *)arg = pc->fd; - } else { - st = PPPERR_PARAM; - } - break; -#endif /* PPPOS_SUPPORT */ - default: - st = PPPERR_PARAM; - break; - } - } - - return st; -} - -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -u_short -pppMTU(int pd) -{ - PPPControl *pc = &pppControl[pd]; - u_short st; - - /* Validate parameters. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - } else { - st = pc->mtu; - } - - return st; -} - -#if PPPOE_SUPPORT -int -pppWriteOverEthernet(int pd, const u_char *s, int n) -{ - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - - /* skip address & flags */ - s += 2; - n -= 2; - - LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - MEMCPY(pb->payload, s, n); - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, (u16_t)n); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return PPPERR_NONE; -} -#endif /* PPPOE_SUPPORT */ - -/* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written - * -1 Failed to write to device - */ -int -pppWrite(int pd, const u_char *s, int n) -{ - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_char c; - u_int fcsOut; - struct pbuf *headMB, *tailMB; -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppWriteOverEthernet(pd, s, n); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - tailMB = headMB; - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - pc->lastXMit = sys_jiffies(); - - fcsOut = PPP_INITFCS; - /* Load output buffer. */ - while (n-- > 0) { - c = *s++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. - * Otherwise send it. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); - /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return PPPERR_NONE; -} - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -ppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp) -{ - PPPControl *pc = &pppControl[unit]; - int i; - - pc->mtu = mtu; - pc->pcomp = pcomp; - pc->accomp = accomp; - - /* Load the ACCM bits for the 32 control codes. */ - for (i = 0; i < 32/8; i++) { - pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF); - } - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", - unit, - pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); -} - - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(int unit, ext_accm *accm) -{ - SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); - PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", - unit, - pppControl[unit].outACCM[0], - pppControl[unit].outACCM[1], - pppControl[unit].outACCM[2], - pppControl[unit].outACCM[3])); -} - - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp) -{ - PPPControl *pc = &pppControl[unit]; - int i; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(accomp); - LWIP_UNUSED_ARG(pcomp); - LWIP_UNUSED_ARG(mru); - - /* Load the ACCM bits for the 32 control codes. */ - SYS_ARCH_PROTECT(lev); - for (i = 0; i < 32 / 8; i++) { - /* @todo: does this work? ext_accm has been modified from pppd! */ - pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8)); - } - SYS_ARCH_UNPROTECT(lev); - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", - unit, - pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); -} - -#if 0 -/* - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. Returns 1 if the method and parameters - * are OK, 0 if the method is known but the parameters are not OK - * (e.g. code size should be reduced), or -1 if the method is unknown. - */ -int -ccp_test( int unit, int opt_len, int for_transmit, u_char *opt_ptr) -{ - return 0; /* XXX Currently no compression. */ -} - -/* - * ccp_flags_set - inform kernel about the current state of CCP. - */ -void -ccp_flags_set(int unit, int isopen, int isup) -{ - /* XXX */ -} - -/* - * ccp_fatal_error - returns 1 if decompression was disabled as a - * result of an error detected after decompression of a packet, - * 0 otherwise. This is necessary because of patent nonsense. - */ -int -ccp_fatal_error(int unit) -{ - /* XXX */ - return 0; -} -#endif - -/* - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(int u, struct ppp_idle *ip) -{ - /* XXX */ - LWIP_UNUSED_ARG(u); - LWIP_UNUSED_ARG(ip); - - return 0; -} - - -/* - * Return user specified netmask, modified by any mask we might determine - * for address `addr' (in network byte order). - * Here we scan through the system's list of interfaces, looking for - * any non-point-to-point interfaces which might appear to be on the same - * network as `addr'. If we find any, we OR in their netmask to the - * user-specified netmask. - */ -u32_t -GetMask(u32_t addr) -{ - u32_t mask, nmask; - - addr = htonl(addr); - if (IP_CLASSA(addr)) { /* determine network mask for address class */ - nmask = IP_CLASSA_NET; - } else if (IP_CLASSB(addr)) { - nmask = IP_CLASSB_NET; - } else { - nmask = IP_CLASSC_NET; - } - - /* class D nets are disallowed by bad_ip_adrs */ - mask = PP_HTONL(0xffffff00UL) | htonl(nmask); - - /* XXX - * Scan through the system's network interfaces. - * Get each netmask and OR them into our mask. - */ - - return mask; -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid) -{ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPControl *pc = &pppControl[pd]; - - pc->vjEnabled = vjcomp; - pc->vjComp.compressSlot = cidcomp; - pc->vjComp.maxSlotIndex = maxcid; - PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", - vjcomp, cidcomp, maxcid)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - LWIP_UNUSED_ARG(pd); - LWIP_UNUSED_ARG(vjcomp); - LWIP_UNUSED_ARG(cidcomp); - LWIP_UNUSED_ARG(maxcid); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - return 0; -} - -/* - * pppifNetifInit - netif init callback - */ -static err_t -pppifNetifInit(struct netif *netif) -{ - netif->name[0] = 'p'; - netif->name[1] = 'p'; - netif->output = pppifOutput; - netif->mtu = pppMTU((int)(size_t)netif->state); - netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup(int pd) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_remove(&pc->netif); - if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) { - netif_set_up(&pc->netif); - pc->if_up = 1; - pc->errCode = PPPERR_NONE; - - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); - } - } else { - st = 0; - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd)); - } - } - - return st; -} - -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int -sifnpmode(int u, int proto, enum NPmode mode) -{ - LWIP_UNUSED_ARG(u); - LWIP_UNUSED_ARG(proto); - LWIP_UNUSED_ARG(mode); - return 0; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(int pd) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd)); - } else { - pc->if_up = 0; - /* make sure the netif status callback is called */ - netif_set_down(&pc->netif); - netif_remove(&pc->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); - } - } - return st; -} - -/** - * sifaddr - Config the interface IP addresses and netmask. - * @param pd Interface unit ??? - * @param o Our IP address ??? - * @param h His IP address ??? - * @param m IP subnet mask ??? - * @param ns1 Primary DNS - * @param ns2 Secondary DNS - */ -int -sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o)); - SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h)); - SMEMCPY(&pc->addrs.netmask, &m, sizeof(m)); - SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); - SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); - } - return st; -} - -/** - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - * @param pd Interface unit ??? - * @param o Our IP address ??? - * @param h IP broadcast address ??? - */ -int -cifaddr( int pd, u32_t o, u32_t h) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(o); - LWIP_UNUSED_ARG(h); - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); - IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); - IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); - } - return st; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(int pd, u32_t l, u32_t g) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(l); - LWIP_UNUSED_ARG(g); - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_set_default(&pc->netif); - } - - /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ - - return st; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(int pd, u32_t l, u32_t g) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(l); - LWIP_UNUSED_ARG(g); - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_set_default(NULL); - } - - return st; -} - -/**********************************/ -/*** LOCAL FUNCTION DEFINITIONS ***/ -/**********************************/ - -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD -/* The main PPP process function. This implements the state machine according - * to section 4 of RFC 1661: The Point-To-Point Protocol. */ -static void -pppInputThread(void *arg) -{ - int count; - PPPControlRx *pcrx = arg; - - while (lcp_phase[pcrx->pd] != PHASE_DEAD) { - count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); - if(count > 0) { - pppInProc(pcrx, pcrx->rxbuf, count); - } else { - /* nothing received, give other tasks a chance to run */ - sys_msleep(1); - } - } -} -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ - -#if PPPOE_SUPPORT - -void -pppOverEthernetInitFailed(int pd) -{ - PPPControl* pc; - - pppHup(pd); - pppStop(pd); - - pc = &pppControl[pd]; - pppoe_destroy(&pc->netif); - pc->openFlag = 0; - - if(pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - } -} - -static void -pppOverEthernetLinkStatusCB(int pd, int up) -{ - if(up) { - PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); - pppStart(pd); - } else { - pppOverEthernetInitFailed(pd); - } -} -#endif /* PPPOE_SUPPORT */ - -struct pbuf * -pppSingleBuf(struct pbuf *p) -{ - struct pbuf *q, *b; - u_char *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - -/** Input helper struct, must be packed since it is stored to pbuf->payload, - * which might be unaligned. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppInputHeader { - PACK_STRUCT_FIELD(int unit); - PACK_STRUCT_FIELD(u16_t proto); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ -static void -pppInput(void *arg) -{ - struct pbuf *nb = (struct pbuf *)arg; - u16_t protocol; - int pd; - - pd = ((struct pppInputHeader *)nb->payload)->unit; - protocol = ((struct pppInputHeader *)nb->payload)->proto; - - if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - - LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&pppControl[pd].netif); - snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { - if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); - goto drop; - } - } - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - struct protent *protp; - int i; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); - goto out; - } - } - - /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } -#if BYTE_ORDER == LITTLE_ENDIAN - protocol = htons(protocol); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - -out: - pbuf_free(nb); - return; -} - -#if PPPOS_SUPPORT -/* - * Drop the input packet. - */ -static void -pppFreeCurrentInputPacket(PPPControlRx *pcrx) -{ - if (pcrx->inHead != NULL) { - if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { - pbuf_free(pcrx->inTail); - } - pbuf_free(pcrx->inHead); - pcrx->inHead = NULL; - } - pcrx->inTail = NULL; -} - -/* - * Drop the input packet and increase error counters. - */ -static void -pppDrop(PPPControlRx *pcrx) -{ - if (pcrx->inHead != NULL) { -#if 0 - PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); -#endif - PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); - } - pppFreeCurrentInputPacket(pcrx); -#if VJ_SUPPORT - vj_uncompress_err(&pppControl[pcrx->pd].vjComp); -#endif /* VJ_SUPPORT */ - - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); -} - -#if !PPP_INPROC_OWNTHREAD -/** Pass received raw characters to PPPoS to be decoded. This function is - * thread-safe and can be called from a dedicated RX-thread or from a main-loop. - * - * @param pd PPP descriptor index, returned by pppOpen() - * @param data received data - * @param len length of received data - */ -void -pppos_input(int pd, u_char* data, int len) -{ - pppInProc(&pppControl[pd].rx, data, len); -} -#endif - -/** - * Process a received octet string. - */ -static void -pppInProc(PPPControlRx *pcrx, u_char *s, int l) -{ - struct pbuf *nextNBuf; - u_char curChar; - u_char escaped; - SYS_ARCH_DECL_PROTECT(lev); - - PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l)); - while (l-- > 0) { - curChar = *s++; - - SYS_ARCH_PROTECT(lev); - escaped = ESCAPE_P(pcrx->inACCM, curChar); - SYS_ARCH_UNPROTECT(lev); - /* Handle special characters. */ - if (escaped) { - /* Check for escape sequences. */ - /* XXX Note that this does not handle an escaped 0x5d character which - * would appear as an escape character. Since this is an ASCII ']' - * and there is no reason that I know of to escape it, I won't complicate - * the code to handle this case. GLL */ - if (curChar == PPP_ESCAPE) { - pcrx->inEscaped = 1; - /* Check for the flag character. */ - } else if (curChar == PPP_FLAG) { - /* If this is just an extra flag character, ignore it. */ - if (pcrx->inState <= PDADDRESS) { - /* ignore it */; - /* If we haven't received the packet header, drop what has come in. */ - } else if (pcrx->inState < PDDATA) { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping incomplete packet %d\n", - pcrx->pd, pcrx->inState)); - LINK_STATS_INC(link.lenerr); - pppDrop(pcrx); - /* If the fcs is invalid, drop the packet. */ - } else if (pcrx->inFCS != PPP_GOODFCS) { - PPPDEBUG(LOG_INFO, - ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - pcrx->pd, pcrx->inFCS, pcrx->inProtocol)); - /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ - LINK_STATS_INC(link.chkerr); - pppDrop(pcrx); - /* Otherwise it's a good packet so pass it on. */ - } else { - struct pbuf *inp; - /* Trim off the checksum. */ - if(pcrx->inTail->len > 2) { - pcrx->inTail->len -= 2; - - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - } - } else { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - } - - pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2); - } - - /* Dispatch the packet thereby consuming it. */ - inp = pcrx->inHead; - /* Packet consumed, release our references. */ - pcrx->inHead = NULL; - pcrx->inTail = NULL; -#if PPP_INPROC_MULTITHREADED - if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); - } -#else /* PPP_INPROC_MULTITHREADED */ - pppInput(inp); -#endif /* PPP_INPROC_MULTITHREADED */ - } - - /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; - pcrx->inState = PDADDRESS; - pcrx->inEscaped = 0; - /* Other characters are usually control characters that may have - * been inserted by the physical layer so here we just drop them. */ - } else { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar)); - } - /* Process other characters. */ - } else { - /* Unencode escaped characters. */ - if (pcrx->inEscaped) { - pcrx->inEscaped = 0; - curChar ^= PPP_TRANS; - } - - /* Process character relative to current state. */ - switch(pcrx->inState) { - case PDIDLE: /* Idle state - waiting. */ - /* Drop the character if it's not 0xff - * we would have processed a flag character above. */ - if (curChar != PPP_ALLSTATIONS) { - break; - } - - /* Fall through */ - case PDSTART: /* Process start flag. */ - /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; - - /* Fall through */ - case PDADDRESS: /* Process address field. */ - if (curChar == PPP_ALLSTATIONS) { - pcrx->inState = PDCONTROL; - break; - } - /* Else assume compressed address and control fields so - * fall through to get the protocol... */ - case PDCONTROL: /* Process control field. */ - /* If we don't get a valid control code, restart. */ - if (curChar == PPP_UI) { - pcrx->inState = PDPROTOCOL1; - break; - } -#if 0 - else { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); - pcrx->inState = PDSTART; - } -#endif - case PDPROTOCOL1: /* Process protocol field 1. */ - /* If the lower bit is set, this is the end of the protocol - * field. */ - if (curChar & 1) { - pcrx->inProtocol = curChar; - pcrx->inState = PDDATA; - } else { - pcrx->inProtocol = (u_int)curChar << 8; - pcrx->inState = PDPROTOCOL2; - } - break; - case PDPROTOCOL2: /* Process protocol field 2. */ - pcrx->inProtocol |= curChar; - pcrx->inState = PDDATA; - break; - case PDDATA: /* Process data byte. */ - /* Make space to receive processed data. */ - if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { - if (pcrx->inTail != NULL) { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - /* give up the inTail reference now */ - pcrx->inTail = NULL; - } - } - /* If we haven't started a packet, we need a packet header. */ - nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nextNBuf == NULL) { - /* No free buffers. Drop the input packet and let the - * higher layers deal with it. Continue processing - * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd)); - LINK_STATS_INC(link.memerr); - pppDrop(pcrx); - pcrx->inState = PDSTART; /* Wait for flag sequence. */ - break; - } - if (pcrx->inHead == NULL) { - struct pppInputHeader *pih = nextNBuf->payload; - - pih->unit = pcrx->pd; - pih->proto = pcrx->inProtocol; - - nextNBuf->len += sizeof(*pih); - - pcrx->inHead = nextNBuf; - } - pcrx->inTail = nextNBuf; - } - /* Load character into buffer. */ - ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar; - break; - } - - /* update the frame check sequence number. */ - pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar); - } - } /* while (l-- > 0), all bytes processed */ - - avRandomize(); -} -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -void -pppInProcOverEthernet(int pd, struct pbuf *pb) -{ - struct pppInputHeader *pih; - u16_t inProtocol; - - if(pb->len < sizeof(inProtocol)) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); - goto drop; - } - - inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - - /* make room for pppInputHeader - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); - goto drop; - } - - pih = pb->payload; - - pih->unit = pd; - pih->proto = inProtocol; - - /* Dispatch the packet thereby consuming it. */ - pppInput(pb); - return; - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - pbuf_free(pb); - return; -} -#endif /* PPPOE_SUPPORT */ - -#if LWIP_NETIF_STATUS_CALLBACK -/** Set the status callback of a PPP's netif - * - * @param pd The PPP descriptor returned by pppOpen() - * @param status_callback pointer to the status callback function - * - * @see netif_set_status_callback - */ -void -ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) -{ - netif_set_status_callback(&pppControl[pd].netif, status_callback); -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_LINK_CALLBACK -/** Set the link callback of a PPP's netif - * - * @param pd The PPP descriptor returned by pppOpen() - * @param link_callback pointer to the link callback function - * - * @see netif_set_link_callback - */ -void -ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) -{ - netif_set_link_callback(&pppControl[pd].netif, link_callback); -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ppp.h b/external/badvpn_dns/lwip/src/netif/ppp/ppp.h deleted file mode 100644 index 08d6e62..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ppp.h +++ /dev/null @@ -1,201 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-11-05 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#ifndef PPP_H -#define PPP_H - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/sio.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timers.h" - - -#ifndef __u_char_defined - -/* Type definitions for BSD code. */ -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; - -#endif - - -/************************* -*** PUBLIC DEFINITIONS *** -*************************/ - -/* Error codes. */ -#define PPPERR_NONE 0 /* No error. */ -#define PPPERR_PARAM -1 /* Invalid parameter. */ -#define PPPERR_OPEN -2 /* Unable to open PPP session. */ -#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ -#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ -#define PPPERR_USER -5 /* User interrupt. */ -#define PPPERR_CONNECT -6 /* Connection lost. */ -#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ -#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ - -/* - * PPP IOCTL commands. - */ -/* - * Get the up status - 0 for down, non-zero for up. The argument must - * point to an int. - */ -#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ -#define PPPCTLS_ERRCODE 101 /* Set the error code */ -#define PPPCTLG_ERRCODE 102 /* Get the error code */ -#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -struct ppp_addrs { - ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; -}; - - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* Initialize the PPP subsystem. */ -void pppInit(void); - -/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ -enum pppAuthType { - PPPAUTHTYPE_NONE, - PPPAUTHTYPE_ANY, - PPPAUTHTYPE_PAP, - PPPAUTHTYPE_CHAP -}; - -void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); - -/* Link status callback function prototype */ -typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); - -#if PPPOS_SUPPORT -/* - * Open a new PPP connection using the given serial I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. - */ -int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -/* - * Open a new PPP Over Ethernet (PPPOE) connection. - */ -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); -#endif /* PPPOE_SUPPORT */ - -/* for source code compatibility */ -#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) - -/* - * Close a PPP connection and release the descriptor. - * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. - */ -int pppClose(int pd); - -/* - * Indicate to the PPP process that the line has disconnected. - */ -void pppSigHUP(int pd); - -/* - * Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. - */ -int pppIOCtl(int pd, int cmd, void *arg); - -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -u_short pppMTU(int pd); - -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD -/* - * PPP over Serial: this is the input function to be called for received data. - * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking - * sio_read() is used, so this is deactivated. - */ -void pppos_input(int pd, u_char* data, int len); -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ - - -#if LWIP_NETIF_STATUS_CALLBACK -/* Set an lwIP-style status-callback for the selected PPP device */ -void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK -/* Set an lwIP-style link-callback for the selected PPP device */ -void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#endif /* PPP_SUPPORT */ - -#endif /* PPP_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ppp_impl.h b/external/badvpn_dns/lwip/src/netif/ppp/ppp_impl.h deleted file mode 100644 index 89aea60..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ppp_impl.h +++ /dev/null @@ -1,363 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 97-11-05 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#ifndef PPP_IMPL_H -#define PPP_IMPL_H - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp.h" -#include "lwip/def.h" -#include "lwip/sio.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timers.h" - -/** Some defines for code we skip compared to the original pppd. - * These are just here to minimise the use of the ugly "#if 0". */ -#define PPP_ADDITIONAL_CALLBACKS 0 - -/** Some error checks to test for unsupported code */ -#if CBCP_SUPPORT -#error "CBCP is not supported in lwIP PPP" -#endif -#if CCP_SUPPORT -#error "CCP is not supported in lwIP PPP" -#endif - -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - */ -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - - -/* - * Constants and structures defined by the internet system, - * Per RFC 790, September 1981, and numerous additions. - */ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_char ext_accm[32]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp); (cp)++; (s) <<= 8; \ - (s) |= *(cp); (cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s & 0xff); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -#define BCMP(s0, s1, l) memcmp((u_char *)(s0), (u_char *)(s1), (l)) -#define BCOPY(s, d, l) MEMCPY((d), (s), (l)) -#define BZERO(s, n) memset(s, 0, n) - -#if PPP_DEBUG -#define PRINTMSG(m, l) { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); } -#else /* PPP_DEBUG */ -#define PRINTMSG(m, l) -#endif /* PPP_DEBUG */ - -/* - * MAKEHEADER - Add PPP Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) (int unit); - /* Process a received packet */ - void (*input) (int unit, u_char *pkt, int len); - /* Process a received protocol-reject */ - void (*protrej) (int unit); - /* Lower layer has come up */ - void (*lowerup) (int unit); - /* Lower layer has gone down */ - void (*lowerdown) (int unit); - /* Open the protocol */ - void (*open) (int unit); - /* Close the protocol */ - void (*close) (int unit, char *reason); -#if PPP_ADDITIONAL_CALLBACKS - /* Print a packet in readable form */ - int (*printpkt) (u_char *pkt, int len, - void (*printer) (void *, char *, ...), - void *arg); - /* Process a received data packet */ - void (*datainput) (int unit, u_char *pkt, int len); -#endif /* PPP_ADDITIONAL_CALLBACKS */ - int enabled_flag; /* 0 if protocol is disabled */ - char *name; /* Text name of protocol */ -#if PPP_ADDITIONAL_CALLBACKS - /* Check requested options, assign defaults */ - void (*check_options) (u_long); - /* Configure interface for demand-dial */ - int (*demand_conf) (int unit); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) (u_char *pkt, int len); -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - u_short xmit_idle; /* seconds since last NP packet sent */ - u_short recv_idle; /* seconds since last NP packet received */ -}; - -struct ppp_settings { - - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ - u_int auth_required : 1; /* Peer is required to authenticate */ - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ - u_int usehostname : 1; /* Use hostname for our_name */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - - u_short idle_time_limit; /* Shut down link if idle for this long */ - int maxconnect; /* Maximum connect time (seconds) */ - - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -}; - -/***************************** -*** PUBLIC DATA STRUCTURES *** -*****************************/ - -/* Buffers for outgoing packets. */ -extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; - -extern struct ppp_settings ppp_settings; - -extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */ - - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written, -1 Failed to write to device. - */ -int pppWrite(int pd, const u_char *s, int n); - -void pppInProcOverEthernet(int pd, struct pbuf *pb); - -struct pbuf *pppSingleBuf(struct pbuf *p); - -void pppLinkTerminated(int pd); - -void pppLinkDown(int pd); - -/* Configure i/f transmit parameters */ -void ppp_send_config (int, u16_t, u32_t, int, int); -/* Set extended transmit ACCM */ -void ppp_set_xaccm (int, ext_accm *); -/* Configure i/f receive parameters */ -void ppp_recv_config (int, int, u32_t, int, int); -/* Find out how long link has been idle */ -int get_idle_time (int, struct ppp_idle *); - -/* Configure VJ TCP header compression */ -int sifvjcomp (int, int, u8_t, u8_t); -/* Configure i/f down (for IP) */ -int sifup (int); -/* Set mode for handling packets for proto */ -int sifnpmode (int u, int proto, enum NPmode mode); -/* Configure i/f down (for IP) */ -int sifdown (int); -/* Configure IP addresses for i/f */ -int sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t); -/* Reset i/f IP addresses */ -int cifaddr (int, u32_t, u32_t); -/* Create default route through i/f */ -int sifdefaultroute (int, u32_t, u32_t); -/* Delete default route through i/f */ -int cifdefaultroute (int, u32_t, u32_t); - -/* Get appropriate netmask for address */ -u32_t GetMask (u32_t); - -#endif /* PPP_SUPPORT */ - -#endif /* PPP_IMPL_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/ppp_oe.c b/external/badvpn_dns/lwip/src/netif/ppp/ppp_oe.c deleted file mode 100644 index fdf52ae..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/ppp_oe.c +++ /dev/null @@ -1,1132 +0,0 @@ -/***************************************************************************** -* ppp_oe.c - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann martin@NetBSD.org. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "lwip/opt.h" - -#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp_oe.h" - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "lwip/timers.h" -#include "lwip/memp.h" - -#include <string.h> -#include <stdio.h> - - -/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ -#define PPPOE_ADD_16(PTR, VAL) \ - *(PTR)++ = (u8_t)((VAL) / 256); \ - *(PTR)++ = (u8_t)((VAL) % 256) - -/* Add a complete PPPoE header to the buffer pointed to by PTR */ -#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ - *(PTR)++ = PPPOE_VERTYPE; \ - *(PTR)++ = (CODE); \ - PPPOE_ADD_16(PTR, SESS); \ - PPPOE_ADD_16(PTR, LEN) - -#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ -#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ -#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ -#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ - -#ifdef PPPOE_SERVER -#error "PPPOE_SERVER is not yet supported under lwIP!" -/* from if_spppsubr.c */ -#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ -#endif - -#ifndef PPPOE_ERRORSTRING_LEN -#define PPPOE_ERRORSTRING_LEN 64 -#endif -static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; - - -/* input routines */ -static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *); - -/* management routines */ -static int pppoe_do_disconnect(struct pppoe_softc *); -static void pppoe_abort_connect(struct pppoe_softc *); -static void pppoe_clear_softc(struct pppoe_softc *, const char *); - -/* internal timeout handling */ -static void pppoe_timeout(void *); - -/* sending actual protocol controll packets */ -static err_t pppoe_send_padi(struct pppoe_softc *); -static err_t pppoe_send_padr(struct pppoe_softc *); -#ifdef PPPOE_SERVER -static err_t pppoe_send_pado(struct pppoe_softc *); -static err_t pppoe_send_pads(struct pppoe_softc *); -#endif -static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); - -/* internal helper functions */ -static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *); -static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *); - -/** linked list of created pppoe interfaces */ -static struct pppoe_softc *pppoe_softc_list; - -err_t -pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr) -{ - struct pppoe_softc *sc; - - sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF); - if (sc == NULL) { - *scptr = NULL; - return ERR_MEM; - } - memset(sc, 0, sizeof(struct pppoe_softc)); - - /* changed to real address later */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - - sc->sc_pd = pd; - sc->sc_linkStatusCB = linkStatusCB; - sc->sc_ethif = ethif; - - /* put the new interface at the head of the list */ - sc->next = pppoe_softc_list; - pppoe_softc_list = sc; - - *scptr = sc; - - return ERR_OK; -} - -err_t -pppoe_destroy(struct netif *ifp) -{ - struct pppoe_softc *sc, *prev = NULL; - - for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) { - if (sc->sc_ethif == ifp) { - break; - } - } - - if(!(sc && (sc->sc_ethif == ifp))) { - return ERR_IF; - } - - sys_untimeout(pppoe_timeout, sc); - if (prev == NULL) { - /* remove sc from the head of the list */ - pppoe_softc_list = sc->next; - } else { - /* remove sc from the list */ - prev->next = sc->next; - } - -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name) { - mem_free(sc->sc_concentrator_name); - } - if (sc->sc_service_name) { - mem_free(sc->sc_service_name); - } -#endif /* PPPOE_TODO */ - memp_free(MEMP_PPPOE_IF, sc); - - return ERR_OK; -} - -/* - * Find the interface handling the specified session. - * Note: O(number of sessions open), this is a client-side only, mean - * and lean implementation, so number of open sessions typically should - * be 1. - */ -static struct pppoe_softc * -pppoe_find_softc_by_session(u_int session, struct netif *rcvif) -{ - struct pppoe_softc *sc; - - if (session == 0) { - return NULL; - } - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc->sc_state == PPPOE_STATE_SESSION - && sc->sc_session == session) { - if (sc->sc_ethif == rcvif) { - return sc; - } else { - return NULL; - } - } - } - return NULL; -} - -/* Check host unique token passed and return appropriate softc pointer, - * or NULL if token is bogus. */ -static struct pppoe_softc * -pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) -{ - struct pppoe_softc *sc, *t; - - if (pppoe_softc_list == NULL) { - return NULL; - } - - if (len != sizeof sc) { - return NULL; - } - MEMCPY(&t, token, len); - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc == t) { - break; - } - } - - if (sc == NULL) { - PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); - return NULL; - } - - /* should be safe to access *sc now */ - if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { - printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state); - return NULL; - } - if (sc->sc_ethif != rcvif) { - printf("%c%c%"U16_F": wrong interface, not accepting host unique\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - return NULL; - } - return sc; -} - -static void -pppoe_linkstatus_up(struct pppoe_softc *sc) -{ - sc->sc_linkStatusCB(sc->sc_pd, 1); -} - -/* analyze and handle a single received packet while not in session state */ -static void -pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) -{ - u16_t tag, len; - u16_t session, plen; - struct pppoe_softc *sc; - const char *err_msg; - char devname[6]; - u8_t *ac_cookie; - u16_t ac_cookie_len; -#ifdef PPPOE_SERVER - u8_t *hunique; - size_t hunique_len; -#endif - struct pppoehdr *ph; - struct pppoetag pt; - int off, err, errortag; - struct eth_hdr *ethhdr; - - pb = pppSingleBuf(pb); - - strcpy(devname, "pppoe"); /* as long as we don't know which instance */ - err_msg = NULL; - errortag = 0; - if (pb->len < sizeof(*ethhdr)) { - goto done; - } - ethhdr = (struct eth_hdr *)pb->payload; - off = sizeof(*ethhdr); - - ac_cookie = NULL; - ac_cookie_len = 0; -#ifdef PPPOE_SERVER - hunique = NULL; - hunique_len = 0; -#endif - session = 0; - if (pb->len - off < PPPOE_HEADERLEN) { - printf("pppoe: packet too short: %d\n", pb->len); - goto done; - } - - ph = (struct pppoehdr *) (ethhdr + 1); - if (ph->vertype != PPPOE_VERTYPE) { - printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); - goto done; - } - session = ntohs(ph->session); - plen = ntohs(ph->plen); - off += sizeof(*ph); - - if (plen + off > pb->len) { - printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", - pb->len - off, plen); - goto done; - } - if(pb->tot_len == pb->len) { - pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */ - } - tag = 0; - len = 0; - sc = NULL; - while (off + sizeof(pt) <= pb->len) { - MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); - tag = ntohs(pt.tag); - len = ntohs(pt.len); - if (off + sizeof(pt) + len > pb->len) { - printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); - goto done; - } - switch (tag) { - case PPPOE_TAG_EOL: - goto breakbreak; - case PPPOE_TAG_SNAME: - break; /* ignored */ - case PPPOE_TAG_ACNAME: - break; /* ignored */ - case PPPOE_TAG_HUNIQUE: - if (sc != NULL) { - break; - } -#ifdef PPPOE_SERVER - hunique = (u8_t*)pb->payload + off + sizeof(pt); - hunique_len = len; -#endif - sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); - if (sc != NULL) { - snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - } - break; - case PPPOE_TAG_ACCOOKIE: - if (ac_cookie == NULL) { - ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); - ac_cookie_len = len; - } - break; - case PPPOE_TAG_SNAME_ERR: - err_msg = "SERVICE NAME ERROR"; - errortag = 1; - break; - case PPPOE_TAG_ACSYS_ERR: - err_msg = "AC SYSTEM ERROR"; - errortag = 1; - break; - case PPPOE_TAG_GENERIC_ERR: - err_msg = "GENERIC ERROR"; - errortag = 1; - break; - } - if (err_msg) { - if (errortag && len) { - u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1); - strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); - pppoe_error_tmp[error_len-1] = '\0'; - printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp); - } else { - printf("%s: %s\n", devname, err_msg); - } - if (errortag) { - goto done; - } - } - off += sizeof(pt) + len; - } - -breakbreak:; - switch (ph->code) { - case PPPOE_CODE_PADI: -#ifdef PPPOE_SERVER - /* - * got service name, concentrator name, and/or host unique. - * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. - */ - if (LIST_EMPTY(&pppoe_softc_list)) { - goto done; - } - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { - continue; - } - if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - continue; - } - if (sc->sc_state == PPPOE_STATE_INITIAL) { - break; - } - } - if (sc == NULL) { - /* printf("pppoe: free passive interface is not found\n"); */ - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); - sc->sc_state = PPPOE_STATE_PADO_SENT; - pppoe_send_pado(sc); - break; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADR: -#ifdef PPPOE_SERVER - /* - * get sc from ac_cookie if IFF_PASSIVE - */ - if (ac_cookie == NULL) { - /* be quiet if there is not a single pppoe instance */ - printf("pppoe: received PADR but not includes ac_cookie\n"); - goto done; - } - sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (!LIST_EMPTY(&pppoe_softc_list)) { - printf("pppoe: received PADR but could not find request for it\n"); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - pppoe_send_pads(sc); - sc->sc_state = PPPOE_STATE_SESSION; - pppoe_linkstatus_up(sc); /* notify upper layers */ - break; -#else - /* ignore, we are no access concentrator */ - goto done; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADO: - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (pppoe_softc_list != NULL) { - printf("pppoe: received PADO but could not find request for it\n"); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADI_SENT) { - printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - goto done; - } - if (ac_cookie) { - sc->sc_ac_cookie_len = ac_cookie_len; - MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); - } - MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); - sys_untimeout(pppoe_timeout, sc); - sc->sc_padr_retried = 0; - sc->sc_state = PPPOE_STATE_PADR_SENT; - if ((err = pppoe_send_padr(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - case PPPOE_CODE_PADS: - if (sc == NULL) { - goto done; - } - sc->sc_session = session; - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); - sc->sc_state = PPPOE_STATE_SESSION; - pppoe_linkstatus_up(sc); /* notify upper layers */ - break; - case PPPOE_CODE_PADT: - if (sc == NULL) { - goto done; - } - pppoe_clear_softc(sc, "received PADT"); - break; - default: - if(sc) { - printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - (u16_t)ph->code, session); - } else { - printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session); - } - break; - } - -done: - pbuf_free(pb); - return; -} - -void -pppoe_disc_input(struct netif *netif, struct pbuf *p) -{ - /* avoid error messages if there is not a single pppoe instance */ - if (pppoe_softc_list != NULL) { - pppoe_dispatch_disc_pkt(netif, p); - } else { - pbuf_free(p); - } -} - -void -pppoe_data_input(struct netif *netif, struct pbuf *pb) -{ - u16_t session, plen; - struct pppoe_softc *sc; - struct pppoehdr *ph; -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - u8_t shost[ETHER_ADDR_LEN]; -#endif - -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); -#endif - if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - pb = pppSingleBuf (pb); - - if (pb->len <= PPPOE_HEADERLEN) { - printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len); - goto drop; - } - - if (pb->len < sizeof(*ph)) { - printf("pppoe_data_input: could not get PPPoE header\n"); - goto drop; - } - ph = (struct pppoehdr *)pb->payload; - - if (ph->vertype != PPPOE_VERTYPE) { - printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); - goto drop; - } - if (ph->code != 0) { - goto drop; - } - - session = ntohs(ph->session); - sc = pppoe_find_softc_by_session(session, netif); - if (sc == NULL) { -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); - pppoe_send_padt(netif, session, shost); -#endif - goto drop; - } - - plen = ntohs(ph->plen); - - if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - pb->len, plen)); - - if (pb->len < plen) { - goto drop; - } - - pppInProcOverEthernet(sc->sc_pd, pb); - - return; - -drop: - pbuf_free(pb); -} - -static err_t -pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) -{ - struct eth_hdr *ethhdr; - u16_t etype; - err_t res; - - if (!sc->sc_ethif) { - pbuf_free(pb); - return ERR_IF; - } - - ethhdr = (struct eth_hdr *)pb->payload; - etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; - ethhdr->type = htons(etype); - MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); - MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr)); - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, - sc->sc_state, sc->sc_session, - sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], - pb->tot_len)); - - res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); - - pbuf_free(pb); - - return res; -} - -static err_t -pppoe_send_padi(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - int len; -#ifdef PPPOE_TODO - int l1 = 0, l2 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - if (sc->sc_state >PPPOE_STATE_PADI_SENT) { - PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state)); - } - - /* calculate length of frame (excluding ethernet header + pppoe header) */ - len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - l1 = (int)strlen(sc->sc_service_name); - len += l1; - } - if (sc->sc_concentrator_name != NULL) { - l2 = (int)strlen(sc->sc_concentrator_name); - len += 2 + 2 + l2; - } -#endif /* PPPOE_TODO */ - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); - /* fill in pkt */ - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name != NULL) { - PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); - PPPOE_ADD_16(p, l2); - MEMCPY(p, sc->sc_concentrator_name, l2); - p += l2; - } -#endif /* PPPOE_TODO */ - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - /* send pkt */ - return pppoe_output(sc, pb); -} - -static void -pppoe_timeout(void *arg) -{ - int retry_wait, err; - struct pppoe_softc *sc = (struct pppoe_softc*)arg; - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - - switch (sc->sc_state) { - case PPPOE_STATE_PADI_SENT: - /* - * We have two basic ways of retrying: - * - Quick retry mode: try a few times in short sequence - * - Slow retry mode: we already had a connection successfully - * established and will try infinitely (without user - * intervention) - * We only enter slow retry mode if IFF_LINK1 (aka autodial) - * is not set. - */ - - /* initialize for quick retry mode */ - retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); - - sc->sc_padi_retried++; - if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { -#if 0 - if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { - /* slow retry mode */ - retry_wait = PPPOE_SLOW_RETRY; - } else -#endif - { - pppoe_abort_connect(sc); - return; - } - } - if ((err = pppoe_send_padi(sc)) != 0) { - sc->sc_padi_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(retry_wait, pppoe_timeout, sc); - break; - - case PPPOE_STATE_PADR_SENT: - sc->sc_padr_retried++; - if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_state = PPPOE_STATE_PADI_SENT; - sc->sc_padr_retried = 0; - if ((err = pppoe_send_padi(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); - return; - } - if ((err = pppoe_send_padr(sc)) != 0) { - sc->sc_padr_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - case PPPOE_STATE_CLOSING: - pppoe_do_disconnect(sc); - break; - default: - return; /* all done, work in peace */ - } -} - -/* Start a connection (i.e. initiate discovery phase) */ -int -pppoe_connect(struct pppoe_softc *sc) -{ - int err; - - if (sc->sc_state != PPPOE_STATE_INITIAL) { - return EBUSY; - } - -#ifdef PPPOE_SERVER - /* wait PADI if IFF_PASSIVE */ - if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - return 0; - } -#endif - /* save state, in case we fail to send PADI */ - sc->sc_state = PPPOE_STATE_PADI_SENT; - sc->sc_padr_retried = 0; - err = pppoe_send_padi(sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); - return err; -} - -/* disconnect */ -void -pppoe_disconnect(struct pppoe_softc *sc) -{ - if (sc->sc_state < PPPOE_STATE_SESSION) { - return; - } - /* - * Do not call pppoe_disconnect here, the upper layer state - * machine gets confused by this. We must return from this - * function and defer disconnecting to the timeout handler. - */ - sc->sc_state = PPPOE_STATE_CLOSING; - sys_timeout(20, pppoe_timeout, sc); -} - -static int -pppoe_do_disconnect(struct pppoe_softc *sc) -{ - int err; - - if (sc->sc_state < PPPOE_STATE_SESSION) { - err = EBUSY; - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); - } - - /* cleanup softc */ - sc->sc_state = PPPOE_STATE_INITIAL; - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_ac_cookie_len = 0; -#ifdef PPPOE_SERVER - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - sc->sc_hunique = NULL; - } - sc->sc_hunique_len = 0; -#endif - sc->sc_session = 0; - - sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ - - return err; -} - -/* Connection attempt aborted */ -static void -pppoe_abort_connect(struct pppoe_softc *sc) -{ - printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - sc->sc_state = PPPOE_STATE_CLOSING; - - sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ - - /* clear connection state */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_state = PPPOE_STATE_INITIAL; -} - -/* Send a PADR packet */ -static err_t -pppoe_send_padr(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; -#ifdef PPPOE_TODO - size_t l1 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - if (sc->sc_state != PPPOE_STATE_PADR_SENT) { - return ERR_CONN; - } - - len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } -#endif /* PPPOE_TODO */ - if (sc->sc_ac_cookie_len > 0) { - len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ - } - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } - if (sc->sc_ac_cookie_len > 0) { - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sc->sc_ac_cookie_len); - MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); - p += sc->sc_ac_cookie_len; - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - return pppoe_output(sc, pb); -} - -/* send a PADT packet */ -static err_t -pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) -{ - struct pbuf *pb; - struct eth_hdr *ethhdr; - err_t res; - u8_t *p; - - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - ethhdr = (struct eth_hdr *)pb->payload; - ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); - MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); - MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr)); - - p = (u8_t*)(ethhdr + 1); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); - - res = outgoing_if->linkoutput(outgoing_if, pb); - - pbuf_free(pb); - - return res; -} - -#ifdef PPPOE_SERVER -static err_t -pppoe_send_pado(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; - - if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - return ERR_CONN; - } - - /* calc length */ - len = 0; - /* include ac_cookie */ - len += 2 + 2 + sizeof(sc); - /* include hunique */ - len += 2 + 2 + sc->sc_hunique_len; - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof(sc)); - p += sizeof(sc); - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} - -static err_t -pppoe_send_pads(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len, l1 = 0; /* XXX: gcc */ - - if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - return ERR_CONN; - } - - sc->sc_session = mono_time.tv_sec % 0xff + 1; - /* calc length */ - len = 0; - /* include hunique */ - len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else { - PPPOE_ADD_16(p, 0); - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} -#endif - -err_t -pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) -{ - u8_t *p; - size_t len; - - /* are we ready to process data yet? */ - if (sc->sc_state < PPPOE_STATE_SESSION) { - /*sppp_flush(&sc->sc_sppp.pp_if);*/ - pbuf_free(pb); - return ERR_CONN; - } - - len = pb->tot_len; - - /* make room for Ethernet header - should not fail */ - if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - - p = (u8_t*)pb->payload + sizeof(struct eth_hdr); - PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); - - return pppoe_output(sc, pb); -} - -#if 0 /*def PFIL_HOOKS*/ -static int -pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) -{ - struct pppoe_softc *sc; - int s; - - if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { - return 0; - } - - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (sc->sc_ethif != ifp) { - continue; - } - if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { - sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); - printf("%c%c%"U16_F": ethernet interface detached, going down\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); - } - sc->sc_ethif = NULL; - pppoe_clear_softc(sc, "ethernet interface detached"); - } - - return 0; -} -#endif - -static void -pppoe_clear_softc(struct pppoe_softc *sc, const char *message) -{ - LWIP_UNUSED_ARG(message); - - /* stop timer */ - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); - - /* fix our state */ - sc->sc_state = PPPOE_STATE_INITIAL; - - /* notify upper layers */ - sc->sc_linkStatusCB(sc->sc_pd, 0); - - /* clean up softc */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_ac_cookie_len = 0; - sc->sc_session = 0; -} - -#endif /* PPPOE_SUPPORT */ - diff --git a/external/badvpn_dns/lwip/src/netif/ppp/pppdebug.h b/external/badvpn_dns/lwip/src/netif/ppp/pppdebug.h deleted file mode 100644 index 8134997..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/pppdebug.h +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** -* pppdebug.h - System debugging utilities. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* portions Copyright (c) 2001 by Cognizant Pty Ltd. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY (please don't use tabs!) -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 98-07-29 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Original. -* -***************************************************************************** -*/ -#ifndef PPPDEBUG_H -#define PPPDEBUG_H - -/* Trace levels. */ -#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_INFO (PPP_DEBUG) -#define LOG_DETAIL (PPP_DEBUG) -#define LOG_DEBUG (PPP_DEBUG) - - -#define TRACELCP PPP_DEBUG - -#if PPP_DEBUG - -#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b) -#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b) -#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) - -#else /* PPP_DEBUG */ - -#define AUTHDEBUG(a, b) -#define IPCPDEBUG(a, b) -#define UPAPDEBUG(a, b) -#define LCPDEBUG(a, b) -#define FSMDEBUG(a, b) -#define CHAPDEBUG(a, b) -#define PPPDEBUG(a, b) - -#endif /* PPP_DEBUG */ - -#endif /* PPPDEBUG_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/randm.c b/external/badvpn_dns/lwip/src/netif/ppp/randm.c deleted file mode 100644 index b736091..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/randm.c +++ /dev/null @@ -1,249 +0,0 @@ -/***************************************************************************** -* randm.c - Random number generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 98-06-03 Guy Lancaster lancasterg@acm.org, Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "md5.h" -#include "randm.h" - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include <string.h> - -#if MD5_SUPPORT /* this module depends on MD5 */ -#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ -static long randCount = 0; /* Pseudo-random incrementer */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* - * Initialize the random number generator. - * - * Since this is to be called on power up, we don't have much - * system randomess to work with. Here all we use is the - * real-time clock. We'll accumulate more randomness as soon - * as things start happening. - */ -void -avRandomInit() -{ - avChurnRand(NULL, 0); -} - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - */ -void -avChurnRand(char *randData, u32_t randLen) -{ - MD5_CTX md5; - - /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */ - MD5Init(&md5); - MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); - if (randData) { - MD5Update(&md5, (u_char *)randData, randLen); - } else { - struct { - /* INCLUDE fields for any system sources of randomness */ - char foobar; - } sysData; - - /* Load sysData fields here. */ - MD5Update(&md5, (u_char *)&sysData, sizeof(sysData)); - } - MD5Final((u_char *)randPool, &md5); -/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ -} - -/* - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). - * Note: It's important that there be sufficient randomness in randPool - * before this is called for otherwise the range of the result may be - * narrow enough to make a search feasible. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - * - * XXX Why does he not just call churnRand() for each block? Probably - * so that you don't ever publish the seed which could possibly help - * predict future values. - * XXX Why don't we preserve md5 between blocks and just update it with - * randCount each time? Probably there is a weakness but I wish that - * it was documented. - */ -void -avGenRand(char *buf, u32_t bufLen) -{ - MD5_CTX md5; - u_char tmp[16]; - u32_t n; - - while (bufLen > 0) { - n = LWIP_MIN(bufLen, RANDPOOLSZ); - MD5Init(&md5); - MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); - MD5Update(&md5, (u_char *)&randCount, sizeof(randCount)); - MD5Final(tmp, &md5); - randCount++; - MEMCPY(buf, tmp, n); - buf += n; - bufLen -= n; - } -} - -/* - * Return a new random number. - */ -u32_t -avRandom() -{ - u32_t newRand; - - avGenRand((char *)&newRand, sizeof(newRand)); - - return newRand; -} - -#else /* MD5_SUPPORT */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -static int avRandomized = 0; /* Set when truely randomized. */ -static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* - * Initialize the random number generator. - * - * Here we attempt to compute a random number seed but even if - * it isn't random, we'll randomize it later. - * - * The current method uses the fields from the real time clock, - * the idle process counter, the millisecond counter, and the - * hardware timer tick counter. When this is invoked - * in startup(), then the idle counter and timer values may - * repeat after each boot and the real time clock may not be - * operational. Thus we call it again on the first random - * event. - */ -void -avRandomInit() -{ -#if 0 - /* Get a pointer into the last 4 bytes of clockBuf. */ - u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); - - /* - * Initialize our seed using the real-time clock, the idle - * counter, the millisecond timer, and the hardware timer - * tick counter. The real-time clock and the hardware - * tick counter are the best sources of randomness but - * since the tick counter is only 16 bit (and truncated - * at that), the idle counter and millisecond timer - * (which may be small values) are added to help - * randomize the lower 16 bits of the seed. - */ - readClk(); - avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr - + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; -#else - avRandomSeed += sys_jiffies(); /* XXX */ -#endif - - /* Initialize the Borland random number generator. */ - srand((unsigned)avRandomSeed); -} - -/* - * Randomize our random seed value. Here we use the fact that - * this function is called at *truely random* times by the polling - * and network functions. Here we only get 16 bits of new random - * value but we use the previous value to randomize the other 16 - * bits. - */ -void -avRandomize(void) -{ - static u32_t last_jiffies; - - if (!avRandomized) { - avRandomized = !0; - avRandomInit(); - /* The initialization function also updates the seed. */ - } else { - /* avRandomSeed += (avRandomSeed << 16) + TM1; */ - avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ - } - last_jiffies = sys_jiffies(); -} - -/* - * Return a new random number. - * Here we use the Borland rand() function to supply a pseudo random - * number which we make truely random by combining it with our own - * seed which is randomized by truely random events. - * Thus the numbers will be truely random unless there have been no - * operator or network events in which case it will be pseudo random - * seeded by the real time clock. - */ -u32_t -avRandom() -{ - return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); -} - -#endif /* MD5_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/randm.h b/external/badvpn_dns/lwip/src/netif/ppp/randm.h deleted file mode 100644 index a0984b0..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/randm.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************** -* randm.h - Random number generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher marc@mbsi.ca -* Ported to lwIP. -* 98-05-29 Guy Lancaster glanca@gesn.com, Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#ifndef RANDM_H -#define RANDM_H - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ -/* - * Initialize the random number generator. - */ -void avRandomInit(void); - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - */ -void avChurnRand(char *randData, u32_t randLen); - -/* - * Randomize our random seed value. To be called for truely random events - * such as user operations and network traffic. - */ -#if MD5_SUPPORT -#define avRandomize() avChurnRand(NULL, 0) -#else /* MD5_SUPPORT */ -void avRandomize(void); -#endif /* MD5_SUPPORT */ - -/* - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). - * Thus it's important to make sure that the results of this are not - * published directly because one could predict the next result to at - * least some degree. Also, it's important to get a good seed before - * the first use. - */ -void avGenRand(char *buf, u32_t bufLen); - -/* - * Return a new random number. - */ -u32_t avRandom(void); - - -#endif /* RANDM_H */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/readme.txt b/external/badvpn_dns/lwip/src/netif/ppp/readme.txt deleted file mode 100644 index 5be41b9..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/readme.txt +++ /dev/null @@ -1,21 +0,0 @@ -About the PPP code: - -The PPP code is not our "own" code - we just copied it from pppd (http://ppp.samba.org/) and adapted it to lwIP. -Unfortunately, not many here know their way around it too well. Back in 2009, we took the effort to see which -version of pppd our code relates to and we're pretty much on 2.3.11 with some bugs from 2.4.x backported. - -Aside from simple code adaptions, there are some files that are different, however: -- chpms.c/.h are named chap_ms.c/.h in the original pppd 2.3.11 sources -- pap.c/.h are named upap.c/.h in the original pppd 2.3.11 sources -- randm.c is a random generator not included in the original pppd -- magic.c does not use the C library's random functions, but uses randm.c instead -- vj.c/.h is an implementation of the Van Jacobson header compression algorithm adapted to lwIP pbufs, - probably copied from one of the vjcompress.c files from pppd. -- ppp.c, ppp.h and ppp_impl.h contain the adaption from pppd to lwIP. This is the "OS"-dependent part like there - is an implementation for linux, xBSD etc. in the pppd sources. -- ppp_oe.c is Marc Boucher's implementation based on NetBSD's if_pppoe.c - -There is of course potential for bugs in it, but when analyzing of reporting bugs, it is strongly encouraged to -compare the code in question to pppd 2.3.11 (our basis) and newer versions (perhaps it's already fixed?) and to -share this knowledge with us when reporting a bug. - diff --git a/external/badvpn_dns/lwip/src/netif/ppp/vj.c b/external/badvpn_dns/lwip/src/netif/ppp/vj.c deleted file mode 100644 index 40fdad1..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/vj.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Routines to compress and uncompess tcp packets (for transmission - * over low speed serial lines. - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * Initial distribution. - * - * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, - * so that the entire packet being decompressed doesn't have - * to be in contiguous memory (just the compressed header). - * - * Modified March 1998 by Guy Lancaster, glanca@gesn.com, - * for a 16 bit processor. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "vj.h" - -#include <string.h> - -#if VJ_SUPPORT - -#if LINK_STATS -#define INCR(counter) ++comp->stats.counter -#else -#define INCR(counter) -#endif - -void -vj_compress_init(struct vjcompress *comp) -{ - register u_char i; - register struct cstate *tstate = comp->tstate; - -#if MAX_SLOTS == 0 - memset((char *)comp, 0, sizeof(*comp)); -#endif - comp->maxSlotIndex = MAX_SLOTS - 1; - comp->compressSlot = 0; /* Disable slot ID compression by default. */ - for (i = MAX_SLOTS - 1; i > 0; --i) { - tstate[i].cs_id = i; - tstate[i].cs_next = &tstate[i - 1]; - } - tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; - tstate[0].cs_id = 0; - comp->last_cs = &tstate[0]; - comp->last_recv = 255; - comp->last_xmit = 255; - comp->flags = VJF_TOSS; -} - - -/* ENCODE encodes a number that is known to be non-zero. ENCODEZ - * checks for zero (since zero has to be encoded in the long, 3 byte - * form). - */ -#define ENCODE(n) { \ - if ((u_short)(n) >= 256) { \ - *cp++ = 0; \ - cp[1] = (u_char)(n); \ - cp[0] = (u_char)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u_char)(n); \ - } \ -} -#define ENCODEZ(n) { \ - if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ - *cp++ = 0; \ - cp[1] = (u_char)(n); \ - cp[0] = (u_char)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u_char)(n); \ - } \ -} - -#define DECODEL(f) { \ - if (*cp == 0) {\ - u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ - (f) = htonl(tmp); \ - cp += 3; \ - } else { \ - u32_t tmp = ntohl(f) + (u32_t)*cp++; \ - (f) = htonl(tmp); \ - } \ -} - -#define DECODES(f) { \ - if (*cp == 0) {\ - u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ - (f) = htons(tmp); \ - cp += 3; \ - } else { \ - u_short tmp = ntohs(f) + (u_short)*cp++; \ - (f) = htons(tmp); \ - } \ -} - -#define DECODEU(f) { \ - if (*cp == 0) {\ - (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ - cp += 3; \ - } else { \ - (f) = htons((u_short)*cp++); \ - } \ -} - -/* - * vj_compress_tcp - Attempt to do Van Jacobson header compression on a - * packet. This assumes that nb and comp are not null and that the first - * buffer of the chain contains a valid IP header. - * Return the VJ type code indicating whether or not the packet was - * compressed. - */ -u_int -vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) -{ - register struct ip_hdr *ip = (struct ip_hdr *)pb->payload; - register struct cstate *cs = comp->last_cs->cs_next; - register u_short hlen = IPH_HL(ip); - register struct tcp_hdr *oth; - register struct tcp_hdr *th; - register u_short deltaS, deltaA; - register u_long deltaL; - register u_int changes = 0; - u_char new_seq[16]; - register u_char *cp = new_seq; - - /* - * Check that the packet is IP proto TCP. - */ - if (IPH_PROTO(ip) != IP_PROTO_TCP) { - return (TYPE_IP); - } - - /* - * Bail if this is an IP fragment or if the TCP packet isn't - * `compressible' (i.e., ACK isn't set or some other control bit is - * set). - */ - if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { - return (TYPE_IP); - } - th = (struct tcp_hdr *)&((long *)ip)[hlen]; - if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { - return (TYPE_IP); - } - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need - * to locate (or create) the connection state. Special case the - * most recently used connection since it's most likely to be used - * again & we don't have to do any reordering if it's used. - */ - INCR(vjs_packets); - if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src) - || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) - || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { - /* - * Wasn't the first -- search for it. - * - * States are kept in a circularly linked list with - * last_cs pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - register struct cstate *lcs; - register struct cstate *lastcs = comp->last_cs; - - do { - lcs = cs; cs = cs->cs_next; - INCR(vjs_searches); - if (ip_addr_cmp(&ip->src, &cs->cs_ip.src) - && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) - && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { - goto found; - } - } while (cs != lastcs); - - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * last_cs to update the lru linkage. - */ - INCR(vjs_misses); - comp->last_cs = lcs; - hlen += TCPH_HDRLEN(th); - hlen <<= 2; - /* Check that the IP/TCP headers are contained in the first buffer. */ - if (hlen > pb->len) { - return (TYPE_IP); - } - goto uncompressed; - - found: - /* - * Found it -- move to the front on the connection list. - */ - if (cs == lastcs) { - comp->last_cs = lcs; - } else { - lcs->cs_next = cs->cs_next; - cs->cs_next = lastcs->cs_next; - lastcs->cs_next = cs; - } - } - - oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; - deltaS = hlen; - hlen += TCPH_HDRLEN(th); - hlen <<= 2; - /* Check that the IP/TCP headers are contained in the first buffer. */ - if (hlen > pb->len) { - PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); - return (TYPE_IP); - } - - /* - * Make sure that only what we expect to change changed. The first - * line of the `if' checks the IP protocol version, header length & - * type of service. The 2nd line checks the "Don't fragment" bit. - * The 3rd line checks the time-to-live and protocol (the protocol - * check is unnecessary but costless). The 4th line checks the TCP - * header length. The 5th line checks IP options, if any. The 6th - * line checks TCP options, if any. If any of these things are - * different between the previous & current datagram, we send the - * current datagram `uncompressed'. - */ - if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] - || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] - || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] - || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) - || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) - || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { - goto uncompressed; - } - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if (TCPH_FLAGS(th) & TCP_URG) { - deltaS = ntohs(th->urgp); - ENCODEZ(deltaS); - changes |= NEW_U; - } else if (th->urgp != oth->urgp) { - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - goto uncompressed; - } - - if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) { - ENCODE(deltaS); - changes |= NEW_W; - } - - if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaA = (u_short)deltaL; - ENCODE(deltaA); - changes |= NEW_A; - } - - if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaS = (u_short)deltaL; - ENCODE(deltaS); - changes |= NEW_S; - } - - switch(changes) { - case 0: - /* - * Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && - ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { - break; - } - - /* (fall through) */ - - case SPECIAL_I: - case SPECIAL_D: - /* - * actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - goto uncompressed; - - case NEW_S|NEW_A: - if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for echoed terminal traffic */ - changes = SPECIAL_I; - cp = new_seq; - } - break; - - case NEW_S: - if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for data xfer */ - changes = SPECIAL_D; - cp = new_seq; - } - break; - } - - deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip))); - if (deltaS != 1) { - ENCODEZ(deltaS); - changes |= NEW_I; - } - if (TCPH_FLAGS(th) & TCP_PSH) { - changes |= TCP_PUSH_BIT; - } - /* - * Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - deltaA = ntohs(th->chksum); - BCOPY(ip, &cs->cs_ip, hlen); - - /* - * We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how - * many bytes of the original packet to toss so subtract the two to - * get the new packet size. - */ - deltaS = (u_short)(cp - new_seq); - if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { - comp->last_xmit = cs->cs_id; - hlen -= deltaS + 4; - if(pbuf_header(pb, -hlen)){ - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u_char *)pb->payload; - *cp++ = (u_char)(changes | NEW_C); - *cp++ = cs->cs_id; - } else { - hlen -= deltaS + 3; - if(pbuf_header(pb, -hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u_char *)pb->payload; - *cp++ = (u_char)changes; - } - *cp++ = (u_char)(deltaA >> 8); - *cp++ = (u_char)deltaA; - BCOPY(new_seq, cp, deltaS); - INCR(vjs_compressed); - return (TYPE_COMPRESSED_TCP); - - /* - * Update connection state cs & send uncompressed packet (that is, - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ -uncompressed: - BCOPY(ip, &cs->cs_ip, hlen); - IPH_PROTO_SET(ip, cs->cs_id); - comp->last_xmit = cs->cs_id; - return (TYPE_UNCOMPRESSED_TCP); -} - -/* - * Called when we may have missed a packet. - */ -void -vj_uncompress_err(struct vjcompress *comp) -{ - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); -} - -/* - * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. - * Return 0 on success, -1 on failure. - */ -int -vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) -{ - register u_int hlen; - register struct cstate *cs; - register struct ip_hdr *ip; - - ip = (struct ip_hdr *)nb->payload; - hlen = IPH_HL(ip) << 2; - if (IPH_PROTO(ip) >= MAX_SLOTS - || hlen + sizeof(struct tcp_hdr) > nb->len - || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) - > nb->len - || hlen > MAX_HDR) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", - IPH_PROTO(ip), hlen, nb->len)); - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return -1; - } - cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; - comp->flags &=~ VJF_TOSS; - IPH_PROTO_SET(ip, IP_PROTO_TCP); - BCOPY(ip, &cs->cs_ip, hlen); - cs->cs_hlen = (u_short)hlen; - INCR(vjs_uncompressedin); - return 0; -} - -/* - * Uncompress a packet of type TYPE_COMPRESSED_TCP. - * The packet is composed of a buffer chain and the first buffer - * must contain an accurate chain length. - * The first buffer must include the entire compressed TCP/IP header. - * This procedure replaces the compressed header with the uncompressed - * header and returns the length of the VJ header. - */ -int -vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) -{ - u_char *cp; - struct tcp_hdr *th; - struct cstate *cs; - u_short *bp; - struct pbuf *n0 = *nb; - u32_t tmp; - u_int vjlen, hlen, changes; - - INCR(vjs_compressedin); - cp = (u_char *)n0->payload; - changes = *cp++; - if (changes & NEW_C) { - /* - * Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. - */ - if (*cp >= MAX_SLOTS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); - goto bad; - } - - comp->flags &=~ VJF_TOSS; - comp->last_recv = *cp++; - } else { - /* - * this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. - */ - if (comp->flags & VJF_TOSS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); - INCR(vjs_tossed); - return (-1); - } - } - cs = &comp->rstate[comp->last_recv]; - hlen = IPH_HL(&cs->cs_ip) << 2; - th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen]; - th->chksum = htons((*cp << 8) | cp[1]); - cp += 2; - if (changes & TCP_PUSH_BIT) { - TCPH_SET_FLAG(th, TCP_PSH); - } else { - TCPH_UNSET_FLAG(th, TCP_PSH); - } - - switch (changes & SPECIALS_MASK) { - case SPECIAL_I: - { - register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->ackno) + i; - th->ackno = htonl(tmp); - tmp = ntohl(th->seqno) + i; - th->seqno = htonl(tmp); - } - break; - - case SPECIAL_D: - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - th->seqno = htonl(tmp); - break; - - default: - if (changes & NEW_U) { - TCPH_SET_FLAG(th, TCP_URG); - DECODEU(th->urgp); - } else { - TCPH_UNSET_FLAG(th, TCP_URG); - } - if (changes & NEW_W) { - DECODES(th->wnd); - } - if (changes & NEW_A) { - DECODEL(th->ackno); - } - if (changes & NEW_S) { - DECODEL(th->seqno); - } - break; - } - if (changes & NEW_I) { - DECODES(cs->cs_ip._id); - } else { - IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1); - IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip))); - } - - /* - * At this point, cp points to the first byte of data in the - * packet. Fill in the IP total length and update the IP - * header checksum. - */ - vjlen = (u_short)(cp - (u_char*)n0->payload); - if (n0->len < vjlen) { - /* - * We must have dropped some characters (crc should detect - * this but the old slip framing won't) - */ - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", - n0->len, vjlen)); - goto bad; - } - -#if BYTE_ORDER == LITTLE_ENDIAN - tmp = n0->tot_len - vjlen + cs->cs_hlen; - IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp)); -#else - IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen)); -#endif - - /* recompute the ip header checksum */ - bp = (u_short *) &cs->cs_ip; - IPH_CHKSUM_SET(&cs->cs_ip, 0); - for (tmp = 0; hlen > 0; hlen -= 2) { - tmp += *bp++; - } - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp)); - - /* Remove the compressed header and prepend the uncompressed header. */ - if(pbuf_header(n0, -((s16_t)(vjlen)))) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { - struct pbuf *np, *q; - u8_t *bufptr; - - np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); - goto bad; - } - - if(pbuf_header(np, -cs->cs_hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - bufptr = n0->payload; - for(q = np; q != NULL; q = q->next) { - MEMCPY(q->payload, bufptr, q->len); - bufptr += q->len; - } - - if(n0->next) { - pbuf_chain(np, n0->next); - pbuf_dechain(n0); - } - pbuf_free(n0); - n0 = np; - } - - if(pbuf_header(n0, cs->cs_hlen)) { - struct pbuf *np; - - LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); - np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); - goto bad; - } - pbuf_cat(np, n0); - n0 = np; - } - LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); - MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); - - *nb = n0; - - return vjlen; - -bad: - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return (-1); -} - -#endif /* VJ_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/external/badvpn_dns/lwip/src/netif/ppp/vj.h b/external/badvpn_dns/lwip/src/netif/ppp/vj.h deleted file mode 100644 index fad1213..0000000 --- a/external/badvpn_dns/lwip/src/netif/ppp/vj.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#ifndef VJ_H -#define VJ_H - -#include "lwip/ip.h" -#include "lwip/tcp_impl.h" - -#define MAX_SLOTS 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; -}; -#define cs_ip vjcs_u.csu_ip -#define cs_hdr vjcs_u.csu_hdr - - -struct vjstat { - unsigned long vjs_packets; /* outbound packets */ - unsigned long vjs_compressed; /* outbound compressed packets */ - unsigned long vjs_searches; /* searches for connection state */ - unsigned long vjs_misses; /* times couldn't find conn. state */ - unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned long vjs_compressedin; /* inbound compressed packets */ - unsigned long vjs_errorin; /* inbound unknown type packets */ - unsigned long vjs_tossed; /* inbound packets tossed because of error */ -}; - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; - u_char maxSlotIndex; - u_char compressSlot; /* Flag indicating OK to compress slot ID. */ -#if LINK_STATS - struct vjstat stats; -#endif - struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ - struct cstate rstate[MAX_SLOTS]; /* receive connection states */ -}; - -/* flag values */ -#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ - -extern void vj_compress_init (struct vjcompress *comp); -extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); -extern void vj_uncompress_err (struct vjcompress *comp); -extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); -extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); - -#endif /* VJ_H */ diff --git a/external/badvpn_dns/lwip/src/netif/slipif.c b/external/badvpn_dns/lwip/src/netif/slipif.c deleted file mode 100644 index 137ba89..0000000 --- a/external/badvpn_dns/lwip/src/netif/slipif.c +++ /dev/null @@ -1,546 +0,0 @@ -/** - * @file - * SLIP Interface - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is built upon the file: src/arch/rtxc/netif/sioslip.c - * - * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> - * Simon Goldschmidt - * - * Usage: This netif can be used in three ways: - * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() - * until data is received. - * 2) In your main loop, call slipif_poll() to check for new RX bytes, - * completed packets are fed into netif->input(). - * 3) Call slipif_received_byte[s]() from your serial RX ISR and - * slipif_process_rxqueue() from your main loop. ISR level decodes - * packets and puts completed packets on a queue which is fed into - * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for - * pbuf_alloc to work on ISR level!). - * - */ - -/* - * This is an arch independent SLIP netif. The specific serial hooks must be - * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send - */ - -#include "netif/slipif.h" -#include "lwip/opt.h" - -#if LWIP_HAVE_SLIPIF - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/sio.h" -#include "lwip/sys.h" - -#define SLIP_END 0xC0 /* 0300: start and end of every packet */ -#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ -#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ -#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ - -/** Maximum packet size that is received by this netif */ -#ifndef SLIP_MAX_SIZE -#define SLIP_MAX_SIZE 1500 -#endif - -/** Define this to the interface speed for SNMP - * (sio_fd is the sio_fd_t returned by sio_open). - * The default value of zero means 'unknown'. - */ -#ifndef SLIP_SIO_SPEED -#define SLIP_SIO_SPEED(sio_fd) 0 -#endif - -enum slipif_recv_state { - SLIP_RECV_NORMAL, - SLIP_RECV_ESCAPE, -}; - -struct slipif_priv { - sio_fd_t sd; - /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ - struct pbuf *p, *q; - u8_t state; - u16_t i, recved; -#if SLIP_RX_FROM_ISR - struct pbuf *rxpackets; -#endif -}; - -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chaing packet to send - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output(struct netif *netif, struct pbuf *p) -{ - struct slipif_priv *priv; - struct pbuf *q; - u16_t i; - u8_t c; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - LWIP_ASSERT("p != NULL", (p != NULL)); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len)); - priv = netif->state; - - /* Send pbuf out on the serial I/O device. */ - /* Start with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - - for (q = p; q != NULL; q = q->next) { - for (i = 0; i < q->len; i++) { - c = ((u8_t *)q->payload)[i]; - switch (c) { - case SLIP_END: - /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_END, priv->sd); - break; - case SLIP_ESC: - /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_ESC, priv->sd); - break; - default: - /* normal byte - no need for escaping */ - sio_send(c, priv->sd); - break; - } - } - } - /* End with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - return ERR_OK; -} - -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chaing packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v4(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} - -#if LWIP_IPV6 -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chaing packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} -#endif /* LWIP_IPV6 */ - -/** - * Handle the incoming SLIP stream character by character - * - * @param netif the lwip network interface structure for this slipif - * @param c received character (multiple calls to this function will - * return a complete packet, NULL is returned before - used for polling) - * @return The IP packet when SLIP_END is received - */ -static struct pbuf* -slipif_rxbyte(struct netif *netif, u8_t c) -{ - struct slipif_priv *priv; - struct pbuf *t; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = netif->state; - - switch (priv->state) { - case SLIP_RECV_NORMAL: - switch (c) { - case SLIP_END: - if (priv->recved > 0) { - /* Received whole packet. */ - /* Trim the pbuf to the size of the received packet. */ - pbuf_realloc(priv->q, priv->recved); - - LINK_STATS_INC(link.recv); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); - t = priv->q; - priv->p = priv->q = NULL; - priv->i = priv->recved = 0; - return t; - } - return NULL; - case SLIP_ESC: - priv->state = SLIP_RECV_ESCAPE; - return NULL; - } /* end switch (c) */ - break; - case SLIP_RECV_ESCAPE: - /* un-escape END or ESC bytes, leave other bytes - (although that would be a protocol error) */ - switch (c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - } - priv->state = SLIP_RECV_NORMAL; - break; - } /* end switch (priv->state) */ - - /* byte received, packet not yet completely received */ - if (priv->p == NULL) { - /* allocate a new pbuf */ - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); - priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); - - if (priv->p == NULL) { - LINK_STATS_INC(link.drop); - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); - /* don't process any further since we got no pbuf to receive to */ - return NULL; - } - - if (priv->q != NULL) { - /* 'chain' the pbuf to the existing chain */ - pbuf_cat(priv->q, priv->p); - } else { - /* p is the first pbuf in the chain */ - priv->q = priv->p; - } - } - - /* this automatically drops bytes if > SLIP_MAX_SIZE */ - if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { - ((u8_t *)priv->p->payload)[priv->i] = c; - priv->recved++; - priv->i++; - if (priv->i >= priv->p->len) { - /* on to the next pbuf */ - priv->i = 0; - if (priv->p->next != NULL && priv->p->next->len > 0) { - /* p is a chain, on to the next in the chain */ - priv->p = priv->p->next; - } else { - /* p is a single pbuf, set it to NULL so next time a new - * pbuf is allocated */ - priv->p = NULL; - } - } - } - return NULL; -} - -/** Like slipif_rxbyte, but passes completed packets to netif->input - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - */ -static void -slipif_rxbyte_input(struct netif *netif, u8_t c) -{ - struct pbuf *p; - p = slipif_rxbyte(netif, c); - if (p != NULL) { - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - } -} - -#if SLIP_USE_RX_THREAD -/** - * The SLIP input thread. - * - * Feed the IP layer with incoming packets - * - * @param nf the lwip network interface structure for this slipif - */ -static void -slipif_loop_thread(void *nf) -{ - u8_t c; - struct netif *netif = (struct netif *)nf; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - - while (1) { - if (sio_read(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } - } -} -#endif /* SLIP_USE_RX_THREAD */ - -/** - * SLIP netif initialization - * - * Call the arch specific sio_open and remember - * the opened device in the state field of the netif. - * - * @param netif the lwip network interface structure for this slipif - * @return ERR_OK if serial line could be opened, - * ERR_MEM if no memory could be allocated, - * ERR_IF is serial line couldn't be opened - * - * @note netif->num must contain the number of the serial port to open - * (0 by default). If netif->state is != NULL, it is interpreted as an - * u8_t pointer pointing to the serial port number instead of netif->num. - * - */ -err_t -slipif_init(struct netif *netif) -{ - struct slipif_priv *priv; - u8_t sio_num; - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); - - /* Allocate private data */ - priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); - if (!priv) { - return ERR_MEM; - } - - netif->name[0] = 's'; - netif->name[1] = 'l'; - netif->output = slipif_output_v4; -#if LWIP_IPV6 - netif->output_ip6 = slipif_output_v6; -#endif /* LWIP_IPV6 */ - netif->mtu = SLIP_MAX_SIZE; - netif->flags |= NETIF_FLAG_POINTTOPOINT; - - /* netif->state or netif->num contain the port number */ - if (netif->state != NULL) { - sio_num = *(u8_t*)netif->state; - } else { - sio_num = netif->num; - } - /* Try to open the serial port. */ - priv->sd = sio_open(sio_num); - if (!priv->sd) { - /* Opening the serial port failed. */ - mem_free(priv); - return ERR_IF; - } - - /* Initialize private data */ - priv->p = NULL; - priv->q = NULL; - priv->state = SLIP_RECV_NORMAL; - priv->i = 0; - priv->recved = 0; -#if SLIP_RX_FROM_ISR - priv->rxpackets = NULL; -#endif - - netif->state = priv; - - /* initialize the snmp variables and counters inside the struct netif */ - NETIF_INIT_SNMP(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); - -#if SLIP_USE_RX_THREAD - /* Create a thread to poll the serial line. */ - sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, - SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); -#endif /* SLIP_USE_RX_THREAD */ - return ERR_OK; -} - -/** - * Polls the serial device and feeds the IP layer with incoming packets. - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_poll(struct netif *netif) -{ - u8_t c; - struct slipif_priv *priv; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - while (sio_tryread(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } -} - -#if SLIP_RX_FROM_ISR -/** - * Feeds the IP layer with incoming packets that were receive - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_process_rxqueue(struct netif *netif) -{ - struct slipif_priv *priv; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - SYS_ARCH_PROTECT(old_level); - while (priv->rxpackets != NULL) { - struct pbuf *p = priv->rxpackets; -#if SLIP_RX_QUEUE - /* dequeue packet */ - struct pbuf *q = p; - while ((q->len != q->tot_len) && (q->next != NULL)) { - q = q->next; - } - priv->rxpackets = q->next; - q->next = NULL; -#else /* SLIP_RX_QUEUE */ - priv->rxpackets = NULL; -#endif /* SLIP_RX_QUEUE */ - SYS_ARCH_UNPROTECT(old_level); - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - SYS_ARCH_PROTECT(old_level); - } -} - -/** Like slipif_rxbyte, but queues completed packets. - * - * @param netif The lwip network interface structure for this slipif - * @param data Received serial byte - */ -static void -slipif_rxbyte_enqueue(struct netif *netif, u8_t data) -{ - struct pbuf *p; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - SYS_ARCH_DECL_PROTECT(old_level); - - p = slipif_rxbyte(netif, data); - if (p != NULL) { - SYS_ARCH_PROTECT(old_level); - if (priv->rxpackets != NULL) { -#if SLIP_RX_QUEUE - /* queue multiple pbufs */ - struct pbuf *q = p; - while(q->next != NULL) { - q = q->next; - } - q->next = p; - } else { -#else /* SLIP_RX_QUEUE */ - pbuf_free(priv->rxpackets); - } - { -#endif /* SLIP_RX_QUEUE */ - priv->rxpackets = p; - } - SYS_ARCH_UNPROTECT(old_level); - } -} - -/** - * Process a received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - */ -void -slipif_received_byte(struct netif *netif, u8_t data) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - slipif_rxbyte_enqueue(netif, data); -} - -/** - * Process multiple received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - * @param len Number of received characters - */ -void -slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) -{ - u8_t i; - u8_t *rxdata = data; - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - for (i = 0; i < len; i++, rxdata++) { - slipif_rxbyte_enqueue(netif, *rxdata); - } -} -#endif /* SLIP_RX_FROM_ISR */ - -#endif /* LWIP_HAVE_SLIPIF */ diff --git a/external/badvpn_dns/lwip/test/unit/core/test_mem.c b/external/badvpn_dns/lwip/test/unit/core/test_mem.c deleted file mode 100644 index d3a5d54..0000000 --- a/external/badvpn_dns/lwip/test/unit/core/test_mem.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "test_mem.h" - -#include "lwip/mem.h" -#include "lwip/stats.h" - -#if !LWIP_STATS || !MEM_STATS -#error "This tests needs MEM-statistics enabled" -#endif -#if LWIP_DNS -#error "This test needs DNS turned off (as it mallocs on init)" -#endif - -/* Setups/teardown functions */ - -static void -mem_setup(void) -{ -} - -static void -mem_teardown(void) -{ -} - - -/* Test functions */ - -/** Call mem_malloc, mem_free and mem_trim and check stats */ -START_TEST(test_mem_one) -{ -#define SIZE1 16 -#define SIZE1_2 12 -#define SIZE2 16 - void *p1, *p2; - mem_size_t s1, s2; - LWIP_UNUSED_ARG(_i); - -#if LWIP_DNS - fail("This test needs DNS turned off (as it mallocs on init)"); -#endif - - fail_unless(lwip_stats.mem.used == 0); - - p1 = mem_malloc(SIZE1); - fail_unless(p1 != NULL); - fail_unless(lwip_stats.mem.used >= SIZE1); - s1 = lwip_stats.mem.used; - - p2 = mem_malloc(SIZE2); - fail_unless(p2 != NULL); - fail_unless(lwip_stats.mem.used >= SIZE2 + s1); - s2 = lwip_stats.mem.used; - - mem_trim(p1, SIZE1_2); - - mem_free(p2); - fail_unless(lwip_stats.mem.used <= s2 - SIZE2); - - mem_free(p1); - fail_unless(lwip_stats.mem.used == 0); -} -END_TEST - - -/** Create the suite including all tests for this module */ -Suite * -mem_suite(void) -{ - TFun tests[] = { - test_mem_one - }; - return create_suite("MEM", tests, sizeof(tests)/sizeof(TFun), mem_setup, mem_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/core/test_mem.h b/external/badvpn_dns/lwip/test/unit/core/test_mem.h deleted file mode 100644 index 13803ed..0000000 --- a/external/badvpn_dns/lwip/test/unit/core/test_mem.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_MEM_H__ -#define __TEST_MEM_H__ - -#include "../lwip_check.h" - -Suite *mem_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/core/test_pbuf.c b/external/badvpn_dns/lwip/test/unit/core/test_pbuf.c deleted file mode 100644 index 2911078..0000000 --- a/external/badvpn_dns/lwip/test/unit/core/test_pbuf.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "test_pbuf.h" - -#include "lwip/pbuf.h" -#include "lwip/stats.h" - -#if !LWIP_STATS || !MEM_STATS ||!MEMP_STATS -#error "This tests needs MEM- and MEMP-statistics enabled" -#endif -#if LWIP_DNS -#error "This test needs DNS turned off (as it mallocs on init)" -#endif - -/* Setups/teardown functions */ - -static void -pbuf_setup(void) -{ -} - -static void -pbuf_teardown(void) -{ -} - - -/* Test functions */ - -/** Call pbuf_copy on a pbuf with zero length */ -START_TEST(test_pbuf_copy_zero_pbuf) -{ - struct pbuf *p1, *p2, *p3; - err_t err; - LWIP_UNUSED_ARG(_i); - - fail_unless(lwip_stats.mem.used == 0); - fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0); - - p1 = pbuf_alloc(PBUF_RAW, 1024, PBUF_RAM); - fail_unless(p1 != NULL); - fail_unless(p1->ref == 1); - - p2 = pbuf_alloc(PBUF_RAW, 2, PBUF_POOL); - fail_unless(p2 != NULL); - fail_unless(p2->ref == 1); - p2->len = p2->tot_len = 0; - - pbuf_cat(p1, p2); - fail_unless(p1->ref == 1); - fail_unless(p2->ref == 1); - - p3 = pbuf_alloc(PBUF_RAW, p1->tot_len, PBUF_POOL); - err = pbuf_copy(p3, p1); - fail_unless(err == ERR_VAL); - - pbuf_free(p1); - pbuf_free(p3); - fail_unless(lwip_stats.mem.used == 0); - - fail_unless(lwip_stats.mem.used == 0); - fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0); -} -END_TEST - - -/** Create the suite including all tests for this module */ -Suite * -pbuf_suite(void) -{ - TFun tests[] = { - test_pbuf_copy_zero_pbuf - }; - return create_suite("PBUF", tests, sizeof(tests)/sizeof(TFun), pbuf_setup, pbuf_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/core/test_pbuf.h b/external/badvpn_dns/lwip/test/unit/core/test_pbuf.h deleted file mode 100644 index b2715ad..0000000 --- a/external/badvpn_dns/lwip/test/unit/core/test_pbuf.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_PBUF_H__ -#define __TEST_PBUF_H__ - -#include "../lwip_check.h" - -Suite *pbuf_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.c b/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.c deleted file mode 100644 index 4b40de8..0000000 --- a/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.c +++ /dev/null @@ -1,916 +0,0 @@ -#include "test_dhcp.h" - -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "netif/etharp.h" - -struct netif net_test; - -static const u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - -static const u8_t magic_cookie[] = { 0x63, 0x82, 0x53, 0x63 }; - -static u8_t dhcp_offer[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */ - 0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */ - 0x08, 0x00, /* Protocol: IP */ - 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */ - 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */ - - 0x02, /* Type == Boot reply */ - 0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */ - 0x00, /* 0 hops */ - 0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */ - 0x00, 0x00, /* 0 seconds elapsed */ - 0x00, 0x00, /* Flags (unicast) */ - 0x00, 0x00, 0x00, 0x00, /* Client ip */ - 0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */ - 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */ - 0x00, 0x00, 0x00, 0x00, /* relay agent */ - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */ - - /* Empty server name and boot file name */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - - 0x63, 0x82, 0x53, 0x63, /* Magic cookie */ - 0x35, 0x01, 0x02, /* Message type: Offer */ - 0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */ - 0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */ - 0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */ - 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */ - 0xff, /* End option */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */ -}; - -static u8_t dhcp_ack[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */ - 0x00, 0x0f, 0xEE, 0x30, 0xAB, 0x22, /* From remote host */ - 0x08, 0x00, /* Proto IP */ - 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */ - 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */ - 0x02, /* Bootp reply */ - 0x01, 0x06, /* Hw type Eth, len 6 */ - 0x00, /* 0 hops */ - 0xAA, 0xAA, 0xAA, 0xAA, - 0x00, 0x00, /* 0 seconds elapsed */ - 0x00, 0x00, /* Flags (unicast) */ - 0x00, 0x00, 0x00, 0x00, /* Client IP */ - 0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */ - 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server IP */ - 0x00, 0x00, 0x00, 0x00, /* Relay agent */ - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Macaddr + padding */ - - /* Empty server name and boot file name */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - - 0x63, 0x82, 0x53, 0x63, /* Magic cookie */ - 0x35, 0x01, 0x05, /* Dhcp message type ack */ - 0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server identifier */ - 0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */ - 0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */ - 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Netmask */ - 0xff, /* End marker */ - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */ -}; - -static const u8_t arpreply[] = { - 0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* dst mac */ - 0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* src mac */ - 0x08, 0x06, /* proto arp */ - 0x00, 0x01, /* hw eth */ - 0x08, 0x00, /* proto ip */ - 0x06, /* hw addr len 6 */ - 0x04, /* proto addr len 4 */ - 0x00, 0x02, /* arp reply */ - 0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* sender mac */ - 0xc3, 0xaa, 0xbd, 0xc8, /* sender ip */ - 0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* target mac */ - 0x00, 0x00, 0x00, 0x00, /* target ip */ -}; - -static int txpacket; -static enum tcase { - TEST_LWIP_DHCP, - TEST_LWIP_DHCP_NAK, - TEST_LWIP_DHCP_RELAY, - TEST_LWIP_DHCP_NAK_NO_ENDMARKER, -} tcase; - -static int debug = 0; -static void setdebug(int a) {debug = a;} - -static int tick = 0; -static void tick_lwip(void) -{ - tick++; - if (tick % 5 == 0) { - dhcp_fine_tmr(); - } - if (tick % 600 == 0) { - dhcp_coarse_tmr(); - } -} - -static void send_pkt(struct netif *netif, const u8_t *data, u32_t len) -{ - struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - struct pbuf *q; - - if (debug) { - /* Dump data */ - u32_t i; - printf("RX data (len %d)", p->tot_len); - for (i = 0; i < len; i++) { - printf(" %02X", data[i]); - } - printf("\n"); - } - - fail_unless(p != NULL); - for(q = p; q != NULL; q = q->next) { - memcpy(q->payload, data, q->len); - data += q->len; - } - netif->input(p, netif); -} - -static err_t lwip_tx_func(struct netif *netif, struct pbuf *p); - -static err_t testif_init(struct netif *netif) -{ - netif->name[0] = 'c'; - netif->name[1] = 'h'; - netif->output = etharp_output; - netif->linkoutput = lwip_tx_func; - netif->mtu = 1500; - netif->hwaddr_len = 6; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; - - netif->hwaddr[0] = 0x00; - netif->hwaddr[1] = 0x23; - netif->hwaddr[2] = 0xC1; - netif->hwaddr[3] = 0xDE; - netif->hwaddr[4] = 0xD0; - netif->hwaddr[5] = 0x0D; - - return ERR_OK; -} - -static void dhcp_setup(void) -{ - txpacket = 0; -} - -static void dhcp_teardown(void) -{ -} - -static void check_pkt(struct pbuf *p, u32_t pos, const u8_t *mem, u32_t len) -{ - u8_t *data; - - fail_if((pos + len) > p->tot_len); - while (pos > p->len && p->next) { - pos -= p->len; - p = p->next; - } - fail_if(p == NULL); - fail_unless(pos + len <= p->len); /* All data we seek within same pbuf */ - - data = p->payload; - fail_if(memcmp(&data[pos], mem, len), "data at pos %d, len %d in packet %d did not match", pos, len, txpacket); -} - -static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, const u8_t *mem, u32_t len) -{ - int found; - u32_t i; - u8_t *data; - - fail_if((startpos + len) > p->tot_len); - while (startpos > p->len && p->next) { - startpos -= p->len; - p = p->next; - } - fail_if(p == NULL); - fail_unless(startpos + len <= p->len); /* All data we seek within same pbuf */ - - found = 0; - data = p->payload; - for (i = startpos; i <= (p->len - len); i++) { - if (memcmp(&data[i], mem, len) == 0) { - found = 1; - break; - } - } - fail_unless(found); -} - -static err_t lwip_tx_func(struct netif *netif, struct pbuf *p) -{ - fail_unless(netif == &net_test); - txpacket++; - - if (debug) { - struct pbuf *pp = p; - /* Dump data */ - printf("TX data (pkt %d, len %d, tick %d)", txpacket, p->tot_len, tick); - do { - int i; - for (i = 0; i < pp->len; i++) { - printf(" %02X", ((u8_t *) pp->payload)[i]); - } - if (pp->next) { - pp = pp->next; - } - } while (pp->next); - printf("\n"); - } - - switch (tcase) { - case TEST_LWIP_DHCP: - switch (txpacket) { - case 1: - case 2: - { - const u8_t ipproto[] = { 0x08, 0x00 }; - const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */ - const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */ - - check_pkt(p, 42, bootp_start, sizeof(bootp_start)); - - check_pkt(p, 53, ipaddrs, sizeof(ipaddrs)); - - check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */ - - check_pkt(p, 278, magic_cookie, sizeof(magic_cookie)); - - /* Check dchp message type, can be at different positions */ - if (txpacket == 1) { - u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 }; - check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt)); - } else if (txpacket == 2) { - u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 }; - u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* Ask for offered IP */ - - check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt)); - check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr)); - } - break; - } - case 3: - case 4: - case 5: - { - const u8_t arpproto[] = { 0x08, 0x06 }; - - check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */ - break; - } - } - break; - - case TEST_LWIP_DHCP_NAK: - { - const u8_t ipproto[] = { 0x08, 0x00 }; - const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */ - const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - const u8_t dhcp_nak_opt[] = { 0x35, 0x01, 0x04 }; - const u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* offered IP */ - - fail_unless(txpacket == 4); - check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */ - - check_pkt(p, 42, bootp_start, sizeof(bootp_start)); - - check_pkt(p, 53, ipaddrs, sizeof(ipaddrs)); - - check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */ - - check_pkt(p, 278, magic_cookie, sizeof(magic_cookie)); - - check_pkt_fuzzy(p, 282, dhcp_nak_opt, sizeof(dhcp_nak_opt)); /* NAK the ack */ - - check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr)); - break; - } - - case TEST_LWIP_DHCP_RELAY: - switch (txpacket) { - case 1: - case 2: - { - const u8_t ipproto[] = { 0x08, 0x00 }; - const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */ - const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */ - - check_pkt(p, 42, bootp_start, sizeof(bootp_start)); - - check_pkt(p, 53, ipaddrs, sizeof(ipaddrs)); - - check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */ - - check_pkt(p, 278, magic_cookie, sizeof(magic_cookie)); - - /* Check dchp message type, can be at different positions */ - if (txpacket == 1) { - u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 }; - check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt)); - } else if (txpacket == 2) { - u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 }; - u8_t requested_ipaddr[] = { 0x32, 0x04, 0x4f, 0x8a, 0x33, 0x05 }; /* Ask for offered IP */ - - check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt)); - check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr)); - } - break; - } - case 3: - case 4: - case 5: - case 6: - { - const u8_t arpproto[] = { 0x08, 0x06 }; - - check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */ - break; - } - case 7: - { - const u8_t fake_arp[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab }; - const u8_t ipproto[] = { 0x08, 0x00 }; - const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */ - const u8_t ipaddrs[] = { 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - const u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 }; - - check_pkt(p, 0, fake_arp, 6); /* eth level dest: broadcast */ - check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */ - - check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */ - - check_pkt(p, 42, bootp_start, sizeof(bootp_start)); - - check_pkt(p, 53, ipaddrs, sizeof(ipaddrs)); - - check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */ - - check_pkt(p, 278, magic_cookie, sizeof(magic_cookie)); - - /* Check dchp message type, can be at different positions */ - check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt)); - break; - } - } - break; - - default: - break; - } - - return ERR_OK; -} - -/* - * Test basic happy flow DHCP session. - * Validate that xid is checked. - */ -START_TEST(test_dhcp) -{ - struct ip_addr addr; - struct ip_addr netmask; - struct ip_addr gw; - int i; - u32_t xid; - LWIP_UNUSED_ARG(_i); - - tcase = TEST_LWIP_DHCP; - setdebug(0); - - IP4_ADDR(&addr, 0, 0, 0, 0); - IP4_ADDR(&netmask, 0, 0, 0, 0); - IP4_ADDR(&gw, 0, 0, 0, 0); - - netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input); - - dhcp_start(&net_test); - - fail_unless(txpacket == 1); /* DHCP discover sent */ - xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */ - memcpy(&dhcp_offer[46], &xid, 4); - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - /* Interface down */ - fail_if(netif_is_up(&net_test)); - - /* IP addresses should be zero */ - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - fail_unless(txpacket == 1, "TX %d packets, expected 1", txpacket); /* Nothing more sent */ - xid = htonl(net_test.dhcp->xid); - memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */ - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - fail_unless(txpacket == 2, "TX %d packets, expected 2", txpacket); /* DHCP request sent */ - xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */ - memcpy(&dhcp_ack[46], &xid, 4); - send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack)); - - fail_unless(txpacket == 2, "TX %d packets, still expected 2", txpacket); /* No more sent */ - xid = htonl(net_test.dhcp->xid); /* xid updated */ - memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */ - send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack)); - - for (i = 0; i < 20; i++) { - tick_lwip(); - } - fail_unless(txpacket == 4, "TX %d packets, expected 4", txpacket); /* ARP requests sent */ - - /* Interface up */ - fail_unless(netif_is_up(&net_test)); - - /* Now it should have taken the IP */ - IP4_ADDR(&addr, 195, 170, 189, 200); - IP4_ADDR(&netmask, 255, 255, 255, 0); - IP4_ADDR(&gw, 195, 170, 189, 171); - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - netif_remove(&net_test); -} -END_TEST - -/* - * Test that IP address is not taken and NAK is sent if someone - * replies to ARP requests for the offered address. - */ -START_TEST(test_dhcp_nak) -{ - struct ip_addr addr; - struct ip_addr netmask; - struct ip_addr gw; - u32_t xid; - LWIP_UNUSED_ARG(_i); - - tcase = TEST_LWIP_DHCP; - setdebug(0); - - IP4_ADDR(&addr, 0, 0, 0, 0); - IP4_ADDR(&netmask, 0, 0, 0, 0); - IP4_ADDR(&gw, 0, 0, 0, 0); - - netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input); - - dhcp_start(&net_test); - - fail_unless(txpacket == 1); /* DHCP discover sent */ - xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */ - memcpy(&dhcp_offer[46], &xid, 4); - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - /* Interface down */ - fail_if(netif_is_up(&net_test)); - - /* IP addresses should be zero */ - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - fail_unless(txpacket == 1); /* Nothing more sent */ - xid = htonl(net_test.dhcp->xid); - memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */ - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - fail_unless(txpacket == 2); /* DHCP request sent */ - xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */ - memcpy(&dhcp_ack[46], &xid, 4); - send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack)); - - fail_unless(txpacket == 2); /* No more sent */ - xid = htonl(net_test.dhcp->xid); /* xid updated */ - memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */ - send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack)); - - fail_unless(txpacket == 3); /* ARP request sent */ - - tcase = TEST_LWIP_DHCP_NAK; /* Switch testcase */ - - /* Send arp reply, mark offered IP as taken */ - send_pkt(&net_test, arpreply, sizeof(arpreply)); - - fail_unless(txpacket == 4); /* DHCP nak sent */ - - netif_remove(&net_test); -} -END_TEST - -/* - * Test case based on captured data where - * replies are sent from a different IP than the - * one the client unicasted to. - */ -START_TEST(test_dhcp_relayed) -{ - const u8_t relay_offer[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, - 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, - 0x08, 0x00, 0x45, 0x00, - 0x01, 0x38, 0xfd, 0x53, 0x00, 0x00, 0x40, 0x11, - 0x78, 0x46, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a, - 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24, - 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35, - 0xb6, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23, - 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, - 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00, - 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08, - 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1, - 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04, - 0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x02, 0x36, - 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff - }; - - const u8_t relay_ack1[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x22, - 0x93, 0x5a, 0xf7, 0x60, 0x08, 0x00, 0x45, 0x00, - 0x01, 0x38, 0xfd, 0x55, 0x00, 0x00, 0x40, 0x11, - 0x78, 0x44, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a, - 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24, - 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35, - 0xb6, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23, - 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, - 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00, - 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08, - 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1, - 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04, - 0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x05, 0x36, - 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff - }; - - const u8_t relay_ack2[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, - 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, - 0x08, 0x00, 0x45, 0x00, - 0x01, 0x38, 0xfa, 0x18, 0x00, 0x00, 0x40, 0x11, - 0x7b, 0x81, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a, - 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24, - 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x49, 0x8b, - 0x6e, 0xab, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8a, - 0x33, 0x05, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23, - 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, - 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00, - 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08, - 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1, - 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04, - 0x00, 0x00, 0x54, 0x60, 0x35, 0x01, 0x05, 0x36, - 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff }; - - const u8_t arp_resp[] = { - 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* DEST */ - 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, /* SRC */ - 0x08, 0x06, /* Type: ARP */ - 0x00, 0x01, /* HW: Ethernet */ - 0x08, 0x00, /* PROTO: IP */ - 0x06, /* HW size */ - 0x04, /* PROTO size */ - 0x00, 0x02, /* OPCODE: Reply */ - - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, /* Target MAC */ - 0x4f, 0x8a, 0x32, 0x01, /* Target IP */ - - 0x00, 0x23, 0xc1, 0x00, 0x06, 0x50, /* src mac */ - 0x4f, 0x8a, 0x33, 0x05, /* src ip */ - - /* Padding follows.. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - - struct ip_addr addr; - struct ip_addr netmask; - struct ip_addr gw; - int i; - u32_t xid; - LWIP_UNUSED_ARG(_i); - - tcase = TEST_LWIP_DHCP_RELAY; - setdebug(0); - - IP4_ADDR(&addr, 0, 0, 0, 0); - IP4_ADDR(&netmask, 0, 0, 0, 0); - IP4_ADDR(&gw, 0, 0, 0, 0); - - netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input); - - dhcp_start(&net_test); - - fail_unless(txpacket == 1); /* DHCP discover sent */ - - /* Interface down */ - fail_if(netif_is_up(&net_test)); - - /* IP addresses should be zero */ - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - fail_unless(txpacket == 1); /* Nothing more sent */ - xid = htonl(net_test.dhcp->xid); - memcpy(&relay_offer[46], &xid, 4); /* insert correct transaction id */ - send_pkt(&net_test, relay_offer, sizeof(relay_offer)); - - /* request sent? */ - fail_unless(txpacket == 2, "txpkt = %d, should be 2", txpacket); - xid = htonl(net_test.dhcp->xid); /* xid updated */ - memcpy(&relay_ack1[46], &xid, 4); /* insert transaction id */ - send_pkt(&net_test, relay_ack1, sizeof(relay_ack1)); - - for (i = 0; i < 25; i++) { - tick_lwip(); - } - fail_unless(txpacket == 4, "txpkt should be 5, is %d", txpacket); /* ARP requests sent */ - - /* Interface up */ - fail_unless(netif_is_up(&net_test)); - - /* Now it should have taken the IP */ - IP4_ADDR(&addr, 79, 138, 51, 5); - IP4_ADDR(&netmask, 255, 255, 254, 0); - IP4_ADDR(&gw, 79, 138, 50, 1); - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - fail_unless(txpacket == 4, "txpacket = %d", txpacket); - - for (i = 0; i < 108000 - 25; i++) { - tick_lwip(); - } - - fail_unless(netif_is_up(&net_test)); - fail_unless(txpacket == 6, "txpacket = %d", txpacket); - - /* We need to send arp response here.. */ - - send_pkt(&net_test, arp_resp, sizeof(arp_resp)); - - fail_unless(txpacket == 7, "txpacket = %d", txpacket); - fail_unless(netif_is_up(&net_test)); - - xid = htonl(net_test.dhcp->xid); /* xid updated */ - memcpy(&relay_ack2[46], &xid, 4); /* insert transaction id */ - send_pkt(&net_test, relay_ack2, sizeof(relay_ack2)); - - for (i = 0; i < 100000; i++) { - tick_lwip(); - } - - fail_unless(txpacket == 7, "txpacket = %d", txpacket); - - netif_remove(&net_test); - -} -END_TEST - -START_TEST(test_dhcp_nak_no_endmarker) -{ - struct ip_addr addr; - struct ip_addr netmask; - struct ip_addr gw; - - u8_t dhcp_nack_no_endmarker[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x54, 0x75, - 0xd0, 0x26, 0xd0, 0x0d, 0x08, 0x00, 0x45, 0x00, - 0x01, 0x15, 0x38, 0x86, 0x00, 0x00, 0xff, 0x11, - 0xc0, 0xa8, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x01, - 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x7a, 0xcb, - 0xba, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, - 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, - 0x53, 0x63, 0x35, 0x01, 0x06, 0x36, 0x04, 0xc0, - 0xa8, 0x01, 0x01, 0x31, 0xef, 0xad, 0x72, 0x31, - 0x43, 0x4e, 0x44, 0x30, 0x32, 0x35, 0x30, 0x43, - 0x52, 0x47, 0x44, 0x38, 0x35, 0x36, 0x3c, 0x08, - 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, - 0x37, 0x0d, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, - 0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xfc, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x71, - 0xf3, 0x5b, 0xe2, 0x71, 0x2e, 0x01, 0x08, 0x03, - 0x04, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xeb, 0x1e, - 0x44, 0xec, 0xeb, 0x1e, 0x30, 0x37, 0x0c, 0x01, - 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, - 0x79, 0xf9, 0x2b, 0xff, 0x25, 0xc0, 0x09, 0xd6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - u32_t xid; - LWIP_UNUSED_ARG(_i); - - tcase = TEST_LWIP_DHCP_NAK_NO_ENDMARKER; - setdebug(0); - - IP4_ADDR(&addr, 0, 0, 0, 0); - IP4_ADDR(&netmask, 0, 0, 0, 0); - IP4_ADDR(&gw, 0, 0, 0, 0); - - netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input); - - dhcp_start(&net_test); - - fail_unless(txpacket == 1); /* DHCP discover sent */ - xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */ - memcpy(&dhcp_offer[46], &xid, 4); - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - /* Interface down */ - fail_if(netif_is_up(&net_test)); - - /* IP addresses should be zero */ - fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr))); - fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr))); - fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr))); - - fail_unless(txpacket == 1); /* Nothing more sent */ - xid = htonl(net_test.dhcp->xid); - memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */ - send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer)); - - fail_unless(net_test.dhcp->state == DHCP_REQUESTING); - - fail_unless(txpacket == 2); /* No more sent */ - xid = htonl(net_test.dhcp->xid); /* xid updated */ - memcpy(&dhcp_nack_no_endmarker[46], &xid, 4); /* insert transaction id */ - send_pkt(&net_test, dhcp_nack_no_endmarker, sizeof(dhcp_nack_no_endmarker)); - - /* NAK should put us in another state for a while, no other way detecting it */ - fail_unless(net_test.dhcp->state != DHCP_REQUESTING); - - netif_remove(&net_test); -} -END_TEST - - -/** Create the suite including all tests for this module */ -Suite * -dhcp_suite(void) -{ - TFun tests[] = { - test_dhcp, - test_dhcp_nak, - test_dhcp_relayed, - test_dhcp_nak_no_endmarker - }; - return create_suite("DHCP", tests, sizeof(tests)/sizeof(TFun), dhcp_setup, dhcp_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.h b/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.h deleted file mode 100644 index aff44b7..0000000 --- a/external/badvpn_dns/lwip/test/unit/dhcp/test_dhcp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_DHCP_H__ -#define __TEST_DHCP_H__ - -#include "../lwip_check.h" - -Suite* dhcp_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.c b/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.c deleted file mode 100644 index cbbc950..0000000 --- a/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "test_etharp.h" - -#include "lwip/udp.h" -#include "netif/etharp.h" -#include "lwip/stats.h" - -#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS -#error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled" -#endif -#if !ETHARP_SUPPORT_STATIC_ENTRIES -#error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled" -#endif - -static struct netif test_netif; -static ip_addr_t test_ipaddr, test_netmask, test_gw; -struct eth_addr test_ethaddr = {1,1,1,1,1,1}; -struct eth_addr test_ethaddr2 = {1,1,1,1,1,2}; -struct eth_addr test_ethaddr3 = {1,1,1,1,1,3}; -struct eth_addr test_ethaddr4 = {1,1,1,1,1,4}; -static int linkoutput_ctr; - -/* Helper functions */ -static void -etharp_remove_all(void) -{ - int i; - /* call etharp_tmr often enough to have all entries cleaned */ - for(i = 0; i < 0xff; i++) { - etharp_tmr(); - } -} - -static err_t -default_netif_linkoutput(struct netif *netif, struct pbuf *p) -{ - fail_unless(netif == &test_netif); - fail_unless(p != NULL); - linkoutput_ctr++; - return ERR_OK; -} - -static err_t -default_netif_init(struct netif *netif) -{ - fail_unless(netif != NULL); - netif->linkoutput = default_netif_linkoutput; - netif->output = etharp_output; - netif->mtu = 1500; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; - netif->hwaddr_len = ETHARP_HWADDR_LEN; - return ERR_OK; -} - -static void -default_netif_add(void) -{ - IP4_ADDR(&test_gw, 192,168,0,1); - IP4_ADDR(&test_ipaddr, 192,168,0,1); - IP4_ADDR(&test_netmask, 255,255,0,0); - - fail_unless(netif_default == NULL); - netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask, - &test_gw, NULL, default_netif_init, NULL)); - netif_set_up(&test_netif); -} - -static void -default_netif_remove(void) -{ - fail_unless(netif_default == &test_netif); - netif_remove(&test_netif); -} - -static void -create_arp_response(ip_addr_t *adr) -{ - int k; - struct eth_hdr *ethhdr; - struct etharp_hdr *etharphdr; - struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM); - if(p == NULL) { - FAIL_RET(); - } - ethhdr = (struct eth_hdr*)p->payload; - etharphdr = (struct etharp_hdr*)(ethhdr + 1); - - ethhdr->dest = test_ethaddr; - ethhdr->src = test_ethaddr2; - ethhdr->type = htons(ETHTYPE_ARP); - - etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1); - etharphdr->proto = htons(ETHTYPE_IP); - etharphdr->hwlen = ETHARP_HWADDR_LEN; - etharphdr->protolen = sizeof(ip_addr_t); - etharphdr->opcode = htons(ARP_REPLY); - - SMEMCPY(ðarphdr->sipaddr, adr, sizeof(ip_addr_t)); - SMEMCPY(ðarphdr->dipaddr, &test_ipaddr, sizeof(ip_addr_t)); - - k = 6; - while(k > 0) { - k--; - /* Write the ARP MAC-Addresses */ - etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k]; - etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k]; - /* Write the Ethernet MAC-Addresses */ - ethhdr->dest.addr[k] = test_ethaddr.addr[k]; - ethhdr->src.addr[k] = test_ethaddr2.addr[k]; - } - - ethernet_input(p, &test_netif); -} - -/* Setups/teardown functions */ - -static void -etharp_setup(void) -{ - etharp_remove_all(); - default_netif_add(); -} - -static void -etharp_teardown(void) -{ - etharp_remove_all(); - default_netif_remove(); -} - - -/* Test functions */ - -START_TEST(test_etharp_table) -{ -#if ETHARP_SUPPORT_STATIC_ENTRIES - err_t err; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - s8_t idx; - ip_addr_t *unused_ipaddr; - struct eth_addr *unused_ethaddr; - struct udp_pcb* pcb; - LWIP_UNUSED_ARG(_i); - - if (netif_default != &test_netif) { - fail("This test needs a default netif"); - } - - linkoutput_ctr = 0; - - pcb = udp_new(); - fail_unless(pcb != NULL); - if (pcb != NULL) { - ip_addr_t adrs[ARP_TABLE_SIZE + 2]; - int i; - for(i = 0; i < ARP_TABLE_SIZE + 2; i++) { - IP4_ADDR(&adrs[i], 192,168,0,i+2); - } - /* fill ARP-table with dynamic entries */ - for(i = 0; i < ARP_TABLE_SIZE; i++) { - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); - fail_unless(p != NULL); - if (p != NULL) { - err_t err = udp_sendto(pcb, p, &adrs[i], 123); - fail_unless(err == ERR_OK); - /* etharp request sent? */ - fail_unless(linkoutput_ctr == (2*i) + 1); - pbuf_free(p); - - /* create an ARP response */ - create_arp_response(&adrs[i]); - /* queued UDP packet sent? */ - fail_unless(linkoutput_ctr == (2*i) + 2); - - idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == i); - etharp_tmr(); - } - } - linkoutput_ctr = 0; -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* create one static entry */ - err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3); - fail_unless(err == ERR_OK); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == 0); - fail_unless(linkoutput_ctr == 0); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - - linkoutput_ctr = 0; - /* fill ARP-table with dynamic entries */ - for(i = 0; i < ARP_TABLE_SIZE; i++) { - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); - fail_unless(p != NULL); - if (p != NULL) { - err_t err = udp_sendto(pcb, p, &adrs[i], 123); - fail_unless(err == ERR_OK); - /* etharp request sent? */ - fail_unless(linkoutput_ctr == (2*i) + 1); - pbuf_free(p); - - /* create an ARP response */ - create_arp_response(&adrs[i]); - /* queued UDP packet sent? */ - fail_unless(linkoutput_ctr == (2*i) + 2); - - idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); - if (i < ARP_TABLE_SIZE - 1) { - fail_unless(idx == i+1); - } else { - /* the last entry must not overwrite the static entry! */ - fail_unless(idx == 1); - } - etharp_tmr(); - } - } -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* create a second static entry */ - err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4); - fail_unless(err == ERR_OK); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == 0); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == 2); - /* and remove it again */ - err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]); - fail_unless(err == ERR_OK); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == 0); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == -1); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - - /* check that static entries don't time out */ - etharp_remove_all(); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == 0); - -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* remove the first static entry */ - err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]); - fail_unless(err == ERR_OK); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == -1); - idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); - fail_unless(idx == -1); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - - udp_remove(pcb); - } -} -END_TEST - - -/** Create the suite including all tests for this module */ -Suite * -etharp_suite(void) -{ - TFun tests[] = { - test_etharp_table - }; - return create_suite("ETHARP", tests, sizeof(tests)/sizeof(TFun), etharp_setup, etharp_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.h b/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.h deleted file mode 100644 index 96e00c3..0000000 --- a/external/badvpn_dns/lwip/test/unit/etharp/test_etharp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_ETHARP_H__ -#define __TEST_ETHARP_H__ - -#include "../lwip_check.h" - -Suite* etharp_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/lwip_check.h b/external/badvpn_dns/lwip/test/unit/lwip_check.h deleted file mode 100644 index e27f55a..0000000 --- a/external/badvpn_dns/lwip/test/unit/lwip_check.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __LWIP_CHECK_H__ -#define __LWIP_CHECK_H__ - -/* Common header file for lwIP unit tests using the check framework */ - -#include <config.h> -#include <check.h> -#include <stdlib.h> - -#define FAIL_RET() do { fail(); return; } while(0) -#define EXPECT(x) fail_unless(x) -#define EXPECT_RET(x) do { fail_unless(x); if(!(x)) { return; }} while(0) -#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0) -#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL) - -/** typedef for a function returning a test suite */ -typedef Suite* (suite_getter_fn)(void); - -/** Create a test suite */ -static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun setup, SFun teardown) -{ - size_t i; - Suite *s = suite_create(name); - - for(i = 0; i < num_tests; i++) { - /* Core test case */ - TCase *tc_core = tcase_create("Core"); - if ((setup != NULL) || (teardown != NULL)) { - tcase_add_checked_fixture(tc_core, setup, teardown); - } - tcase_add_test(tc_core, tests[i]); - suite_add_tcase(s, tc_core); - } - return s; -} - -#endif /* __LWIP_CHECK_H__ */ diff --git a/external/badvpn_dns/lwip/test/unit/lwip_unittests.c b/external/badvpn_dns/lwip/test/unit/lwip_unittests.c deleted file mode 100644 index 41d1f36..0000000 --- a/external/badvpn_dns/lwip/test/unit/lwip_unittests.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "lwip_check.h" - -#include "udp/test_udp.h" -#include "tcp/test_tcp.h" -#include "tcp/test_tcp_oos.h" -#include "core/test_mem.h" -#include "core/test_pbuf.h" -#include "etharp/test_etharp.h" -#include "dhcp/test_dhcp.h" - -#include "lwip/init.h" - - -int main() -{ - int number_failed; - SRunner *sr; - size_t i; - suite_getter_fn* suites[] = { - udp_suite, - tcp_suite, - tcp_oos_suite, - mem_suite, - pbuf_suite, - etharp_suite, - dhcp_suite - }; - size_t num = sizeof(suites)/sizeof(void*); - LWIP_ASSERT("No suites defined", num > 0); - - lwip_init(); - - sr = srunner_create((suites[0])()); - for(i = 1; i < num; i++) { - srunner_add_suite(sr, ((suite_getter_fn*)suites[i])()); - } - -#ifdef LWIP_UNITTESTS_NOFORK - srunner_set_fork_status(sr, CK_NOFORK); -#endif -#ifdef LWIP_UNITTESTS_FORK - srunner_set_fork_status(sr, CK_FORK); -#endif - - srunner_run_all(sr, CK_NORMAL); - number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/external/badvpn_dns/lwip/test/unit/lwipopts.h b/external/badvpn_dns/lwip/test/unit/lwipopts.h deleted file mode 100644 index 0059515..0000000 --- a/external/badvpn_dns/lwip/test/unit/lwipopts.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - -/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ -#define NO_SYS 1 -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 - -/* Enable DHCP to test it, disable UDP checksum to easier inject packets */ -#define LWIP_DHCP 1 - -/* Minimal changes to opt.h required for tcp unit tests: */ -#define MEM_SIZE 16000 -#define TCP_SND_QUEUELEN 40 -#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN -#define TCP_SND_BUF (12 * TCP_MSS) -#define TCP_WND (10 * TCP_MSS) - -/* Minimal changes to opt.h required for etharp unit tests: */ -#define ETHARP_SUPPORT_STATIC_ENTRIES 1 - -#endif /* __LWIPOPTS_H__ */ diff --git a/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.c b/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.c deleted file mode 100644 index ff503db..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.c +++ /dev/null @@ -1,303 +0,0 @@ -#include "tcp_helper.h" - -#include "lwip/tcp_impl.h" -#include "lwip/stats.h" -#include "lwip/pbuf.h" -#include "lwip/inet_chksum.h" - -#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS -#error "This tests needs TCP- and MEMP-statistics enabled" -#endif - -/** Remove all pcbs on the given list. */ -static void -tcp_remove(struct tcp_pcb* pcb_list) -{ - struct tcp_pcb *pcb = pcb_list; - struct tcp_pcb *pcb2; - - while(pcb != NULL) { - pcb2 = pcb; - pcb = pcb->next; - tcp_abort(pcb2); - } -} - -/** Remove all pcbs on listen-, active- and time-wait-list (bound- isn't exported). */ -void -tcp_remove_all(void) -{ - tcp_remove(tcp_listen_pcbs.pcbs); - tcp_remove(tcp_active_pcbs); - tcp_remove(tcp_tw_pcbs); - fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); - fail_unless(lwip_stats.memp[MEMP_TCP_PCB_LISTEN].used == 0); - fail_unless(lwip_stats.memp[MEMP_TCP_SEG].used == 0); - fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0); -} - -/** Create a TCP segment usable for passing to tcp_input */ -static struct pbuf* -tcp_create_segment_wnd(ip_addr_t* src_ip, ip_addr_t* dst_ip, - u16_t src_port, u16_t dst_port, void* data, size_t data_len, - u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd) -{ - struct pbuf *p, *q; - struct ip_hdr* iphdr; - struct tcp_hdr* tcphdr; - u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len); - - p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL); - EXPECT_RETNULL(p != NULL); - /* first pbuf must be big enough to hold the headers */ - EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); - if (data_len > 0) { - /* first pbuf must be big enough to hold at least 1 data byte, too */ - EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); - } - - for(q = p; q != NULL; q = q->next) { - memset(q->payload, 0, q->len); - } - - iphdr = p->payload; - /* fill IP header */ - iphdr->dest.addr = dst_ip->addr; - iphdr->src.addr = src_ip->addr; - IPH_VHL_SET(iphdr, 4, IP_HLEN / 4); - IPH_TOS_SET(iphdr, 0); - IPH_LEN_SET(iphdr, htons(p->tot_len)); - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); - - /* let p point to TCP header */ - pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); - - tcphdr = p->payload; - tcphdr->src = htons(src_port); - tcphdr->dest = htons(dst_port); - tcphdr->seqno = htonl(seqno); - tcphdr->ackno = htonl(ackno); - TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4); - TCPH_FLAGS_SET(tcphdr, headerflags); - tcphdr->wnd = htons(wnd); - - if (data_len > 0) { - /* let p point to TCP data */ - pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr)); - /* copy data */ - pbuf_take(p, data, data_len); - /* let p point to TCP header again */ - pbuf_header(p, sizeof(struct tcp_hdr)); - } - - /* calculate checksum */ - - tcphdr->chksum = inet_chksum_pseudo(p, - IP_PROTO_TCP, p->tot_len, src_ip, dst_ip); - - pbuf_header(p, sizeof(struct ip_hdr)); - - return p; -} - -/** Create a TCP segment usable for passing to tcp_input */ -struct pbuf* -tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, - u16_t src_port, u16_t dst_port, void* data, size_t data_len, - u32_t seqno, u32_t ackno, u8_t headerflags) -{ - return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data, - data_len, seqno, ackno, headerflags, TCP_WND); -} - -/** Create a TCP segment usable for passing to tcp_input - * - IP-addresses, ports, seqno and ackno are taken from pcb - * - seqno and ackno can be altered with an offset - */ -struct pbuf* -tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, - u32_t ackno_offset, u8_t headerflags) -{ - return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, - data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags); -} - -/** Create a TCP segment usable for passing to tcp_input - * - IP-addresses, ports, seqno and ackno are taken from pcb - * - seqno and ackno can be altered with an offset - * - TCP window can be adjusted - */ -struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, - u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd) -{ - return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, - data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd); -} - -/** Safely bring a tcp_pcb into the requested state */ -void -tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, - ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port) -{ - /* @todo: are these all states? */ - /* @todo: remove from previous list */ - pcb->state = state; - if (state == ESTABLISHED) { - TCP_REG(&tcp_active_pcbs, pcb); - pcb->local_ip.addr = local_ip->addr; - pcb->local_port = local_port; - pcb->remote_ip.addr = remote_ip->addr; - pcb->remote_port = remote_port; - } else if(state == LISTEN) { - TCP_REG(&tcp_listen_pcbs.pcbs, pcb); - pcb->local_ip.addr = local_ip->addr; - pcb->local_port = local_port; - } else if(state == TIME_WAIT) { - TCP_REG(&tcp_tw_pcbs, pcb); - pcb->local_ip.addr = local_ip->addr; - pcb->local_port = local_port; - pcb->remote_ip.addr = remote_ip->addr; - pcb->remote_port = remote_port; - } else { - fail(); - } -} - -void -test_tcp_counters_err(void* arg, err_t err) -{ - struct test_tcp_counters* counters = arg; - EXPECT_RET(arg != NULL); - counters->err_calls++; - counters->last_err = err; -} - -static void -test_tcp_counters_check_rxdata(struct test_tcp_counters* counters, struct pbuf* p) -{ - struct pbuf* q; - u32_t i, received; - if(counters->expected_data == NULL) { - /* no data to compare */ - return; - } - EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len); - received = counters->recved_bytes; - for(q = p; q != NULL; q = q->next) { - char *data = q->payload; - for(i = 0; i < q->len; i++) { - EXPECT_RET(data[i] == counters->expected_data[received]); - received++; - } - } - EXPECT(received == counters->recved_bytes + p->tot_len); -} - -err_t -test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) -{ - struct test_tcp_counters* counters = arg; - EXPECT_RETX(arg != NULL, ERR_OK); - EXPECT_RETX(pcb != NULL, ERR_OK); - EXPECT_RETX(err == ERR_OK, ERR_OK); - - if (p != NULL) { - if (counters->close_calls == 0) { - counters->recv_calls++; - test_tcp_counters_check_rxdata(counters, p); - counters->recved_bytes += p->tot_len; - } else { - counters->recv_calls_after_close++; - counters->recved_bytes_after_close += p->tot_len; - } - pbuf_free(p); - } else { - counters->close_calls++; - } - EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0); - return ERR_OK; -} - -/** Allocate a pcb and set up the test_tcp_counters_* callbacks */ -struct tcp_pcb* -test_tcp_new_counters_pcb(struct test_tcp_counters* counters) -{ - struct tcp_pcb* pcb = tcp_new(); - if (pcb != NULL) { - /* set up args and callbacks */ - tcp_arg(pcb, counters); - tcp_recv(pcb, test_tcp_counters_recv); - tcp_err(pcb, test_tcp_counters_err); - pcb->snd_wnd = TCP_WND; - pcb->snd_wnd_max = TCP_WND; - } - return pcb; -} - -/** Calls tcp_input() after adjusting current_iphdr_dest */ -void test_tcp_input(struct pbuf *p, struct netif *inp) -{ - struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; - /* these lines are a hack, don't use them as an example :-) */ - ip_addr_copy(*ipX_current_dest_addr(), iphdr->dest); - ip_addr_copy(*ipX_current_src_addr(), iphdr->src); - ip_current_netif() = inp; - ip_current_header() = iphdr; - - /* since adding IPv6, p->payload must point to tcp header, not ip header */ - pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); - - tcp_input(p, inp); - - ipX_current_dest_addr()->addr = 0; - ipX_current_src_addr()->addr = 0; - ip_current_netif() = NULL; - ip_current_header() = NULL; -} - -static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr) -{ - struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state; - LWIP_UNUSED_ARG(ipaddr); - if (txcounters != NULL) - { - txcounters->num_tx_calls++; - txcounters->num_tx_bytes += p->tot_len; - if (txcounters->copy_tx_packets) { - struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - err_t err; - EXPECT(p_copy != NULL); - err = pbuf_copy(p_copy, p); - EXPECT(err == ERR_OK); - if (txcounters->tx_packets == NULL) { - txcounters->tx_packets = p_copy; - } else { - pbuf_cat(txcounters->tx_packets, p_copy); - } - } - } - return ERR_OK; -} - -void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, - ip_addr_t *ip_addr, ip_addr_t *netmask) -{ - struct netif *n; - memset(netif, 0, sizeof(struct netif)); - if (txcounters != NULL) { - memset(txcounters, 0, sizeof(struct test_tcp_txcounters)); - netif->state = txcounters; - } - netif->output = test_tcp_netif_output; - netif->flags |= NETIF_FLAG_UP; - ip_addr_copy(netif->netmask, *netmask); - ip_addr_copy(netif->ip_addr, *ip_addr); - for (n = netif_list; n != NULL; n = n->next) { - if (n == netif) { - return; - } - } - netif->next = NULL; - netif_list = netif; -} diff --git a/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.h b/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.h deleted file mode 100644 index 4a72c93..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/tcp_helper.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __TCP_HELPER_H__ -#define __TCP_HELPER_H__ - -#include "../lwip_check.h" -#include "lwip/arch.h" -#include "lwip/tcp.h" -#include "lwip/netif.h" - -/* counters used for test_tcp_counters_* callback functions */ -struct test_tcp_counters { - u32_t recv_calls; - u32_t recved_bytes; - u32_t recv_calls_after_close; - u32_t recved_bytes_after_close; - u32_t close_calls; - u32_t err_calls; - err_t last_err; - char* expected_data; - u32_t expected_data_len; -}; - -struct test_tcp_txcounters { - u32_t num_tx_calls; - u32_t num_tx_bytes; - u8_t copy_tx_packets; - struct pbuf *tx_packets; -}; - -/* Helper functions */ -void tcp_remove_all(void); - -struct pbuf* tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, - u16_t src_port, u16_t dst_port, void* data, size_t data_len, - u32_t seqno, u32_t ackno, u8_t headerflags); -struct pbuf* tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, - u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags); -struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, - u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd); -void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, - ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port); -void test_tcp_counters_err(void* arg, err_t err); -err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err); - -struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters); - -void test_tcp_input(struct pbuf *p, struct netif *inp); - -void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, - ip_addr_t *ip_addr, ip_addr_t *netmask); - - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.c b/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.c deleted file mode 100644 index 8172098..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.c +++ /dev/null @@ -1,671 +0,0 @@ -#include "test_tcp.h" - -#include "lwip/tcp_impl.h" -#include "lwip/stats.h" -#include "tcp_helper.h" - -#ifdef _MSC_VER -#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */ -#endif - -#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS -#error "This tests needs TCP- and MEMP-statistics enabled" -#endif -#if TCP_SND_BUF <= TCP_WND -#error "This tests needs TCP_SND_BUF to be > TCP_WND" -#endif - -static u8_t test_tcp_timer; - -/* our own version of tcp_tmr so we can reset fast/slow timer state */ -static void -test_tcp_tmr(void) -{ - tcp_fasttmr(); - if (++test_tcp_timer & 1) { - tcp_slowtmr(); - } -} - -/* Setups/teardown functions */ - -static void -tcp_setup(void) -{ - /* reset iss to default (6510) */ - tcp_ticks = 0; - tcp_ticks = 0 - (tcp_next_iss() - 6510); - tcp_next_iss(); - tcp_ticks = 0; - - test_tcp_timer = 0; - tcp_remove_all(); -} - -static void -tcp_teardown(void) -{ - tcp_remove_all(); - netif_list = NULL; - netif_default = NULL; -} - - -/* Test functions */ - -/** Call tcp_new() and tcp_abort() and test memp stats */ -START_TEST(test_tcp_new_abort) -{ - struct tcp_pcb* pcb; - LWIP_UNUSED_ARG(_i); - - fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); - - pcb = tcp_new(); - fail_unless(pcb != NULL); - if (pcb != NULL) { - fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); - } -} -END_TEST - -/** Create an ESTABLISHED pcb and check if receive callback is called */ -START_TEST(test_tcp_recv_inseq) -{ - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf* p; - char data[] = {1, 2, 3, 4}; - ip_addr_t remote_ip, local_ip, netmask; - u16_t data_len; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - struct test_tcp_txcounters txcounters; - LWIP_UNUSED_ARG(_i); - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); - data_len = sizeof(data); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = data_len; - counters.expected_data = data; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - - /* create a segment */ - p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0); - EXPECT(p != NULL); - if (p != NULL) { - /* pass the segment to tcp_input */ - test_tcp_input(p, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 1); - EXPECT(counters.recved_bytes == data_len); - EXPECT(counters.err_calls == 0); - } - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - -/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. - * At the end, send more data. */ -START_TEST(test_tcp_fast_retx_recover) -{ - struct netif netif; - struct test_tcp_txcounters txcounters; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf* p; - char data1[] = { 1, 2, 3, 4}; - char data2[] = { 5, 6, 7, 8}; - char data3[] = { 9, 10, 11, 12}; - char data4[] = {13, 14, 15, 16}; - char data5[] = {17, 18, 19, 20}; - char data6[] = {21, 22, 23, 24}; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - err_t err; - LWIP_UNUSED_ARG(_i); - - /* initialize local vars */ - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); - memset(&counters, 0, sizeof(counters)); - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->mss = TCP_MSS; - /* disable initial congestion window (we don't send a SYN here...) */ - pcb->cwnd = pcb->snd_wnd; - - /* send data1 */ - err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT_RET(txcounters.num_tx_calls == 1); - EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); - memset(&txcounters, 0, sizeof(txcounters)); - /* "recv" ACK for data1 */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK); - EXPECT_RET(p != NULL); - test_tcp_input(p, &netif); - EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(pcb->unacked == NULL); - /* send data2 */ - err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT_RET(txcounters.num_tx_calls == 1); - EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); - memset(&txcounters, 0, sizeof(txcounters)); - /* duplicate ACK for data1 (data2 is lost) */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - EXPECT_RET(p != NULL); - test_tcp_input(p, &netif); - EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(pcb->dupacks == 1); - /* send data3 */ - err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /* nagle enabled, no tx calls */ - EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(txcounters.num_tx_bytes == 0); - memset(&txcounters, 0, sizeof(txcounters)); - /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - EXPECT_RET(p != NULL); - test_tcp_input(p, &netif); - EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(pcb->dupacks == 2); - /* queue data4, don't send it (unsent-oversize is != 0) */ - err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - EXPECT_RET(p != NULL); - test_tcp_input(p, &netif); - /*EXPECT_RET(txcounters.num_tx_calls == 1);*/ - EXPECT_RET(pcb->dupacks == 3); - memset(&txcounters, 0, sizeof(txcounters)); - /* TODO: check expected data?*/ - - /* send data5, not output yet */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - /*err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK);*/ - EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(txcounters.num_tx_bytes == 0); - memset(&txcounters, 0, sizeof(txcounters)); - { - int i = 0; - do - { - err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY); - i++; - }while(err == ERR_OK); - EXPECT_RET(err != ERR_OK); - } - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /*EXPECT_RET(txcounters.num_tx_calls == 0); - EXPECT_RET(txcounters.num_tx_bytes == 0);*/ - memset(&txcounters, 0, sizeof(txcounters)); - - /* send even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /* ...and even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /* ...and even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /* ...and even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - - /* send ACKs for data2 and data3 */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK); - EXPECT_RET(p != NULL); - test_tcp_input(p, &netif); - /*EXPECT_RET(txcounters.num_tx_calls == 0);*/ - - /* ...and even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - /* ...and even more data */ - err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - -#if 0 - /* create expected segment */ - p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0); - EXPECT_RET(p != NULL); - if (p != NULL) { - /* pass the segment to tcp_input */ - test_tcp_input(p, &netif); - /* check if counters are as expected */ - EXPECT_RET(counters.close_calls == 0); - EXPECT_RET(counters.recv_calls == 1); - EXPECT_RET(counters.recved_bytes == data_len); - EXPECT_RET(counters.err_calls == 0); - } -#endif - /* make sure the pcb is freed */ - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - -static u8_t tx_data[TCP_WND*2]; - -static void -check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected) -{ - struct tcp_seg *s = segs; - int i; - for (i = 0; i < num_expected; i++, s = s->next) { - EXPECT_RET(s != NULL); - EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i])); - } - EXPECT(s == NULL); -} - -/** Send data with sequence numbers that wrap around the u32_t range. - * Then, provoke fast retransmission by duplicate ACKs and check that all - * segment lists are still properly sorted. */ -START_TEST(test_tcp_fast_rexmit_wraparound) -{ - struct netif netif; - struct test_tcp_txcounters txcounters; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf* p; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - err_t err; -#define SEQNO1 (0xFFFFFF00 - TCP_MSS) -#define ISS 6510 - u16_t i, sent_total = 0; - u32_t seqnos[] = { - SEQNO1, - SEQNO1 + (1 * TCP_MSS), - SEQNO1 + (2 * TCP_MSS), - SEQNO1 + (3 * TCP_MSS), - SEQNO1 + (4 * TCP_MSS), - SEQNO1 + (5 * TCP_MSS)}; - LWIP_UNUSED_ARG(_i); - - for (i = 0; i < sizeof(tx_data); i++) { - tx_data[i] = (u8_t)i; - } - - /* initialize local vars */ - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); - memset(&counters, 0, sizeof(counters)); - - /* create and initialize the pcb */ - tcp_ticks = SEQNO1 - ISS; - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - EXPECT(pcb->lastack == SEQNO1); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->mss = TCP_MSS; - /* disable initial congestion window (we don't send a SYN here...) */ - pcb->cwnd = 2*TCP_MSS; - - /* send 6 mss-sized segments */ - for (i = 0; i < 6; i++) { - err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - sent_total += TCP_MSS; - } - check_seqnos(pcb->unsent, 6, seqnos); - EXPECT(pcb->unacked == NULL); - err = tcp_output(pcb); - EXPECT(txcounters.num_tx_calls == 2); - EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); - memset(&txcounters, 0, sizeof(txcounters)); - - check_seqnos(pcb->unacked, 2, seqnos); - check_seqnos(pcb->unsent, 4, &seqnos[2]); - - /* ACK the first segment */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK); - test_tcp_input(p, &netif); - /* ensure this didn't trigger a retransmission */ - EXPECT(txcounters.num_tx_calls == 1); - EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); - memset(&txcounters, 0, sizeof(txcounters)); - check_seqnos(pcb->unacked, 2, &seqnos[1]); - check_seqnos(pcb->unsent, 3, &seqnos[3]); - - /* 3 dupacks */ - EXPECT(pcb->dupacks == 0); - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - test_tcp_input(p, &netif); - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(pcb->dupacks == 1); - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - test_tcp_input(p, &netif); - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(pcb->dupacks == 2); - /* 3rd dupack -> fast rexmit */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - test_tcp_input(p, &netif); - EXPECT(pcb->dupacks == 3); - EXPECT(txcounters.num_tx_calls == 4); - memset(&txcounters, 0, sizeof(txcounters)); - EXPECT(pcb->unsent == NULL); - check_seqnos(pcb->unacked, 5, &seqnos[1]); - - /* make sure the pcb is freed */ - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - -/** Send data with sequence numbers that wrap around the u32_t range. - * Then, provoke RTO retransmission and check that all - * segment lists are still properly sorted. */ -START_TEST(test_tcp_rto_rexmit_wraparound) -{ - struct netif netif; - struct test_tcp_txcounters txcounters; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - err_t err; -#define SEQNO1 (0xFFFFFF00 - TCP_MSS) -#define ISS 6510 - u16_t i, sent_total = 0; - u32_t seqnos[] = { - SEQNO1, - SEQNO1 + (1 * TCP_MSS), - SEQNO1 + (2 * TCP_MSS), - SEQNO1 + (3 * TCP_MSS), - SEQNO1 + (4 * TCP_MSS), - SEQNO1 + (5 * TCP_MSS)}; - LWIP_UNUSED_ARG(_i); - - for (i = 0; i < sizeof(tx_data); i++) { - tx_data[i] = (u8_t)i; - } - - /* initialize local vars */ - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); - memset(&counters, 0, sizeof(counters)); - - /* create and initialize the pcb */ - tcp_ticks = 0; - tcp_ticks = 0 - tcp_next_iss(); - tcp_ticks = SEQNO1 - tcp_next_iss(); - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - EXPECT(pcb->lastack == SEQNO1); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->mss = TCP_MSS; - /* disable initial congestion window (we don't send a SYN here...) */ - pcb->cwnd = 2*TCP_MSS; - - /* send 6 mss-sized segments */ - for (i = 0; i < 6; i++) { - err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - sent_total += TCP_MSS; - } - check_seqnos(pcb->unsent, 6, seqnos); - EXPECT(pcb->unacked == NULL); - err = tcp_output(pcb); - EXPECT(txcounters.num_tx_calls == 2); - EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); - memset(&txcounters, 0, sizeof(txcounters)); - - check_seqnos(pcb->unacked, 2, seqnos); - check_seqnos(pcb->unsent, 4, &seqnos[2]); - - /* call the tcp timer some times */ - for (i = 0; i < 10; i++) { - test_tcp_tmr(); - EXPECT(txcounters.num_tx_calls == 0); - } - /* 11th call to tcp_tmr: RTO rexmit fires */ - test_tcp_tmr(); - EXPECT(txcounters.num_tx_calls == 1); - check_seqnos(pcb->unacked, 1, seqnos); - check_seqnos(pcb->unsent, 5, &seqnos[1]); - - /* fake greater cwnd */ - pcb->cwnd = pcb->snd_wnd; - /* send more data */ - err = tcp_output(pcb); - EXPECT(err == ERR_OK); - /* check queues are sorted */ - EXPECT(pcb->unsent == NULL); - check_seqnos(pcb->unacked, 6, seqnos); - - /* make sure the pcb is freed */ - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - -/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. - * At the end, send more data. */ -static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent) -{ - struct netif netif; - struct test_tcp_txcounters txcounters; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - err_t err; - u16_t sent_total, i; - u8_t expected = 0xFE; - - for (i = 0; i < sizeof(tx_data); i++) { - u8_t d = (u8_t)i; - if (d == 0xFE) { - d = 0xF0; - } - tx_data[i] = d; - } - if (zero_window_probe_from_unsent) { - tx_data[TCP_WND] = expected; - } else { - tx_data[0] = expected; - } - - /* initialize local vars */ - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); - memset(&counters, 0, sizeof(counters)); - memset(&txcounters, 0, sizeof(txcounters)); - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->mss = TCP_MSS; - /* disable initial congestion window (we don't send a SYN here...) */ - pcb->cwnd = pcb->snd_wnd; - - /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */ - sent_total = 0; - if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) { - u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS; - err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT(txcounters.num_tx_calls == 1); - EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U); - memset(&txcounters, 0, sizeof(txcounters)); - sent_total += initial_data_len; - } - for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) { - err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT(txcounters.num_tx_calls == 1); - EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); - memset(&txcounters, 0, sizeof(txcounters)); - } - EXPECT(sent_total == (TCP_WND - TCP_MSS)); - - /* now ACK the packet before the first */ - p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); - test_tcp_input(p, &netif); - /* ensure this didn't trigger a retransmission */ - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(txcounters.num_tx_bytes == 0); - - EXPECT(pcb->persist_backoff == 0); - /* send the last packet, now a complete window has been sent */ - err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); - sent_total += TCP_MSS; - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT(txcounters.num_tx_calls == 1); - EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); - memset(&txcounters, 0, sizeof(txcounters)); - EXPECT(pcb->persist_backoff == 0); - - if (zero_window_probe_from_unsent) { - /* ACK all data but close the TX window */ - p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0); - test_tcp_input(p, &netif); - /* ensure this didn't trigger any transmission */ - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(txcounters.num_tx_bytes == 0); - EXPECT(pcb->persist_backoff == 1); - } - - /* send one byte more (out of window) -> persist timer starts */ - err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY); - EXPECT_RET(err == ERR_OK); - err = tcp_output(pcb); - EXPECT_RET(err == ERR_OK); - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(txcounters.num_tx_bytes == 0); - memset(&txcounters, 0, sizeof(txcounters)); - if (!zero_window_probe_from_unsent) { - /* no persist timer unless a zero window announcement has been received */ - EXPECT(pcb->persist_backoff == 0); - } else { - EXPECT(pcb->persist_backoff == 1); - - /* call tcp_timer some more times to let persist timer count up */ - for (i = 0; i < 4; i++) { - test_tcp_tmr(); - EXPECT(txcounters.num_tx_calls == 0); - EXPECT(txcounters.num_tx_bytes == 0); - } - - /* this should trigger the zero-window-probe */ - txcounters.copy_tx_packets = 1; - test_tcp_tmr(); - txcounters.copy_tx_packets = 0; - EXPECT(txcounters.num_tx_calls == 1); - EXPECT(txcounters.num_tx_bytes == 1 + 40U); - EXPECT(txcounters.tx_packets != NULL); - if (txcounters.tx_packets != NULL) { - u8_t sent; - u16_t ret; - ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U); - EXPECT(ret == 1); - EXPECT(sent == expected); - } - if (txcounters.tx_packets != NULL) { - pbuf_free(txcounters.tx_packets); - txcounters.tx_packets = NULL; - } - } - - /* make sure the pcb is freed */ - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} - -START_TEST(test_tcp_tx_full_window_lost_from_unsent) -{ - LWIP_UNUSED_ARG(_i); - test_tcp_tx_full_window_lost(1); -} -END_TEST - -START_TEST(test_tcp_tx_full_window_lost_from_unacked) -{ - LWIP_UNUSED_ARG(_i); - test_tcp_tx_full_window_lost(0); -} -END_TEST - -/** Create the suite including all tests for this module */ -Suite * -tcp_suite(void) -{ - TFun tests[] = { - test_tcp_new_abort, - test_tcp_recv_inseq, - test_tcp_fast_retx_recover, - test_tcp_fast_rexmit_wraparound, - test_tcp_rto_rexmit_wraparound, - test_tcp_tx_full_window_lost_from_unacked, - test_tcp_tx_full_window_lost_from_unsent - }; - return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.h b/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.h deleted file mode 100644 index f1c4a46..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_TCP_H__ -#define __TEST_TCP_H__ - -#include "../lwip_check.h" - -Suite *tcp_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.c b/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.c deleted file mode 100644 index 612c468..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.c +++ /dev/null @@ -1,958 +0,0 @@ -#include "test_tcp_oos.h" - -#include "lwip/tcp_impl.h" -#include "lwip/stats.h" -#include "tcp_helper.h" - -#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS -#error "This tests needs TCP- and MEMP-statistics enabled" -#endif -#if !TCP_QUEUE_OOSEQ -#error "This tests needs TCP_QUEUE_OOSEQ enabled" -#endif - -/** CHECK_SEGMENTS_ON_OOSEQ: - * 1: check count, seqno and len of segments on pcb->ooseq (strict) - * 0: only check that bytes are received in correct order (less strict) */ -#define CHECK_SEGMENTS_ON_OOSEQ 1 - -#if CHECK_SEGMENTS_ON_OOSEQ -#define EXPECT_OOSEQ(x) EXPECT(x) -#else -#define EXPECT_OOSEQ(x) -#endif - -/* helper functions */ - -/** Get the numbers of segments on the ooseq list */ -static int tcp_oos_count(struct tcp_pcb* pcb) -{ - int num = 0; - struct tcp_seg* seg = pcb->ooseq; - while(seg != NULL) { - num++; - seg = seg->next; - } - return num; -} - -/** Get the numbers of pbufs on the ooseq list */ -static int tcp_oos_pbuf_count(struct tcp_pcb* pcb) -{ - int num = 0; - struct tcp_seg* seg = pcb->ooseq; - while(seg != NULL) { - num += pbuf_clen(seg->p); - seg = seg->next; - } - return num; -} - -/** Get the seqno of a segment (by index) on the ooseq list - * - * @param pcb the pcb to check for ooseq segments - * @param seg_index index of the segment on the ooseq list - * @return seqno of the segment - */ -static u32_t -tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index) -{ - int num = 0; - struct tcp_seg* seg = pcb->ooseq; - - /* then check the actual segment */ - while(seg != NULL) { - if(num == seg_index) { - return seg->tcphdr->seqno; - } - num++; - seg = seg->next; - } - fail(); - return 0; -} - -/** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list - * - * @param pcb the pcb to check for ooseq segments - * @param seg_index index of the segment on the ooseq list - * @return tcplen of the segment - */ -static int -tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index) -{ - int num = 0; - struct tcp_seg* seg = pcb->ooseq; - - /* then check the actual segment */ - while(seg != NULL) { - if(num == seg_index) { - return TCP_TCPLEN(seg); - } - num++; - seg = seg->next; - } - fail(); - return -1; -} - -/** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list - * - * @param pcb the pcb to check for ooseq segments - * @return tcplen of all segment - */ -static int -tcp_oos_tcplen(struct tcp_pcb* pcb) -{ - int len = 0; - struct tcp_seg* seg = pcb->ooseq; - - /* then check the actual segment */ - while(seg != NULL) { - len += TCP_TCPLEN(seg); - seg = seg->next; - } - return len; -} - -/* Setup/teardown functions */ - -static void -tcp_oos_setup(void) -{ - tcp_remove_all(); -} - -static void -tcp_oos_teardown(void) -{ - tcp_remove_all(); - netif_list = NULL; - netif_default = NULL; -} - - - -/* Test functions */ - -/** create multiple segments and pass them to tcp_input in a wrong - * order to see if ooseq-caching works correctly - * FIN is received in out-of-sequence segments only */ -START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) -{ - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq; - char data[] = { - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 10, 11, 12, - 13, 14, 15, 16}; - ip_addr_t remote_ip, local_ip, netmask; - u16_t data_len; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - LWIP_UNUSED_ARG(_i); - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - data_len = sizeof(data); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = data_len; - counters.expected_data = data; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - - /* create segments */ - /* pinseq is sent as last segment! */ - pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); - /* p1: 8 bytes before FIN */ - /* seqno: 8..16 */ - p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN); - /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ - /* seqno: 4..11 */ - p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); - /* p3: same as p2 but 2 bytes longer */ - /* seqno: 4..13 */ - p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK); - /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */ - /* seqno: 2..15 */ - p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK); - /* FIN, seqno 16 */ - p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN); - EXPECT(pinseq != NULL); - EXPECT(p_8_9 != NULL); - EXPECT(p_4_8 != NULL); - EXPECT(p_4_10 != NULL); - EXPECT(p_2_14 != NULL); - EXPECT(p_fin != NULL); - if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) { - /* pass the segment to tcp_input */ - test_tcp_input(p_8_9, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */ - - /* pass the segment to tcp_input */ - test_tcp_input(p_4_8, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ - - /* pass the segment to tcp_input */ - test_tcp_input(p_4_10, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* ooseq queue: unchanged */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ - - /* pass the segment to tcp_input */ - test_tcp_input(p_2_14, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ - - /* pass the segment to tcp_input */ - test_tcp_input(p_fin, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* ooseq queue: unchanged */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ - - /* pass the segment to tcp_input */ - test_tcp_input(pinseq, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 1); - EXPECT(counters.recv_calls == 1); - EXPECT(counters.recved_bytes == data_len); - EXPECT(counters.err_calls == 0); - EXPECT(pcb->ooseq == NULL); - } - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - - -/** create multiple segments and pass them to tcp_input in a wrong - * order to see if ooseq-caching works correctly - * FIN is received IN-SEQUENCE at the end */ -START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) -{ - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN; - char data[] = { - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 10, 11, 12, - 13, 14, 15, 16}; - ip_addr_t remote_ip, local_ip, netmask; - u16_t data_len; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - LWIP_UNUSED_ARG(_i); - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - data_len = sizeof(data); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = data_len; - counters.expected_data = data; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - - /* create segments */ - /* p1: 7 bytes - 2 before FIN */ - /* seqno: 1..2 */ - p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK); - /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ - /* seqno: 4..11 */ - p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); - /* p3: same as p2 but 2 bytes longer and one byte more at the front */ - /* seqno: 3..13 */ - p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK); - /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */ - /* seqno: 2..13 */ - p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK); - /* pinseq is the first segment that is held back to create ooseq! */ - /* seqno: 0..3 */ - pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); - /* p5: last byte before FIN */ - /* seqno: 15 */ - p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); - /* p6: same as p5, should be ignored */ - p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); - /* pinseqFIN: last 2 bytes plus FIN */ - /* only segment containing seqno 14 and FIN */ - pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN); - EXPECT(pinseq != NULL); - EXPECT(p_1_2 != NULL); - EXPECT(p_4_8 != NULL); - EXPECT(p_3_11 != NULL); - EXPECT(p_2_12 != NULL); - EXPECT(p_15_1 != NULL); - EXPECT(p_15_1a != NULL); - EXPECT(pinseqFIN != NULL); - if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL) - && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) { - /* pass the segment to tcp_input */ - test_tcp_input(p_1_2, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); - - /* pass the segment to tcp_input */ - test_tcp_input(p_4_8, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8); - - /* pass the segment to tcp_input */ - test_tcp_input(p_3_11, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); - /* p_3_11 has removed p_4_8 from ooseq */ - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11); - - /* pass the segment to tcp_input */ - test_tcp_input(p_2_12, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12); - - /* pass the segment to tcp_input */ - test_tcp_input(pinseq, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 1); - EXPECT(counters.recved_bytes == 14); - EXPECT(counters.err_calls == 0); - EXPECT(pcb->ooseq == NULL); - - /* pass the segment to tcp_input */ - test_tcp_input(p_15_1, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 1); - EXPECT(counters.recved_bytes == 14); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); - - /* pass the segment to tcp_input */ - test_tcp_input(p_15_1a, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 1); - EXPECT(counters.recved_bytes == 14); - EXPECT(counters.err_calls == 0); - /* check ooseq queue: unchanged */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); - - /* pass the segment to tcp_input */ - test_tcp_input(pinseqFIN, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 1); - EXPECT(counters.recv_calls == 2); - EXPECT(counters.recved_bytes == data_len); - EXPECT(counters.err_calls == 0); - EXPECT(pcb->ooseq == NULL); - } - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} -END_TEST - -static char data_full_wnd[TCP_WND]; - -/** create multiple segments and pass them to tcp_input with the first segment missing - * to simulate overruning the rxwin with ooseq queueing enabled */ -START_TEST(test_tcp_recv_ooseq_overrun_rxwin) -{ -#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS - int i, k; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *pinseq, *p_ovr; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - int datalen = 0; - int datalen2; - - for(i = 0; i < sizeof(data_full_wnd); i++) { - data_full_wnd[i] = (char)i; - } - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = TCP_WND; - counters.expected_data = data_full_wnd; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->rcv_nxt = 0x8000; - - /* create segments */ - /* pinseq is sent as last segment! */ - pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); - - for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) { - int count, expected_datalen; - struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], - TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); - EXPECT_RET(p != NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - count = tcp_oos_count(pcb); - EXPECT_OOSEQ(count == k+1); - datalen = tcp_oos_tcplen(pcb); - if (i + TCP_MSS < TCP_WND) { - expected_datalen = (k+1)*TCP_MSS; - } else { - expected_datalen = TCP_WND - TCP_MSS; - } - if (datalen != expected_datalen) { - EXPECT_OOSEQ(datalen == expected_datalen); - } - } - - /* pass in one more segment, cleary overrunning the rxwin */ - p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); - EXPECT_RET(p_ovr != NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p_ovr, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == k); - datalen2 = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(datalen == datalen2); - - /* now pass inseq */ - test_tcp_input(pinseq, &netif); - EXPECT(pcb->ooseq == NULL); - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */ - LWIP_UNUSED_ARG(_i); -} -END_TEST - -START_TEST(test_tcp_recv_ooseq_max_bytes) -{ -#if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) - int i, k; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p_ovr; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - int datalen = 0; - int datalen2; - - for(i = 0; i < sizeof(data_full_wnd); i++) { - data_full_wnd[i] = (char)i; - } - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = TCP_WND; - counters.expected_data = data_full_wnd; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->rcv_nxt = 0x8000; - - /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ - - /* create segments and 'recv' them */ - for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) { - int count; - struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k], - TCP_MSS, k, 0, TCP_ACK); - EXPECT_RET(p != NULL); - EXPECT_RET(p->next == NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - count = tcp_oos_pbuf_count(pcb); - EXPECT_OOSEQ(count == i); - datalen = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(datalen == (i * TCP_MSS)); - } - - /* pass in one more segment, overrunning the limit */ - p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK); - EXPECT_RET(p_ovr != NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p_ovr, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue (ensure the new segment was not accepted) */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); - datalen2 = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS)); - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -#endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ - LWIP_UNUSED_ARG(_i); -} -END_TEST - -START_TEST(test_tcp_recv_ooseq_max_pbufs) -{ -#if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) - int i; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p_ovr; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - int datalen = 0; - int datalen2; - - for(i = 0; i < sizeof(data_full_wnd); i++) { - data_full_wnd[i] = (char)i; - } - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = TCP_WND; - counters.expected_data = data_full_wnd; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->rcv_nxt = 0x8000; - - /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ - - /* create segments and 'recv' them */ - for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) { - int count; - struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i], - 1, i, 0, TCP_ACK); - EXPECT_RET(p != NULL); - EXPECT_RET(p->next == NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue */ - count = tcp_oos_pbuf_count(pcb); - EXPECT_OOSEQ(count == i); - datalen = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(datalen == i); - } - - /* pass in one more segment, overrunning the limit */ - p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK); - EXPECT_RET(p_ovr != NULL); - /* pass the segment to tcp_input */ - test_tcp_input(p_ovr, &netif); - /* check if counters are as expected */ - EXPECT(counters.close_calls == 0); - EXPECT(counters.recv_calls == 0); - EXPECT(counters.recved_bytes == 0); - EXPECT(counters.err_calls == 0); - /* check ooseq queue (ensure the new segment was not accepted) */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); - datalen2 = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(datalen2 == (i-1)); - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -#endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ - LWIP_UNUSED_ARG(_i); -} -END_TEST - -static void -check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls, - u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len) -{ - int oos_len; - EXPECT(counters->close_calls == exp_close_calls); - EXPECT(counters->recv_calls == exp_rx_calls); - EXPECT(counters->recved_bytes == exp_rx_bytes); - EXPECT(counters->err_calls == exp_err_calls); - /* check that pbuf is queued in ooseq */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count); - oos_len = tcp_oos_tcplen(pcb); - EXPECT_OOSEQ(exp_oos_len == oos_len); -} - -/* this test uses 4 packets: - * - data (len=TCP_MSS) - * - FIN - * - data after FIN (len=1) (invalid) - * - 2nd FIN (invalid) - * - * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq - */ -static void test_tcp_recv_ooseq_double_FINs(int delay_packet) -{ - int i, k; - struct test_tcp_counters counters; - struct tcp_pcb* pcb; - struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq; - ip_addr_t remote_ip, local_ip, netmask; - u16_t remote_port = 0x100, local_port = 0x101; - struct netif netif; - u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0; - int first_dropped = 0xff; - int last_dropped = 0; - - for(i = 0; i < sizeof(data_full_wnd); i++) { - data_full_wnd[i] = (char)i; - } - - /* initialize local vars */ - memset(&netif, 0, sizeof(netif)); - IP4_ADDR(&local_ip, 192, 168, 1, 1); - IP4_ADDR(&remote_ip, 192, 168, 1, 2); - IP4_ADDR(&netmask, 255, 255, 255, 0); - test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); - /* initialize counter struct */ - memset(&counters, 0, sizeof(counters)); - counters.expected_data_len = TCP_WND; - counters.expected_data = data_full_wnd; - - /* create and initialize the pcb */ - pcb = test_tcp_new_counters_pcb(&counters); - EXPECT_RET(pcb != NULL); - tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); - pcb->rcv_nxt = 0x8000; - - /* create segments */ - p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); - p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN); - k = 1; - p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK); - p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN); - - if(delay_packet & 1) { - /* drop normal data */ - first_dropped = 1; - last_dropped = 1; - } else { - /* send normal data */ - test_tcp_input(p, &netif); - exp_rx_calls++; - exp_rx_bytes += TCP_MSS; - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 2) { - /* drop FIN */ - if(first_dropped > 2) { - first_dropped = 2; - } - last_dropped = 2; - } else { - /* send FIN */ - test_tcp_input(p_normal_fin, &netif); - if (first_dropped < 2) { - /* already dropped packets, this one is ooseq */ - exp_oos_pbufs++; - exp_oos_tcplen++; - } else { - /* inseq */ - exp_close_calls++; - } - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 4) { - /* drop data-after-FIN */ - if(first_dropped > 3) { - first_dropped = 3; - } - last_dropped = 3; - } else { - /* send data-after-FIN */ - test_tcp_input(p_data_after_fin, &netif); - if (first_dropped < 3) { - /* already dropped packets, this one is ooseq */ - if (delay_packet & 2) { - /* correct FIN was ooseq */ - exp_oos_pbufs++; - exp_oos_tcplen += k; - } - } else { - /* inseq: no change */ - } - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 8) { - /* drop 2nd-FIN */ - if(first_dropped > 4) { - first_dropped = 4; - } - last_dropped = 4; - } else { - /* send 2nd-FIN */ - test_tcp_input(p_2nd_fin_ooseq, &netif); - if (first_dropped < 3) { - /* already dropped packets, this one is ooseq */ - if (delay_packet & 2) { - /* correct FIN was ooseq */ - exp_oos_pbufs++; - exp_oos_tcplen++; - } - } else { - /* inseq: no change */ - } - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 1) { - /* dropped normal data before */ - test_tcp_input(p, &netif); - exp_rx_calls++; - exp_rx_bytes += TCP_MSS; - if((delay_packet & 2) == 0) { - /* normal FIN was NOT delayed */ - exp_close_calls++; - exp_oos_pbufs = exp_oos_tcplen = 0; - } - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 2) { - /* dropped normal FIN before */ - test_tcp_input(p_normal_fin, &netif); - exp_close_calls++; - exp_oos_pbufs = exp_oos_tcplen = 0; - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 4) { - /* dropped data-after-FIN before */ - test_tcp_input(p_data_after_fin, &netif); - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - if(delay_packet & 8) { - /* dropped 2nd-FIN before */ - test_tcp_input(p_2nd_fin_ooseq, &netif); - } - /* check if counters are as expected */ - check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); - - /* check that ooseq data has been dumped */ - EXPECT(pcb->ooseq == NULL); - - /* make sure the pcb is freed */ - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); - tcp_abort(pcb); - EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); -} - -/** create multiple segments and pass them to tcp_input with the first segment missing - * to simulate overruning the rxwin with ooseq queueing enabled */ -#define FIN_TEST(name, num) \ - START_TEST(name) \ - { \ - LWIP_UNUSED_ARG(_i); \ - test_tcp_recv_ooseq_double_FINs(num); \ - } \ - END_TEST -FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14) -FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15) - - -/** Create the suite including all tests for this module */ -Suite * -tcp_oos_suite(void) -{ - TFun tests[] = { - test_tcp_recv_ooseq_FIN_OOSEQ, - test_tcp_recv_ooseq_FIN_INSEQ, - test_tcp_recv_ooseq_overrun_rxwin, - test_tcp_recv_ooseq_max_bytes, - test_tcp_recv_ooseq_max_pbufs, - test_tcp_recv_ooseq_double_FIN_0, - test_tcp_recv_ooseq_double_FIN_1, - test_tcp_recv_ooseq_double_FIN_2, - test_tcp_recv_ooseq_double_FIN_3, - test_tcp_recv_ooseq_double_FIN_4, - test_tcp_recv_ooseq_double_FIN_5, - test_tcp_recv_ooseq_double_FIN_6, - test_tcp_recv_ooseq_double_FIN_7, - test_tcp_recv_ooseq_double_FIN_8, - test_tcp_recv_ooseq_double_FIN_9, - test_tcp_recv_ooseq_double_FIN_10, - test_tcp_recv_ooseq_double_FIN_11, - test_tcp_recv_ooseq_double_FIN_12, - test_tcp_recv_ooseq_double_FIN_13, - test_tcp_recv_ooseq_double_FIN_14, - test_tcp_recv_ooseq_double_FIN_15 - }; - return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.h b/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.h deleted file mode 100644 index 5e411f0..0000000 --- a/external/badvpn_dns/lwip/test/unit/tcp/test_tcp_oos.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_TCP_OOS_H__ -#define __TEST_TCP_OOS_H__ - -#include "../lwip_check.h" - -Suite *tcp_oos_suite(void); - -#endif diff --git a/external/badvpn_dns/lwip/test/unit/udp/test_udp.c b/external/badvpn_dns/lwip/test/unit/udp/test_udp.c deleted file mode 100644 index a2f02af..0000000 --- a/external/badvpn_dns/lwip/test/unit/udp/test_udp.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "test_udp.h" - -#include "lwip/udp.h" -#include "lwip/stats.h" - -#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS -#error "This tests needs UDP- and MEMP-statistics enabled" -#endif - -/* Helper functions */ -static void -udp_remove_all(void) -{ - struct udp_pcb *pcb = udp_pcbs; - struct udp_pcb *pcb2; - - while(pcb != NULL) { - pcb2 = pcb; - pcb = pcb->next; - udp_remove(pcb2); - } - fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); -} - -/* Setups/teardown functions */ - -static void -udp_setup(void) -{ - udp_remove_all(); -} - -static void -udp_teardown(void) -{ - udp_remove_all(); -} - - -/* Test functions */ - -START_TEST(test_udp_new_remove) -{ - struct udp_pcb* pcb; - LWIP_UNUSED_ARG(_i); - - fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); - - pcb = udp_new(); - fail_unless(pcb != NULL); - if (pcb != NULL) { - fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 1); - udp_remove(pcb); - fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); - } -} -END_TEST - - -/** Create the suite including all tests for this module */ -Suite * -udp_suite(void) -{ - TFun tests[] = { - test_udp_new_remove, - }; - return create_suite("UDP", tests, sizeof(tests)/sizeof(TFun), udp_setup, udp_teardown); -} diff --git a/external/badvpn_dns/lwip/test/unit/udp/test_udp.h b/external/badvpn_dns/lwip/test/unit/udp/test_udp.h deleted file mode 100644 index 9335368..0000000 --- a/external/badvpn_dns/lwip/test/unit/udp/test_udp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __TEST_UDP_H__ -#define __TEST_UDP_H__ - -#include "../lwip_check.h" - -Suite* udp_suite(void); - -#endif diff --git a/external/badvpn_dns/misc/BRefTarget.h b/external/badvpn_dns/misc/BRefTarget.h deleted file mode 100644 index 4324605..0000000 --- a/external/badvpn_dns/misc/BRefTarget.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file BRefTarget.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_B_REF_TARGET_H -#define BADVPN_B_REF_TARGET_H - -#include <limits.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> - -/** - * Represents a reference-counted object. - */ -typedef struct BRefTarget_s BRefTarget; - -/** - * Callback function called after the reference count of a {@link BRefTarget} - * reaches has reached zero. At this point the BRefTarget object has already - * been invalidated, i.e. {@link BRefTarget_Ref} must not be called on this - * object after this handler is called. - */ -typedef void (*BRefTarget_func_release) (BRefTarget *o); - -struct BRefTarget_s { - BRefTarget_func_release func_release; - int refcnt; - DebugObject d_obj; -}; - -/** - * Initializes a reference target object. The initial reference count of the object - * is 1. The \a func_release argument specifies the function to be called from - * {@link BRefTarget_Deref} when the reference count reaches zero. - */ -static void BRefTarget_Init (BRefTarget *o, BRefTarget_func_release func_release); - -/** - * Decrements the reference count of a reference target object. If the reference - * count has reached zero, the object's {@link BRefTarget_func_release} function - * is called, and the object is considered destroyed. - */ -static void BRefTarget_Deref (BRefTarget *o); - -/** - * Increments the reference count of a reference target object. - * Returns 1 on success and 0 on failure. - */ -static int BRefTarget_Ref (BRefTarget *o) WARN_UNUSED; - -static void BRefTarget_Init (BRefTarget *o, BRefTarget_func_release func_release) -{ - ASSERT(func_release) - - o->func_release = func_release; - o->refcnt = 1; - - DebugObject_Init(&o->d_obj); -} - -static void BRefTarget_Deref (BRefTarget *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->refcnt > 0) - - o->refcnt--; - - if (o->refcnt == 0) { - DebugObject_Free(&o->d_obj); - o->func_release(o); - } -} - -static int BRefTarget_Ref (BRefTarget *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->refcnt > 0) - - if (o->refcnt == INT_MAX) { - return 0; - } - - o->refcnt++; - - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/Utf16Decoder.h b/external/badvpn_dns/misc/Utf16Decoder.h deleted file mode 100644 index 819ac94..0000000 --- a/external/badvpn_dns/misc/Utf16Decoder.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file Utf16Decoder.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UTF16DECODER_H -#define BADVPN_UTF16DECODER_H - -#include <stdint.h> - -#include <misc/debug.h> - -/** - * Decodes UTF-16 data into Unicode characters. - */ -typedef struct { - int cont; - uint32_t ch; -} Utf16Decoder; - -/** - * Initializes the UTF-16 decoder. - * - * @param o the object - */ -static void Utf16Decoder_Init (Utf16Decoder *o); - -/** - * Inputs a 16-bit value to the decoder. - * - * @param o the object - * @param b 16-bit value to input - * @param out_ch will receive a Unicode character if this function returns 1. - * If written, the character will be in the range 0 - 0x10FFFF, - * excluding the surrogate range 0xD800 - 0xDFFF. - * @return 1 if a Unicode character has been written to *out_ch, 0 if not - */ -static int Utf16Decoder_Input (Utf16Decoder *o, uint16_t b, uint32_t *out_ch); - -void Utf16Decoder_Init (Utf16Decoder *o) -{ - o->cont = 0; -} - -int Utf16Decoder_Input (Utf16Decoder *o, uint16_t b, uint32_t *out_ch) -{ - // high surrogate - if (b >= UINT16_C(0xD800) && b <= UINT16_C(0xDBFF)) { - // set continuation state - o->cont = 1; - - // add high bits - o->ch = (uint32_t)(b - UINT16_C(0xD800)) << 10; - - return 0; - } - - // low surrogate - if (b >= UINT16_C(0xDC00) && b <= UINT16_C(0xDFFF)) { - // check continuation - if (!o->cont) { - return 0; - } - - // add low bits - o->ch |= (b - UINT16_C(0xDC00)); - - // reset state - o->cont = 0; - - // don't report surrogates - if (o->ch >= UINT32_C(0xD800) && o->ch <= UINT32_C(0xDFFF)) { - return 0; - } - - // return character - *out_ch = o->ch; - return 1; - } - - // reset state - o->cont = 0; - - // return character - *out_ch = b; - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/Utf16Encoder.h b/external/badvpn_dns/misc/Utf16Encoder.h deleted file mode 100644 index 4900b42..0000000 --- a/external/badvpn_dns/misc/Utf16Encoder.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @file Utf16Encoder.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UTF16ENCODER_H -#define BADVPN_UTF16ENCODER_H - -#include <stdint.h> - -/** - * Encodes a Unicode character into a sequence of 16-bit values according to UTF-16. - * - * @param ch Unicode character to encode - * @param out will receive the encoded 16-bit values. Must have space for 2 values. - * @return number of 16-bit values written, 0-2, with 0 meaning the character cannot - * be encoded - */ -static int Utf16Encoder_EncodeCharacter (uint32_t ch, uint16_t *out); - -int Utf16Encoder_EncodeCharacter (uint32_t ch, uint16_t *out) -{ - if (ch <= UINT32_C(0xFFFF)) { - // surrogates - if (ch >= UINT32_C(0xD800) && ch <= UINT32_C(0xDFFF)) { - return 0; - } - - out[0] = ch; - return 1; - } - - if (ch <= UINT32_C(0x10FFFF)) { - uint32_t x = ch - UINT32_C(0x10000); - out[0] = UINT32_C(0xD800) + (x >> 10); - out[1] = UINT32_C(0xDC00) + (x & UINT32_C(0x3FF)); - return 2; - } - - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/Utf8Decoder.h b/external/badvpn_dns/misc/Utf8Decoder.h deleted file mode 100644 index c6412b1..0000000 --- a/external/badvpn_dns/misc/Utf8Decoder.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file Utf8Decoder.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UTF8DECODER_H -#define BADVPN_UTF8DECODER_H - -#include <stdint.h> - -#include <misc/debug.h> - -/** - * Decodes UTF-8 data into Unicode characters. - */ -typedef struct { - int bytes; - int pos; - uint32_t ch; -} Utf8Decoder; - -/** - * Initializes the UTF-8 decoder. - * - * @param o the object - */ -static void Utf8Decoder_Init (Utf8Decoder *o); - -/** - * Inputs a byte to the decoder. - * - * @param o the object - * @param b byte to input - * @param out_ch will receive a Unicode character if this function returns 1. - * If written, the character will be in the range 0 - 0x10FFFF, - * excluding the surrogate range 0xD800 - 0xDFFF. - * @return 1 if a Unicode character has been written to *out_ch, 0 if not - */ -static int Utf8Decoder_Input (Utf8Decoder *o, uint8_t b, uint32_t *out_ch); - -void Utf8Decoder_Init (Utf8Decoder *o) -{ - o->bytes = 0; -} - -int Utf8Decoder_Input (Utf8Decoder *o, uint8_t b, uint32_t *out_ch) -{ - // one-byte character - if ((b & 128) == 0) { - o->bytes = 0; - *out_ch = b; - return 1; - } - - // start of two-byte character - if ((b & 224) == 192) { - o->bytes = 2; - o->pos = 1; - o->ch = (uint32_t)(b & 31) << 6; - return 0; - } - - // start of three-byte character - if ((b & 240) == 224) { - o->bytes = 3; - o->pos = 1; - o->ch = (uint32_t)(b & 15) << 12; - return 0; - } - - // start of four-byte character - if ((b & 248) == 240) { - o->bytes = 4; - o->pos = 1; - o->ch = (uint32_t)(b & 7) << 18; - return 0; - } - - // continuation of multi-byte character - if ((b & 192) == 128 && o->bytes > 0) { - ASSERT(o->bytes <= 4) - ASSERT(o->pos > 0) - ASSERT(o->pos < o->bytes) - - // add bits from this byte - o->ch |= (uint32_t)(b & 63) << (6 * (o->bytes - o->pos - 1)); - - // end of multi-byte character? - if (o->pos == o->bytes - 1) { - // reset state - o->bytes = 0; - - // don't report out-of-range characters - if (o->ch > UINT32_C(0x10FFFF)) { - return 0; - } - - // don't report surrogates - if (o->ch >= UINT32_C(0xD800) && o->ch <= UINT32_C(0xDFFF)) { - return 0; - } - - *out_ch = o->ch; - return 1; - } - - // increment byte index - o->pos++; - - return 0; - } - - // error, reset state - o->bytes = 0; - - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/Utf8Encoder.h b/external/badvpn_dns/misc/Utf8Encoder.h deleted file mode 100644 index 00eb5e6..0000000 --- a/external/badvpn_dns/misc/Utf8Encoder.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file Utf8Encoder.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UTF8ENCODER_H -#define BADVPN_UTF8ENCODER_H - -#include <stdint.h> - -/** - * Encodes a Unicode character into a sequence of bytes according to UTF-8. - * - * @param ch Unicode character to encode - * @param out will receive the encoded bytes. Must have space for 4 bytes. - * @return number of bytes written, 0-4, with 0 meaning the character cannot - * be encoded - */ -static int Utf8Encoder_EncodeCharacter (uint32_t ch, uint8_t *out); - -int Utf8Encoder_EncodeCharacter (uint32_t ch, uint8_t *out) -{ - if (ch <= UINT32_C(0x007F)) { - out[0] = ch; - return 1; - } - - if (ch <= UINT32_C(0x07FF)) { - out[0] = (0xC0 | (ch >> 6)); - out[1] = (0x80 | ((ch >> 0) & 0x3F)); - return 2; - } - - if (ch <= UINT32_C(0xFFFF)) { - // surrogates - if (ch >= UINT32_C(0xD800) && ch <= UINT32_C(0xDFFF)) { - return 0; - } - - out[0] = (0xE0 | (ch >> 12)); - out[1] = (0x80 | ((ch >> 6) & 0x3F)); - out[2] = (0x80 | ((ch >> 0) & 0x3F)); - return 3; - } - - if (ch < UINT32_C(0x10FFFF)) { - out[0] = (0xF0 | (ch >> 18)); - out[1] = (0x80 | ((ch >> 12) & 0x3F)); - out[2] = (0x80 | ((ch >> 6) & 0x3F)); - out[3] = (0x80 | ((ch >> 0) & 0x3F)); - return 4; - } - - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/arp_proto.h b/external/badvpn_dns/misc/arp_proto.h deleted file mode 100644 index 71a6c98..0000000 --- a/external/badvpn_dns/misc/arp_proto.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file arp_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the ARP protocol. - */ - -#ifndef BADVPN_ARP_PROTO_H -#define BADVPN_ARP_PROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define ARP_HARDWARE_TYPE_ETHERNET 1 - -#define ARP_OPCODE_REQUEST 1 -#define ARP_OPCODE_REPLY 2 - -B_START_PACKED -struct arp_packet { - uint16_t hardware_type; - uint16_t protocol_type; - uint8_t hardware_size; - uint8_t protocol_size; - uint16_t opcode; - uint8_t sender_mac[6]; - uint32_t sender_ip; - uint8_t target_mac[6]; - uint32_t target_ip; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/misc/array_length.h b/external/badvpn_dns/misc/array_length.h deleted file mode 100644 index 15de964..0000000 --- a/external/badvpn_dns/misc/array_length.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file array_length.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_ARRAY_LENGTH -#define BADVPN_ARRAY_LENGTH - -#define B_ARRAY_LENGTH(arr) (sizeof((arr)) / sizeof((arr)[0])) - -#endif diff --git a/external/badvpn_dns/misc/balign.h b/external/badvpn_dns/misc/balign.h deleted file mode 100644 index 57152af..0000000 --- a/external/badvpn_dns/misc/balign.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file balign.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Integer alignment macros. - */ - -#ifndef BADVPN_MISC_BALIGN_H -#define BADVPN_MISC_BALIGN_H - -#include <stddef.h> -#include <stdint.h> - -/** - * Checks if aligning x up to n would overflow. - */ -static int balign_up_overflows (size_t x, size_t n) -{ - size_t r = x % n; - - return (r && x > SIZE_MAX - (n - r)); -} - -/** - * Aligns x up to n. - */ -static size_t balign_up (size_t x, size_t n) -{ - size_t r = x % n; - return (r ? x + (n - r) : x); -} - -/** - * Aligns x down to n. - */ -static size_t balign_down (size_t x, size_t n) -{ - return (x - (x % n)); -} - -/** - * Calculates the quotient of a and b, rounded up. - */ -static size_t bdivide_up (size_t a, size_t b) -{ - size_t r = a % b; - return (r > 0 ? a / b + 1 : a / b); -} - -#endif diff --git a/external/badvpn_dns/misc/balloc.h b/external/badvpn_dns/misc/balloc.h deleted file mode 100644 index 7d2d54f..0000000 --- a/external/badvpn_dns/misc/balloc.h +++ /dev/null @@ -1,248 +0,0 @@ -/** - * @file balloc.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Memory allocation functions. - */ - -#ifndef BADVPN_MISC_BALLOC_H -#define BADVPN_MISC_BALLOC_H - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/bsize.h> -#include <misc/maxalign.h> - -/** - * Allocates memory. - * - * @param bytes number of bytes to allocate. - * @return a non-NULL pointer to the memory, or NULL on failure. - * The memory allocated can be freed using {@link BFree}. - */ -static void * BAlloc (size_t bytes); - -/** - * Frees memory. - * - * @param m memory to free. Must have been obtained with {@link BAlloc}, - * {@link BAllocArray}, or {@link BAllocArray2}. May be NULL; - * in this case, this function does nothing. - */ -static void BFree (void *m); - -/** - * Changes the size of a memory block. On success, the memory block - * may be moved to a different address. - * - * @param m pointer to a memory block obtained from {@link BAlloc} - * or other functions in this group. If this is NULL, the - * call is equivalent to {@link BAlloc}(bytes). - * @param bytes new size of the memory block - * @return new pointer to the memory block, or NULL on failure - */ -static void * BRealloc (void *m, size_t bytes); - -/** - * Allocates memory, with size given as a {@link bsize_t}. - * - * @param bytes number of bytes to allocate. If the size is overflow, - * this function will return NULL. - * @return a non-NULL pointer to the memory, or NULL on failure. - * The memory allocated can be freed using {@link BFree}. - */ -static void * BAllocSize (bsize_t bytes); - -/** - * Allocates memory for an array. - * A check is first done to make sure the multiplication doesn't overflow; - * otherwise, this is equivalent to {@link BAlloc}(count * bytes). - * This may be slightly faster if 'bytes' is constant, because a division - * with 'bytes' is performed. - * - * @param count number of elements. - * @param bytes size of one array element. - * @return a non-NULL pointer to the memory, or NULL on failure. - * The memory allocated can be freed using {@link BFree}. - */ -static void * BAllocArray (size_t count, size_t bytes); - -/** - * Reallocates memory that was allocated using one of the allocation - * functions in this file. On success, the memory may be moved to a - * different address, leaving the old address invalid. - * - * @param mem pointer to an existing memory block. May be NULL, in which - * case this is equivalent to {@link BAllocArray}. - * @param count number of elements for reallocation - * @param bytes size of one array element for reallocation - * @return a non-NULL pointer to the address of the reallocated memory - * block, or NULL on failure. On failure, the original memory - * block is left intact. - */ -static void * BReallocArray (void *mem, size_t count, size_t bytes); - -/** - * Allocates memory for a two-dimensional array. - * - * Checks are first done to make sure the multiplications don't overflow; - * otherwise, this is equivalent to {@link BAlloc}((count2 * (count1 * bytes)). - * - * @param count2 number of elements in one dimension. - * @param count1 number of elements in the other dimension. - * @param bytes size of one array element. - * @return a non-NULL pointer to the memory, or NULL on failure. - * The memory allocated can be freed using {@link BFree}. - */ -static void * BAllocArray2 (size_t count2, size_t count1, size_t bytes); - -/** - * Adds to a size_t with overflow detection. - * - * @param s pointer to a size_t to add to - * @param add number to add - * @return 1 on success, 0 on failure - */ -static int BSizeAdd (size_t *s, size_t add); - -/** - * Aligns a size_t upwards with overflow detection. - * - * @param s pointer to a size_t to align - * @param align alignment value. Must be >0. - * @return 1 on success, 0 on failure - */ -static int BSizeAlign (size_t *s, size_t align); - -void * BAlloc (size_t bytes) -{ - if (bytes == 0) { - return malloc(1); - } - - return malloc(bytes); -} - -void BFree (void *m) -{ - free(m); -} - -void * BRealloc (void *m, size_t bytes) -{ - if (bytes == 0) { - return realloc(m, 1); - } - - return realloc(m, bytes); -} - -void * BAllocSize (bsize_t bytes) -{ - if (bytes.is_overflow) { - return NULL; - } - - return BAlloc(bytes.value); -} - -void * BAllocArray (size_t count, size_t bytes) -{ - if (count == 0 || bytes == 0) { - return malloc(1); - } - - if (count > SIZE_MAX / bytes) { - return NULL; - } - - return BAlloc(count * bytes); -} - -void * BReallocArray (void *mem, size_t count, size_t bytes) -{ - if (count == 0 || bytes == 0) { - return realloc(mem, 1); - } - - if (count > SIZE_MAX / bytes) { - return NULL; - } - - return realloc(mem, count * bytes); -} - -void * BAllocArray2 (size_t count2, size_t count1, size_t bytes) -{ - if (count2 == 0 || count1 == 0 || bytes == 0) { - return malloc(1); - } - - if (count1 > SIZE_MAX / bytes) { - return NULL; - } - - if (count2 > SIZE_MAX / (count1 * bytes)) { - return NULL; - } - - return BAlloc(count2 * (count1 * bytes)); -} - -int BSizeAdd (size_t *s, size_t add) -{ - ASSERT(s) - - if (add > SIZE_MAX - *s) { - return 0; - } - *s += add; - return 1; -} - -int BSizeAlign (size_t *s, size_t align) -{ - ASSERT(s) - ASSERT(align > 0) - - size_t mod = *s % align; - if (mod > 0) { - if (align - mod > SIZE_MAX - *s) { - return 0; - } - *s += align - mod; - } - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/blimits.h b/external/badvpn_dns/misc/blimits.h deleted file mode 100644 index 8bcdc2a..0000000 --- a/external/badvpn_dns/misc/blimits.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file blimits.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BLIMITS_H -#define BADVPN_BLIMITS_H - -#include <stdint.h> - -#define BTYPE_IS_SIGNED(type) ((type)-1 < 0) - -#define BSIGNED_TYPE_MIN(type) ( \ - sizeof(type) == 1 ? INT8_MIN : ( \ - sizeof(type) == 2 ? INT16_MIN : ( \ - sizeof(type) == 4 ? INT32_MIN : ( \ - sizeof(type) == 8 ? INT64_MIN : 0)))) - -#define BSIGNED_TYPE_MAX(type) ( \ - sizeof(type) == 1 ? INT8_MAX : ( \ - sizeof(type) == 2 ? INT16_MAX : ( \ - sizeof(type) == 4 ? INT32_MAX : ( \ - sizeof(type) == 8 ? INT64_MAX : 0)))) - -#define BUNSIGNED_TYPE_MIN(type) ((type)0) - -#define BUNSIGNED_TYPE_MAX(type) ( \ - sizeof(type) == 1 ? UINT8_MAX : ( \ - sizeof(type) == 2 ? UINT16_MAX : ( \ - sizeof(type) == 4 ? UINT32_MAX : ( \ - sizeof(type) == 8 ? UINT64_MAX : 0)))) - -#define BTYPE_MIN(type) (BTYPE_IS_SIGNED(type) ? BSIGNED_TYPE_MIN(type) : BUNSIGNED_TYPE_MIN(type)) -#define BTYPE_MAX(type) (BTYPE_IS_SIGNED(type) ? BSIGNED_TYPE_MAX(type) : BUNSIGNED_TYPE_MAX(type)) - -#endif diff --git a/external/badvpn_dns/misc/bsize.h b/external/badvpn_dns/misc/bsize.h deleted file mode 100644 index 2d724df..0000000 --- a/external/badvpn_dns/misc/bsize.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file bsize.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Arithmetic with overflow detection. - */ - -#ifndef BADVPN_MISC_BSIZE_H -#define BADVPN_MISC_BSIZE_H - -#include <stddef.h> -#include <limits.h> -#include <stdint.h> - -typedef struct { - int is_overflow; - size_t value; -} bsize_t; - -static bsize_t bsize_fromsize (size_t v); -static bsize_t bsize_fromint (int v); -static bsize_t bsize_overflow (void); -static int bsize_tosize (bsize_t s, size_t *out); -static int bsize_toint (bsize_t s, int *out); -static bsize_t bsize_add (bsize_t s1, bsize_t s2); -static bsize_t bsize_max (bsize_t s1, bsize_t s2); -static bsize_t bsize_mul (bsize_t s1, bsize_t s2); - -bsize_t bsize_fromsize (size_t v) -{ - bsize_t s = {0, v}; - return s; -} - -bsize_t bsize_fromint (int v) -{ - bsize_t s = {(v < 0 || v > SIZE_MAX), v}; - return s; -} - -static bsize_t bsize_overflow (void) -{ - bsize_t s = {1, 0}; - return s; -} - -int bsize_tosize (bsize_t s, size_t *out) -{ - if (s.is_overflow) { - return 0; - } - - if (out) { - *out = s.value; - } - - return 1; -} - -int bsize_toint (bsize_t s, int *out) -{ - if (s.is_overflow || s.value > INT_MAX) { - return 0; - } - - if (out) { - *out = s.value; - } - - return 1; -} - -bsize_t bsize_add (bsize_t s1, bsize_t s2) -{ - bsize_t s = {(s1.is_overflow || s2.is_overflow || s2.value > SIZE_MAX - s1.value), (s1.value + s2.value)}; - return s; -} - -bsize_t bsize_max (bsize_t s1, bsize_t s2) -{ - bsize_t s = {(s1.is_overflow || s2.is_overflow), ((s1.value > s2.value) * s1.value + (s1.value <= s2.value) * s2.value)}; - return s; -} - -bsize_t bsize_mul (bsize_t s1, bsize_t s2) -{ - bsize_t s = {(s1.is_overflow || s2.is_overflow || (s1.value != 0 && s2.value > SIZE_MAX / s1.value)), (s1.value * s2.value)}; - return s; -} - -#endif diff --git a/external/badvpn_dns/misc/bsort.h b/external/badvpn_dns/misc/bsort.h deleted file mode 100644 index 24d7a66..0000000 --- a/external/badvpn_dns/misc/bsort.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file bsort.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Sorting functions. - */ - -#ifndef BADVPN_MISC_BSORT_H -#define BADVPN_MISC_BSORT_H - -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -typedef int (*BSort_comparator) (const void *e1, const void *e2); - -static void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator, void *temp); - -void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator, void *temp) -{ - ASSERT(esize > 0) - - for (size_t i = 0; i < count; i++) { - size_t j = i; - while (j > 0) { - uint8_t *x = (uint8_t *)arr + (j - 1) * esize; - uint8_t *y = (uint8_t *)arr + j * esize; - int c = compatator(x, y); - if (c <= 0) { - break; - } - memcpy(temp, x, esize); - memcpy(x, y, esize); - memcpy(y, temp, esize); - j--; - } - } -} - -#endif diff --git a/external/badvpn_dns/misc/bstring.h b/external/badvpn_dns/misc/bstring.h deleted file mode 100644 index caef106..0000000 --- a/external/badvpn_dns/misc/bstring.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file bstring.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BSTRING_H -#define BADVPN_BSTRING_H - -#include <misc/debug.h> - -#include <stdlib.h> -#include <string.h> - -#define BSTRING_TYPE_STATIC 5 -#define BSTRING_TYPE_DYNAMIC 7 -#define BSTRING_TYPE_EXTERNAL 11 - -#define BSTRING_STATIC_SIZE 23 -#define BSTRING_STATIC_MAX (BSTRING_STATIC_SIZE - 1) - -typedef struct { - union { - struct { - char type; - char static_string[BSTRING_STATIC_SIZE]; - } us; - struct { - char type; - char *dynamic_string; - } ud; - struct { - char type; - const char *external_string; - } ue; - } u; -} BString; - -static void BString__assert (BString *o) -{ - switch (o->u.us.type) { - case BSTRING_TYPE_STATIC: - case BSTRING_TYPE_DYNAMIC: - case BSTRING_TYPE_EXTERNAL: - return; - } - - ASSERT(0); -} - -static int BString_Init (BString *o, const char *str) -{ - if (strlen(str) <= BSTRING_STATIC_MAX) { - strcpy(o->u.us.static_string, str); - o->u.us.type = BSTRING_TYPE_STATIC; - } else { - if (!(o->u.ud.dynamic_string = malloc(strlen(str) + 1))) { - return 0; - } - strcpy(o->u.ud.dynamic_string, str); - o->u.ud.type = BSTRING_TYPE_DYNAMIC; - } - - BString__assert(o); - return 1; -} - -static void BString_InitStatic (BString *o, const char *str) -{ - ASSERT(strlen(str) <= BSTRING_STATIC_MAX) - - strcpy(o->u.us.static_string, str); - o->u.us.type = BSTRING_TYPE_STATIC; - - BString__assert(o); -} - -static void BString_InitExternal (BString *o, const char *str) -{ - o->u.ue.external_string = str; - o->u.ue.type = BSTRING_TYPE_EXTERNAL; - - BString__assert(o); -} - -static void BString_InitAllocated (BString *o, char *str) -{ - o->u.ud.dynamic_string = str; - o->u.ud.type = BSTRING_TYPE_DYNAMIC; - - BString__assert(o); -} - -static void BString_Free (BString *o) -{ - BString__assert(o); - - if (o->u.ud.type == BSTRING_TYPE_DYNAMIC) { - free(o->u.ud.dynamic_string); - } -} - -static const char * BString_Get (BString *o) -{ - BString__assert(o); - - switch (o->u.us.type) { - case BSTRING_TYPE_STATIC: return o->u.us.static_string; - case BSTRING_TYPE_DYNAMIC: return o->u.ud.dynamic_string; - case BSTRING_TYPE_EXTERNAL: return o->u.ue.external_string; - } - - ASSERT(0); - return NULL; -} - -#endif diff --git a/external/badvpn_dns/misc/byteorder.h b/external/badvpn_dns/misc/byteorder.h deleted file mode 100644 index 055b0a5..0000000 --- a/external/badvpn_dns/misc/byteorder.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @file byteorder.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Byte order conversion functions. - * - * hton* functions convert from host to big-endian (network) byte order. - * htol* functions convert from host to little-endian byte order. - * ntoh* functions convert from big-endian (network) to host byte order. - * ltoh* functions convert from little-endian to host byte order. - */ - -#ifndef BADVPN_MISC_BYTEORDER_H -#define BADVPN_MISC_BYTEORDER_H - -#if (defined(BADVPN_LITTLE_ENDIAN) + defined(BADVPN_BIG_ENDIAN)) != 1 -#error Unknown byte order or too many byte orders -#endif - -#include <stdint.h> - -static uint16_t badvpn_reverse16 (uint16_t x) -{ - uint16_t y; - *((uint8_t *)&y+0) = *((uint8_t *)&x+1); - *((uint8_t *)&y+1) = *((uint8_t *)&x+0); - return y; -} - -static uint32_t badvpn_reverse32 (uint32_t x) -{ - uint32_t y; - *((uint8_t *)&y+0) = *((uint8_t *)&x+3); - *((uint8_t *)&y+1) = *((uint8_t *)&x+2); - *((uint8_t *)&y+2) = *((uint8_t *)&x+1); - *((uint8_t *)&y+3) = *((uint8_t *)&x+0); - return y; -} - -static uint64_t badvpn_reverse64 (uint64_t x) -{ - uint64_t y; - *((uint8_t *)&y+0) = *((uint8_t *)&x+7); - *((uint8_t *)&y+1) = *((uint8_t *)&x+6); - *((uint8_t *)&y+2) = *((uint8_t *)&x+5); - *((uint8_t *)&y+3) = *((uint8_t *)&x+4); - *((uint8_t *)&y+4) = *((uint8_t *)&x+3); - *((uint8_t *)&y+5) = *((uint8_t *)&x+2); - *((uint8_t *)&y+6) = *((uint8_t *)&x+1); - *((uint8_t *)&y+7) = *((uint8_t *)&x+0); - return y; -} - -static uint8_t hton8 (uint8_t x) -{ - return x; -} - -static uint8_t htol8 (uint8_t x) -{ - return x; -} - -#if defined(BADVPN_LITTLE_ENDIAN) - -static uint16_t hton16 (uint16_t x) -{ - return badvpn_reverse16(x); -} - -static uint32_t hton32 (uint32_t x) -{ - return badvpn_reverse32(x); -} - -static uint64_t hton64 (uint64_t x) -{ - return badvpn_reverse64(x); -} - -static uint16_t htol16 (uint16_t x) -{ - return x; -} - -static uint32_t htol32 (uint32_t x) -{ - return x; -} - -static uint64_t htol64 (uint64_t x) -{ - return x; -} - -#elif defined(BADVPN_BIG_ENDIAN) - -static uint16_t hton16 (uint16_t x) -{ - return x; -} - -static uint32_t hton32 (uint32_t x) -{ - return x; -} - -static uint64_t hton64 (uint64_t x) -{ - return x; -} - -static uint16_t htol16 (uint16_t x) -{ - return badvpn_reverse16(x); -} - -static uint32_t htol32 (uint32_t x) -{ - return badvpn_reverse32(x); -} - -static uint64_t htol64 (uint64_t x) -{ - return badvpn_reverse64(x); -} - -#endif - -static uint8_t ntoh8 (uint8_t x) -{ - return hton8(x); -} - -static uint16_t ntoh16 (uint16_t x) -{ - return hton16(x); -} - -static uint32_t ntoh32 (uint32_t x) -{ - return hton32(x); -} - -static uint64_t ntoh64 (uint64_t x) -{ - return hton64(x); -} - -static uint8_t ltoh8 (uint8_t x) -{ - return htol8(x); -} - -static uint16_t ltoh16 (uint16_t x) -{ - return htol16(x); -} - -static uint32_t ltoh32 (uint32_t x) -{ - return htol32(x); -} - -static uint64_t ltoh64 (uint64_t x) -{ - return htol64(x); -} - -#endif diff --git a/external/badvpn_dns/misc/cmdline.h b/external/badvpn_dns/misc/cmdline.h deleted file mode 100644 index fba899a..0000000 --- a/external/badvpn_dns/misc/cmdline.h +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @file cmdline.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Command line construction functions. - */ - -#ifndef BADVPN_MISC_CMDLINE_H -#define BADVPN_MISC_CMDLINE_H - -#include <stddef.h> -#include <stdarg.h> - -#include <misc/debug.h> -#include <misc/exparray.h> -#include <misc/strdup.h> -#include <misc/cstring.h> - -typedef struct { - struct ExpArray arr; - size_t n; -} CmdLine; - -static int CmdLine_Init (CmdLine *c); -static void CmdLine_Free (CmdLine *c); -static int CmdLine_Append (CmdLine *c, const char *str); -static int CmdLine_AppendNoNull (CmdLine *c, const char *str, size_t str_len); -static int CmdLine_AppendCstring (CmdLine *c, b_cstring cstr, size_t offset, size_t length); -static int CmdLine_AppendMulti (CmdLine *c, int num, ...); -static int CmdLine_Finish (CmdLine *c); -static char ** CmdLine_Get (CmdLine *c); - -static int _CmdLine_finished (CmdLine *c) -{ - return (c->n > 0 && ((char **)c->arr.v)[c->n - 1] == NULL); -} - -int CmdLine_Init (CmdLine *c) -{ - if (!ExpArray_init(&c->arr, sizeof(char *), 16)) { - return 0; - } - - c->n = 0; - - return 1; -} - -void CmdLine_Free (CmdLine *c) -{ - for (size_t i = 0; i < c->n; i++) { - free(((char **)c->arr.v)[i]); - } - - free(c->arr.v); -} - -int CmdLine_Append (CmdLine *c, const char *str) -{ - ASSERT(str) - ASSERT(!_CmdLine_finished(c)) - - if (!ExpArray_resize(&c->arr, c->n + 1)) { - return 0; - } - - if (!(((char **)c->arr.v)[c->n] = strdup(str))) { - return 0; - } - - c->n++; - - return 1; -} - -int CmdLine_AppendNoNull (CmdLine *c, const char *str, size_t str_len) -{ - ASSERT(str) - ASSERT(!memchr(str, '\0', str_len)) - ASSERT(!_CmdLine_finished(c)) - - if (!ExpArray_resize(&c->arr, c->n + 1)) { - return 0; - } - - if (!(((char **)c->arr.v)[c->n] = b_strdup_bin(str, str_len))) { - return 0; - } - - c->n++; - - return 1; -} - -int CmdLine_AppendCstring (CmdLine *c, b_cstring cstr, size_t offset, size_t length) -{ - b_cstring_assert_range(cstr, offset, length); - ASSERT(!b_cstring_memchr(cstr, offset, length, '\0', NULL)) - - if (!ExpArray_resize(&c->arr, c->n + 1)) { - return 0; - } - - if (!(((char **)c->arr.v)[c->n] = b_cstring_strdup(cstr, offset, length))) { - return 0; - } - - c->n++; - - return 1; -} - -int CmdLine_AppendMulti (CmdLine *c, int num, ...) -{ - int res = 1; - - va_list vl; - va_start(vl, num); - - for (int i = 0; i < num; i++) { - const char *str = va_arg(vl, const char *); - if (!CmdLine_Append(c, str)) { - res = 0; - break; - } - } - - va_end(vl); - - return res; -} - -int CmdLine_Finish (CmdLine *c) -{ - ASSERT(!_CmdLine_finished(c)) - - if (!ExpArray_resize(&c->arr, c->n + 1)) { - return 0; - } - - ((char **)c->arr.v)[c->n] = NULL; - - c->n++; - - return 1; -} - -char ** CmdLine_Get (CmdLine *c) -{ - ASSERT(_CmdLine_finished(c)) - - return (char **)c->arr.v; -} - -#endif diff --git a/external/badvpn_dns/misc/compare.h b/external/badvpn_dns/misc/compare.h deleted file mode 100644 index 8d1a1b9..0000000 --- a/external/badvpn_dns/misc/compare.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file compare.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_COMPARE_H -#define BADVPN_COMPARE_H - -#define B_COMPARE(a, b) (((a) > (b)) - ((a) < (b))) -#define B_COMPARE_COMBINE(cmp1, cmp2) ((cmp1) ? (cmp1) : (cmp2)) -#define B_COMPARE2(a, b, c, d) B_COMPARE_COMBINE(B_COMPARE((a), (b)), B_COMPARE((c), (d))) - -#endif diff --git a/external/badvpn_dns/misc/concat_strings.h b/external/badvpn_dns/misc/concat_strings.h deleted file mode 100644 index 30330bc..0000000 --- a/external/badvpn_dns/misc/concat_strings.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file concat_strings.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function for concatenating strings. - */ - -#ifndef BADVPN_MISC_CONCAT_STRINGS_H -#define BADVPN_MISC_CONCAT_STRINGS_H - -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> - -#include <misc/debug.h> - -static char * concat_strings (int num, ...) -{ - ASSERT(num >= 0) - - // calculate sum of lengths - size_t sum = 0; - va_list ap; - va_start(ap, num); - for (int i = 0; i < num; i++) { - const char *str = va_arg(ap, const char *); - size_t str_len = strlen(str); - if (str_len > SIZE_MAX - 1 - sum) { - va_end(ap); - return NULL; - } - sum += str_len; - } - va_end(ap); - - // allocate memory - char *res_str = (char *)malloc(sum + 1); - if (!res_str) { - return NULL; - } - - // copy strings - sum = 0; - va_start(ap, num); - for (int i = 0; i < num; i++) { - const char *str = va_arg(ap, const char *); - size_t str_len = strlen(str); - memcpy(res_str + sum, str, str_len); - sum += str_len; - } - va_end(ap); - - // terminate - res_str[sum] = '\0'; - - return res_str; -} - -#endif diff --git a/external/badvpn_dns/misc/cstring.h b/external/badvpn_dns/misc/cstring.h deleted file mode 100644 index bd8de75..0000000 --- a/external/badvpn_dns/misc/cstring.h +++ /dev/null @@ -1,347 +0,0 @@ -/** - * @file cstring.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_COMPOSED_STRING_H -#define BADVPN_COMPOSED_STRING_H - -#include <stddef.h> -#include <string.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -struct b_cstring_s; - -/** - * Callback function which is called by {@link b_cstring_get} to access the underlying resource. - * \a cstr points to the cstring being accessed, and the callback can use the userN members to - * retrieve any state information. - * \a offset is the offset from the beginning of the string; offset < cstr->length. - * This callback must set *\a out_length and return a pointer, representing a continuous - * region of the string that starts at the byte at index \a offset. Returning a region that - * spans past the end of the string is allowed. - */ -typedef const char * (*b_cstring_func) (const struct b_cstring_s *cstr, size_t offset, size_t *out_length); - -/** - * An abstract string which is not necessarily continuous. Given a cstring, its length - * can be determined by reading the 'length' member, and its data can be read using - * {@link b_cstring_get} (which internally invokes the {@link b_cstring_func} callback). - */ -typedef struct b_cstring_s { - size_t length; - b_cstring_func func; - union { - size_t size; - void *ptr; - void (*fptr) (void); - } user1; - union { - size_t size; - void *ptr; - void (*fptr) (void); - } user2; - union { - size_t size; - void *ptr; - void (*fptr) (void); - } user3; -} b_cstring; - -/** - * Makes a cstring pointing to a buffer. - * \a data may be NULL if \a length is 0. - */ -static b_cstring b_cstring_make_buf (const char *data, size_t length); - -/** - * Makes a cstring which represents an empty string. - */ -static b_cstring b_cstring_make_empty (void); - -/** - * Retrieves a pointer to a continuous region of the string. - * \a offset specifies the starting offset of the region to retrieve, and must be < cstr.length. - * \a maxlen specifies the maximum length of the returned region, and must be > 0. - * The length of the region will be stored in *\a out_chunk_len, and it will always be > 0. - * It is possible that the returned region spans past the end of the string, unless limited - * by \a maxlen. The pointer to the region will be returned; it will point to the byte - * at offset exactly \a offset into the string. - */ -static const char * b_cstring_get (b_cstring cstr, size_t offset, size_t maxlen, size_t *out_chunk_len); - -/** - * Retrieves the byte in the string at position \a pos. - */ -static char b_cstring_at (b_cstring cstr, size_t pos); - -/** - * Asserts that the range given by \a offset and \a length is valid for the string. - */ -static void b_cstring_assert_range (b_cstring cstr, size_t offset, size_t length); - -/** - * Copies a range to an external buffer. - */ -static void b_cstring_copy_to_buf (b_cstring cstr, size_t offset, size_t length, char *dest); - -/** - * Performs a memcmp-like operation on the given ranges of two cstrings. - */ -static int b_cstring_memcmp (b_cstring cstr1, b_cstring cstr2, size_t offset1, size_t offset2, size_t length); - -/** - * Determines if a range within a string is equal to the bytes in an external buffer. - */ -static int b_cstring_equals_buffer (b_cstring cstr, size_t offset, size_t length, const char *data); - -/** - * Determines if a range within a string contains the byte \a ch. - * Returns 1 if it does, and 0 if it does not. If it does contain it, and \a out_pos is not - * NULL, *\a out_pos is set to the index of the first matching byte in the range, relative - * to the beginning of the range \a offset. - */ -static int b_cstring_memchr (b_cstring cstr, size_t offset, size_t length, char ch, size_t *out_pos); - -/** - * Allocates a buffer for a range and copies it. The buffer is allocated using {@link BAlloc}. - * An extra null byte will be appended. On failure, returns NULL. - */ -static char * b_cstring_strdup (b_cstring cstr, size_t offset, size_t length); - -/** - * Macro which iterates the continuous regions of a range within a cstring. - * For reach region, the statements in \a body are executed, in order. - * \a cstr is the string to be iterated. - * \a offset and \a length specify the range of the string to iterate; they must - * refer to a valid range for the string. - * \a rel_pos_var, \a chunk_data_var and \a chunk_length_var specify names of variables - * which will be available in \a body. - * \a rel_pos_var will hold the offset (size_t) of the current continuous region, relative - * to \a offset. - * \a chunk_data_var will hold a pointer (const char *) to the beginning of the region, and - * \a chunk_length_var will hold its length (size_t). - * - * Note: \a cstr, \a offset and \a length may be evaluated multiple times, or not at all. - * Note: do not use 'continue' or 'break' from inside the body, their behavior depends - * on the internal implementation of this macro. - * - * See the implementation of {@link b_cstring_copy_to_buf} for a usage example. - */ -#define B_CSTRING_LOOP_RANGE(cstr, offset, length, rel_pos_var, chunk_data_var, chunk_length_var, body) \ -{ \ - size_t rel_pos_var = 0; \ - while (rel_pos_var < (length)) { \ - size_t chunk_length_var; \ - const char *chunk_data_var = b_cstring_get((cstr), (offset) + rel_pos_var, (length) - rel_pos_var, &chunk_length_var); \ - { body } \ - rel_pos_var += chunk_length_var; \ - } \ -} - -/** - * Like {@link B_CSTRING_LOOP_RANGE}, but iterates the entire string, - * i.e. offset==0 and length==cstr.length. - */ -#define B_CSTRING_LOOP(cstr, rel_pos_var, chunk_data_var, chunk_length_var, body) B_CSTRING_LOOP_RANGE(cstr, 0, (cstr).length, rel_pos_var, chunk_data_var, chunk_length_var, body) - -/** - * Macro which iterates the characters of a range within a cstring. - * For each character, the statements in \a body are executed, in order. - * \a cstr is the string to be iterated. - * \a offset and \a length specify the range of the string to iterate; they must - * refer to a valid range for the string. - * \a char_rel_pos_var and \a char_var specify names of variables which will be - * available in \a body. - * \a char_rel_pos_var will hold the position (size_t) of the current character - * relative to \a offset. - * \a char_var will hold the current character (char). - * - * Note: \a cstr, \a offset and \a length may be evaluated multiple times, or not at all. - * Note: do not use 'continue' or 'break' from inside the body, their behavior depends - * on the internal implementation of this macro. - */ -#define B_CSTRING_LOOP_CHARS_RANGE(cstr, offset, length, char_rel_pos_var, char_var, body) \ -B_CSTRING_LOOP_RANGE(cstr, offset, length, b_cstring_loop_chars_pos, b_cstring_loop_chars_chunk_data, b_cstring_loop_chars_chunk_length, { \ - for (size_t b_cstring_loop_chars_chunk_pos = 0; b_cstring_loop_chars_chunk_pos < b_cstring_loop_chars_chunk_length; b_cstring_loop_chars_chunk_pos++) { \ - char char_rel_pos_var = b_cstring_loop_chars_pos + b_cstring_loop_chars_chunk_pos; \ - B_USE(char_rel_pos_var) \ - char char_var = b_cstring_loop_chars_chunk_data[b_cstring_loop_chars_chunk_pos]; \ - { body } \ - } \ -}) - -/** - * Like {@link B_CSTRING_LOOP_CHARS_RANGE}, but iterates the entire string, - * i.e. offset==0 and length==cstr.length. - */ -#define B_CSTRING_LOOP_CHARS(cstr, char_rel_pos_var, char_var, body) B_CSTRING_LOOP_CHARS_RANGE(cstr, 0, (cstr).length, char_rel_pos_var, char_var, body) - -static const char * b_cstring__buf_func (const b_cstring *cstr, size_t offset, size_t *out_length) -{ - ASSERT(offset < cstr->length) - ASSERT(out_length) - ASSERT(cstr->func == b_cstring__buf_func) - ASSERT(cstr->user1.ptr) - - *out_length = cstr->length - offset; - return (const char *)cstr->user1.ptr + offset; -} - -static b_cstring b_cstring_make_buf (const char *data, size_t length) -{ - ASSERT(length == 0 || data) - - b_cstring cstr; - cstr.length = length; - cstr.func = b_cstring__buf_func; - cstr.user1.ptr = (void *)data; - return cstr; -} - -static b_cstring b_cstring_make_empty (void) -{ - b_cstring cstr; - cstr.length = 0; - cstr.func = NULL; - return cstr; -} - -static const char * b_cstring_get (b_cstring cstr, size_t offset, size_t maxlen, size_t *out_chunk_len) -{ - ASSERT(offset < cstr.length) - ASSERT(maxlen > 0) - ASSERT(out_chunk_len) - ASSERT(cstr.func) - - const char *data = cstr.func(&cstr, offset, out_chunk_len); - ASSERT(data) - ASSERT(*out_chunk_len > 0) - - if (*out_chunk_len > maxlen) { - *out_chunk_len = maxlen; - } - - return data; -} - -static char b_cstring_at (b_cstring cstr, size_t pos) -{ - ASSERT(pos < cstr.length) - ASSERT(cstr.func) - - size_t chunk_len; - const char *data = cstr.func(&cstr, pos, &chunk_len); - ASSERT(data) - ASSERT(chunk_len > 0) - - return *data; -} - -static void b_cstring_assert_range (b_cstring cstr, size_t offset, size_t length) -{ - ASSERT(offset <= cstr.length) - ASSERT(length <= cstr.length - offset) -} - -static void b_cstring_copy_to_buf (b_cstring cstr, size_t offset, size_t length, char *dest) -{ - b_cstring_assert_range(cstr, offset, length); - ASSERT(length == 0 || dest) - - B_CSTRING_LOOP_RANGE(cstr, offset, length, pos, chunk_data, chunk_length, { - memcpy(dest + pos, chunk_data, chunk_length); - }) -} - -static int b_cstring_memcmp (b_cstring cstr1, b_cstring cstr2, size_t offset1, size_t offset2, size_t length) -{ - b_cstring_assert_range(cstr1, offset1, length); - b_cstring_assert_range(cstr2, offset2, length); - - B_CSTRING_LOOP_RANGE(cstr1, offset1, length, pos1, chunk_data1, chunk_len1, { - B_CSTRING_LOOP_RANGE(cstr2, offset2 + pos1, chunk_len1, pos2, chunk_data2, chunk_len2, { - int cmp = memcmp(chunk_data1 + pos2, chunk_data2, chunk_len2); - if (cmp) { - return cmp; - } - }) - }) - - return 0; -} - -static int b_cstring_equals_buffer (b_cstring cstr, size_t offset, size_t length, const char *data) -{ - b_cstring_assert_range(cstr, offset, length); - - B_CSTRING_LOOP_RANGE(cstr, offset, length, pos, chunk_data, chunk_len, { - if (memcmp(chunk_data, data + pos, chunk_len)) { - return 0; - } - }) - - return 1; -} - -static int b_cstring_memchr (b_cstring cstr, size_t offset, size_t length, char ch, size_t *out_pos) -{ - b_cstring_assert_range(cstr, offset, length); - - B_CSTRING_LOOP_CHARS_RANGE(cstr, offset, length, cur_ch_pos, cur_ch, { - if (cur_ch == ch) { - if (out_pos) { - *out_pos = cur_ch_pos; - } - return 1; - } - }) - - return 0; -} - -static char * b_cstring_strdup (b_cstring cstr, size_t offset, size_t length) -{ - b_cstring_assert_range(cstr, offset, length); - - if (length == SIZE_MAX) { - return NULL; - } - - char *buf = (char *)BAlloc(length + 1); - if (buf) { - b_cstring_copy_to_buf(cstr, offset, length, buf); - buf[length] = '\0'; - } - - return buf; -} - -#endif diff --git a/external/badvpn_dns/misc/dead.h b/external/badvpn_dns/misc/dead.h deleted file mode 100644 index 7f57421..0000000 --- a/external/badvpn_dns/misc/dead.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file dead.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Dead mechanism definitions. - * - * The dead mechanism is a way for a piece of code to detect whether some - * specific event has occured during some operation (usually during calling - * a user-provided handler function), without requiring access to memory - * that might no longer be available because of the event. - * - * It works somehow like that: - * - * First a dead variable ({@link dead_t}) is allocated somewhere, and - * initialized with {@link DEAD_INIT}, e.g.: - * DEAD_INIT(dead); - * - * When the event that needs to be caught occurs, {@link DEAD_KILL} is - * called, e.g.: - * DEAD_KILL(dead); - * The memory used by the dead variable is no longer needed after - * that. - * - * If a piece of code needs to know whether the event occured during some - * operation (but it must not have occured before!), it puts {@link DEAD_ENTER}} - * in front of the operation, and does {@link DEAD_LEAVE} at the end. If - * {@link DEAD_LEAVE} returned nonzero, the event occured, otherwise it did - * not. Example: - * DEAD_ENTER(dead) - * HandlerFunction(); - * if (DEAD_LEAVE(dead)) { - * (event occured) - * } - * - * If is is needed to check for the event more than once in a single block, - * {@link DEAD_DECLARE} should be put somewhere before, and {@link DEAD_ENTER2} - * should be used instead of {@link DEAD_ENTER}. - * - * If it is needed to check for multiple events (dead variables) at the same - * time, DEAD_*_N macros should be used instead, specifying different - * identiers as the first argument for different dead variables. - */ - -#ifndef BADVPN_MISC_DEAD_H -#define BADVPN_MISC_DEAD_H - -#include <stdlib.h> - -/** - * Dead variable. - */ -typedef int *dead_t; - -/** - * Initializes a dead variable. - */ -#define DEAD_INIT(ptr) { ptr = NULL; } - -/** - * Kills the dead variable, - */ -#define DEAD_KILL(ptr) { if (ptr) *(ptr) = 1; } - -/** - * Kills the dead variable with the given value, or does nothing - * if the value is 0. The value will seen by {@link DEAD_KILLED}. - */ -#define DEAD_KILL_WITH(ptr, val) { if (ptr) *(ptr) = (val); } - -/** - * Declares dead catching variables. - */ -#define DEAD_DECLARE int badvpn__dead; dead_t badvpn__prev_ptr; - -/** - * Enters a dead catching using already declared dead catching variables. - * The dead variable must have been initialized with {@link DEAD_INIT}, - * and {@link DEAD_KILL} must not have been called yet. - * {@link DEAD_LEAVE2} must be called before the current scope is left. - */ -#define DEAD_ENTER2(ptr) { badvpn__dead = 0; badvpn__prev_ptr = ptr; ptr = &badvpn__dead; } - -/** - * Declares dead catching variables and enters a dead catching. - * The dead variable must have been initialized with {@link DEAD_INIT}, - * and {@link DEAD_KILL} must not have been called yet. - * {@link DEAD_LEAVE2} must be called before the current scope is left. - */ -#define DEAD_ENTER(ptr) DEAD_DECLARE DEAD_ENTER2(ptr) - -/** - * Leaves a dead catching. - */ -#define DEAD_LEAVE2(ptr) { if (!badvpn__dead) ptr = badvpn__prev_ptr; if (badvpn__prev_ptr) *badvpn__prev_ptr = badvpn__dead; } - -/** - * Returns 1 if {@link DEAD_KILL} was called for the dead variable, 0 otherwise. - * Must be called after entering a dead catching. - */ -#define DEAD_KILLED (badvpn__dead) - -#define DEAD_DECLARE_N(n) int badvpn__dead##n; dead_t badvpn__prev_ptr##n; -#define DEAD_ENTER2_N(n, ptr) { badvpn__dead##n = 0; badvpn__prev_ptr##n = ptr; ptr = &badvpn__dead##n;} -#define DEAD_ENTER_N(n, ptr) DEAD_DECLARE_N(n) DEAD_ENTER2_N(n, ptr) -#define DEAD_LEAVE2_N(n, ptr) { if (!badvpn__dead##n) ptr = badvpn__prev_ptr##n; if (badvpn__prev_ptr##n) *badvpn__prev_ptr##n = badvpn__dead##n; } -#define DEAD_KILLED_N(n) (badvpn__dead##n) - -#endif diff --git a/external/badvpn_dns/misc/debug.h b/external/badvpn_dns/misc/debug.h deleted file mode 100644 index 13bc866..0000000 --- a/external/badvpn_dns/misc/debug.h +++ /dev/null @@ -1,142 +0,0 @@ -/** - * @file debug.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Debugging macros. - */ - -/** - * @def DEBUG - * - * Macro for printing debugging text. Use the same way as printf, - * but without a newline. - * Prepends "function_name: " and appends a newline. - */ - -/** - * @def ASSERT_FORCE - * - * Macro for forced assertions. - * Evaluates the argument and terminates the program abnormally - * if the result is false. - */ - -/** - * @def ASSERT - * - * Macro for assertions. - * The argument may or may not be evaluated. - * If the argument is evaluated, it must not evaluate to false. - */ - -/** - * @def ASSERT_EXECUTE - * - * Macro for always-evaluated assertions. - * The argument is evaluated. - * The argument must not evaluate to false. - */ - -/** - * @def DEBUG_ZERO_MEMORY - * - * If debugging is enabled, zeroes the given memory region. - * First argument is pointer to the memory region, second is - * number of bytes. - */ - -/** - * @def WARN_UNUSED - * - * Tells the compiler that the result of a function should not be unused. - * Insert at the end of the declaration of a function before the semicolon. - */ - -/** - * @def B_USE - * - * This can be used to suppress warnings about unused variables. It can - * be applied to a variable or any expression. It does not evaluate the - * expression. - */ - -#ifndef BADVPN_MISC_DEBUG_H -#define BADVPN_MISC_DEBUG_H - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <assert.h> - -#define DEBUG(...) \ - { \ - fprintf(stderr, "%s: ", __FUNCTION__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } - -#define ASSERT_FORCE(e) \ - { \ - if (!(e)) { \ - fprintf(stderr, "%s:%d Assertion failed\n", __FILE__, __LINE__); \ - abort(); \ - } \ - } - -#ifdef NDEBUG - #define DEBUG_ZERO_MEMORY(buf, len) {} - #define ASSERT(e) {} - #define ASSERT_EXECUTE(e) { (e); } -#else - #define DEBUG_ZERO_MEMORY(buf, len) { memset((buf), 0, (len)); } - #ifdef BADVPN_USE_C_ASSERT - #define ASSERT(e) { assert(e); } - #define ASSERT_EXECUTE(e) \ - { \ - int _assert_res = !!(e); \ - assert(_assert_res); \ - } - #else - #define ASSERT(e) ASSERT_FORCE(e) - #define ASSERT_EXECUTE(e) ASSERT_FORCE(e) - #endif -#endif - -#ifdef __GNUC__ - #define WARN_UNUSED __attribute__((warn_unused_result)) -#else - #define WARN_UNUSED -#endif - -#define B_USE(expr) (void)(sizeof((expr))); - -#define B_ASSERT_USE(expr) { ASSERT(expr) B_USE(expr) } - -#endif diff --git a/external/badvpn_dns/misc/debugcounter.h b/external/badvpn_dns/misc/debugcounter.h deleted file mode 100644 index a8a54a1..0000000 --- a/external/badvpn_dns/misc/debugcounter.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file debugcounter.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Counter for detecting leaks. - */ - -#ifndef BADVPN_MISC_DEBUGCOUNTER_H -#define BADVPN_MISC_DEBUGCOUNTER_H - -#include <stdint.h> - -#include <misc/debug.h> - -/** - * Counter for detecting leaks. - */ -typedef struct { -#ifndef NDEBUG - int32_t c; -#endif -} DebugCounter; - -#ifndef NDEBUG -#define DEBUGCOUNTER_STATIC { 0 } -#else -#define DEBUGCOUNTER_STATIC {} -#endif - -/** - * Initializes the object. - * The object is initialized with counter value zero. - * - * @param obj the object - */ -static void DebugCounter_Init (DebugCounter *obj) -{ -#ifndef NDEBUG - obj->c = 0; -#endif -} - -/** - * Frees the object. - * This does not have to be called when the counter is no longer needed. - * The counter value must be zero. - * - * @param obj the object - */ -static void DebugCounter_Free (DebugCounter *obj) -{ -#ifndef NDEBUG - ASSERT(obj->c == 0 || obj->c == INT32_MAX) -#endif -} - -/** - * Increments the counter. - * Increments the counter value by one. - * - * @param obj the object - */ -static void DebugCounter_Increment (DebugCounter *obj) -{ -#ifndef NDEBUG - ASSERT(obj->c >= 0) - - if (obj->c != INT32_MAX) { - obj->c++; - } -#endif -} - -/** - * Decrements the counter. - * The counter value must be >0. - * Decrements the counter value by one. - * - * @param obj the object - */ -static void DebugCounter_Decrement (DebugCounter *obj) -{ -#ifndef NDEBUG - ASSERT(obj->c > 0) - - if (obj->c != INT32_MAX) { - obj->c--; - } -#endif -} - -#endif diff --git a/external/badvpn_dns/misc/debugerror.h b/external/badvpn_dns/misc/debugerror.h deleted file mode 100644 index 182afd7..0000000 --- a/external/badvpn_dns/misc/debugerror.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file debugerror.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Mechanism for ensuring an object is destroyed from inside an error handler - * or its jobs. - */ - -#ifndef BADVPN_MISC_DEBUGERROR_H -#define BADVPN_MISC_DEBUGERROR_H - -#include <misc/debug.h> -#include <base/BPending.h> - -#ifndef NDEBUG - #define DEBUGERROR(de, call) \ - { \ - ASSERT(!BPending_IsSet(&(de)->job)) \ - BPending_Set(&(de)->job); \ - (call); \ - } -#else - #define DEBUGERROR(de, call) { (call); } -#endif - -typedef struct { - #ifndef NDEBUG - BPending job; - #endif -} DebugError; - -static void DebugError_Init (DebugError *o, BPendingGroup *pg); -static void DebugError_Free (DebugError *o); -static void DebugError_AssertNoError (DebugError *o); - -#ifndef NDEBUG -static void _DebugError_job_handler (DebugError *o) -{ - ASSERT(0); -} -#endif - -void DebugError_Init (DebugError *o, BPendingGroup *pg) -{ - #ifndef NDEBUG - BPending_Init(&o->job, pg, (BPending_handler)_DebugError_job_handler, o); - #endif -} - -void DebugError_Free (DebugError *o) -{ - #ifndef NDEBUG - BPending_Free(&o->job); - #endif -} - -void DebugError_AssertNoError (DebugError *o) -{ - #ifndef NDEBUG - ASSERT(!BPending_IsSet(&o->job)) - #endif -} - -#endif diff --git a/external/badvpn_dns/misc/dhcp_proto.h b/external/badvpn_dns/misc/dhcp_proto.h deleted file mode 100644 index ed83544..0000000 --- a/external/badvpn_dns/misc/dhcp_proto.h +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file dhcp_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the DHCP protocol. - */ - -#ifndef BADVPN_MISC_DHCP_PROTO_H -#define BADVPN_MISC_DHCP_PROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define DHCP_OP_BOOTREQUEST 1 -#define DHCP_OP_BOOTREPLY 2 - -#define DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET 1 - -#define DHCP_MAGIC 0x63825363 - -#define DHCP_OPTION_PAD 0 -#define DHCP_OPTION_END 255 - -#define DHCP_OPTION_SUBNET_MASK 1 -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DOMAIN_NAME_SERVER 6 -#define DHCP_OPTION_HOST_NAME 12 -#define DHCP_OPTION_REQUESTED_IP_ADDRESS 50 -#define DHCP_OPTION_IP_ADDRESS_LEASE_TIME 51 -#define DHCP_OPTION_DHCP_MESSAGE_TYPE 53 -#define DHCP_OPTION_DHCP_SERVER_IDENTIFIER 54 -#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 -#define DHCP_OPTION_MAXIMUM_MESSAGE_SIZE 57 -#define DHCP_OPTION_RENEWAL_TIME_VALUE 58 -#define DHCP_OPTION_REBINDING_TIME_VALUE 59 -#define DHCP_OPTION_VENDOR_CLASS_IDENTIFIER 60 -#define DHCP_OPTION_CLIENT_IDENTIFIER 61 - -#define DHCP_MESSAGE_TYPE_DISCOVER 1 -#define DHCP_MESSAGE_TYPE_OFFER 2 -#define DHCP_MESSAGE_TYPE_REQUEST 3 -#define DHCP_MESSAGE_TYPE_DECLINE 4 -#define DHCP_MESSAGE_TYPE_ACK 5 -#define DHCP_MESSAGE_TYPE_NAK 6 -#define DHCP_MESSAGE_TYPE_RELEASE 7 - -B_START_PACKED -struct dhcp_header { - uint8_t op; - uint8_t htype; - uint8_t hlen; - uint8_t hops; - uint32_t xid; - uint16_t secs; - uint16_t flags; - uint32_t ciaddr; - uint32_t yiaddr; - uint32_t siaddr; - uint32_t giaddr; - uint8_t chaddr[16]; - uint8_t sname[64]; - uint8_t file[128]; - uint32_t magic; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_header { - uint8_t type; - uint8_t len; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_dhcp_message_type { - uint8_t type; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_maximum_message_size { - uint16_t size; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_dhcp_server_identifier { - uint32_t id; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_time { - uint32_t time; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct dhcp_option_addr { - uint32_t addr; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/misc/ethernet_proto.h b/external/badvpn_dns/misc/ethernet_proto.h deleted file mode 100644 index 6e49e02..0000000 --- a/external/badvpn_dns/misc/ethernet_proto.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file ethernet_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the Ethernet protocol. - */ - -#ifndef BADVPN_MISC_ETHERNET_PROTO_H -#define BADVPN_MISC_ETHERNET_PROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_ARP 0x0806 - -B_START_PACKED -struct ethernet_header { - uint8_t dest[6]; - uint8_t source[6]; - uint16_t type; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/misc/exparray.h b/external/badvpn_dns/misc/exparray.h deleted file mode 100644 index b24149f..0000000 --- a/external/badvpn_dns/misc/exparray.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file exparray.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Dynamic array which grows exponentionally on demand. - */ - -#ifndef BADVPN_MISC_EXPARRAY_H -#define BADVPN_MISC_EXPARRAY_H - -#include <stddef.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/debug.h> - -struct ExpArray { - size_t esize; - size_t size; - void *v; -}; - -static int ExpArray_init (struct ExpArray *o, size_t esize, size_t size) -{ - ASSERT(esize > 0) - ASSERT(size > 0) - - o->esize = esize; - o->size = size; - - if (o->size > SIZE_MAX / o->esize) { - return 0; - } - - if (!(o->v = malloc(o->size * o->esize))) { - return 0; - } - - return 1; -} - -static int ExpArray_resize (struct ExpArray *o, size_t size) -{ - ASSERT(size > 0) - - if (size <= o->size) { - return 1; - } - - size_t newsize = o->size; - - while (newsize < size) { - if (2 > SIZE_MAX / newsize) { - return 0; - } - - newsize = 2 * newsize; - } - - if (newsize > SIZE_MAX / o->esize) { - return 0; - } - - void *newarr = realloc(o->v, newsize * o->esize); - if (!newarr) { - return 0; - } - - o->size = newsize; - o->v = newarr; - - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/expstring.h b/external/badvpn_dns/misc/expstring.h deleted file mode 100644 index 3247135..0000000 --- a/external/badvpn_dns/misc/expstring.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file expstring.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_MISC_EXPSTRING_H -#define BADVPN_MISC_EXPSTRING_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/exparray.h> -#include <misc/bsize.h> - -typedef struct { - struct ExpArray arr; - size_t n; -} ExpString; - -static int ExpString_Init (ExpString *c); -static void ExpString_Free (ExpString *c); -static int ExpString_Append (ExpString *c, const char *str); -static int ExpString_AppendChar (ExpString *c, char ch); -static int ExpString_AppendByte (ExpString *c, uint8_t x); -static int ExpString_AppendBinary (ExpString *c, const uint8_t *data, size_t len); -static int ExpString_AppendZeros (ExpString *c, size_t len); -static char * ExpString_Get (ExpString *c); -static size_t ExpString_Length (ExpString *c); - -int ExpString_Init (ExpString *c) -{ - if (!ExpArray_init(&c->arr, 1, 16)) { - return 0; - } - - c->n = 0; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -void ExpString_Free (ExpString *c) -{ - free(c->arr.v); -} - -int ExpString_Append (ExpString *c, const char *str) -{ - ASSERT(str) - - size_t l = strlen(str); - bsize_t newsize = bsize_add(bsize_fromsize(c->n), bsize_add(bsize_fromsize(l), bsize_fromint(1))); - - if (newsize.is_overflow || !ExpArray_resize(&c->arr, newsize.value)) { - return 0; - } - - memcpy((char *)c->arr.v + c->n, str, l); - c->n += l; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -int ExpString_AppendChar (ExpString *c, char ch) -{ - ASSERT(ch != '\0') - - bsize_t newsize = bsize_add(bsize_fromsize(c->n), bsize_fromint(2)); - - if (newsize.is_overflow || !ExpArray_resize(&c->arr, newsize.value)) { - return 0; - } - - ((char *)c->arr.v)[c->n] = ch; - c->n++; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -int ExpString_AppendByte (ExpString *c, uint8_t x) -{ - bsize_t newsize = bsize_add(bsize_fromsize(c->n), bsize_fromint(2)); - - if (newsize.is_overflow || !ExpArray_resize(&c->arr, newsize.value)) { - return 0; - } - - ((uint8_t *)c->arr.v)[c->n] = x; - c->n++; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -int ExpString_AppendBinary (ExpString *c, const uint8_t *data, size_t len) -{ - bsize_t newsize = bsize_add(bsize_fromsize(c->n), bsize_add(bsize_fromsize(len), bsize_fromint(1))); - - if (newsize.is_overflow || !ExpArray_resize(&c->arr, newsize.value)) { - return 0; - } - - memcpy((char *)c->arr.v + c->n, data, len); - c->n += len; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -int ExpString_AppendZeros (ExpString *c, size_t len) -{ - bsize_t newsize = bsize_add(bsize_fromsize(c->n), bsize_add(bsize_fromsize(len), bsize_fromint(1))); - - if (newsize.is_overflow || !ExpArray_resize(&c->arr, newsize.value)) { - return 0; - } - - memset((char *)c->arr.v + c->n, 0, len); - c->n += len; - ((char *)c->arr.v)[c->n] = '\0'; - - return 1; -} - -char * ExpString_Get (ExpString *c) -{ - return (char *)c->arr.v; -} - -size_t ExpString_Length (ExpString *c) -{ - return c->n; -} - -#endif diff --git a/external/badvpn_dns/misc/find_char.h b/external/badvpn_dns/misc/find_char.h deleted file mode 100644 index 9277ac6..0000000 --- a/external/badvpn_dns/misc/find_char.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file find_char.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_FIND_CHAR_H -#define BADVPN_FIND_CHAR_H - -#include <stddef.h> - -#include <misc/debug.h> - -/** - * Finds the first character 'c' in the string represented by 'str' and 'len'. - * If found, returns 1 and writes the position to *out_pos (if out_pos!=NULL). - * If not found, returns 0 and does not modify *out_pos. - */ -static int b_find_char_bin (const char *str, size_t len, char c, size_t *out_pos) -{ - ASSERT(str) - - for (size_t i = 0; i < len; i++) { - if (str[i] == c) { - if (out_pos) { - *out_pos = i; - } - return 1; - } - } - - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/find_program.h b/external/badvpn_dns/misc/find_program.h deleted file mode 100644 index ecc87be..0000000 --- a/external/badvpn_dns/misc/find_program.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file find_program.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function that finds the absolute path of a program by checking a predefined - * list of directories. - */ - -#ifndef BADVPN_FIND_PROGRAM_H -#define BADVPN_FIND_PROGRAM_H - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <misc/concat_strings.h> -#include <misc/debug.h> -#include <misc/balloc.h> - -static char * badvpn_find_program (const char *name); - -static char * badvpn_find_program (const char *name) -{ - ASSERT(name) - - char *path = getenv("PATH"); - if (path) { - while (1) { - size_t i = 0; - while (path[i] != ':' && path[i] != '\0') { - i++; - } - char const *src = path; - size_t src_len = i; - if (src_len == 0) { - src = "."; - src_len = 1; - } - size_t name_len = strlen(name); - char *entry = BAllocSize(bsize_add(bsize_fromsize(src_len), bsize_add(bsize_fromsize(name_len), bsize_fromsize(2)))); - if (!entry) { - goto fail; - } - memcpy(entry, src, src_len); - entry[src_len] = '/'; - strcpy(entry + (src_len + 1), name); - if (access(entry, X_OK) == 0) { - return entry; - } - free(entry); - if (path[i] == '\0') { - break; - } - path += i + 1; - } - } - - const char *dirs[] = {"/usr/sbin", "/usr/bin", "/sbin", "/bin", NULL}; - - for (size_t i = 0; dirs[i]; i++) { - char *path = concat_strings(3, dirs[i], "/", name); - if (!path) { - goto fail; - } - - if (access(path, X_OK) == 0) { - return path; - } - - free(path); - } - -fail: - return NULL; -} - -#endif diff --git a/external/badvpn_dns/misc/get_iface_info.h b/external/badvpn_dns/misc/get_iface_info.h deleted file mode 100644 index 190741b..0000000 --- a/external/badvpn_dns/misc/get_iface_info.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file get_iface_info.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_GETIFACEINFO_H -#define BADVPN_GETIFACEINFO_H - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <sys/ioctl.h> - -#include <misc/debug.h> - -/** - * Returns information about a network interface with the given name. - * - * @param ifname name of interface to get information for - * @param out_mac the MAC address will be returned here, unless NULL - * @param out_mtu the MTU will be returned here, unless NULL - * @param out_ifindex the interface index will be returned here, unless NULL - * @return 1 on success, 0 on failure - */ -static int badvpn_get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, int *out_ifindex) WARN_UNUSED; - - -static int badvpn_get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, int *out_ifindex) -{ - ASSERT(ifname) - - struct ifreq ifr; - - int s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - goto fail0; - } - - // get MAC - if (out_mac) { - memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname); - if (ioctl(s, SIOCGIFHWADDR, &ifr)) { - goto fail1; - } - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - goto fail1; - } - memcpy(out_mac, ifr.ifr_hwaddr.sa_data, 6); - } - - // get MTU - if (out_mtu) { - memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname); - if (ioctl(s, SIOCGIFMTU, &ifr)) { - goto fail1; - } - *out_mtu = ifr.ifr_mtu; - } - - // get interface index - if (out_ifindex) { - memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname); - if (ioctl(s, SIOCGIFINDEX, &ifr)) { - goto fail1; - } - *out_ifindex = ifr.ifr_ifindex; - } - - close(s); - - return 1; - -fail1: - close(s); -fail0: - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/grow_array.h b/external/badvpn_dns/misc/grow_array.h deleted file mode 100644 index 9a42d04..0000000 --- a/external/badvpn_dns/misc/grow_array.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file grow_array.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Preprocessor inputs: -// GROWARRAY_NAME - prefix of of functions to define -// GROWARRAY_OBJECT_TYPE - type of structure where array and capacity sizes are -// GROWARRAY_ARRAY_MEMBER - array member -// GROWARRAY_CAPACITY_MEMBER - capacity member -// GROWARRAY_MAX_CAPACITY - max value of capacity member - -#include <limits.h> -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/merge.h> - -#define GrowArrayObject GROWARRAY_OBJECT_TYPE -#define GrowArray_Init MERGE(GROWARRAY_NAME, _Init) -#define GrowArray_InitEmpty MERGE(GROWARRAY_NAME, _InitEmpty) -#define GrowArray_Free MERGE(GROWARRAY_NAME, _Free) -#define GrowArray_DoubleUp MERGE(GROWARRAY_NAME, _DoubleUp) -#define GrowArray_DoubleUpLimit MERGE(GROWARRAY_NAME, _DoubleUpLimit) - -static int GrowArray_Init (GrowArrayObject *o, size_t capacity) WARN_UNUSED; -static void GrowArray_InitEmpty (GrowArrayObject *o); -static void GrowArray_Free (GrowArrayObject *o); -static int GrowArray_DoubleUp (GrowArrayObject *o) WARN_UNUSED; -static int GrowArray_DoubleUpLimit (GrowArrayObject *o, size_t limit) WARN_UNUSED; - -static int GrowArray_Init (GrowArrayObject *o, size_t capacity) -{ - if (capacity > GROWARRAY_MAX_CAPACITY) { - return 0; - } - - if (capacity == 0) { - o->GROWARRAY_ARRAY_MEMBER = NULL; - } else { - if (!(o->GROWARRAY_ARRAY_MEMBER = BAllocArray(capacity, sizeof(o->GROWARRAY_ARRAY_MEMBER[0])))) { - return 0; - } - } - - o->GROWARRAY_CAPACITY_MEMBER = capacity; - - return 1; -} - -static void GrowArray_InitEmpty (GrowArrayObject *o) -{ - o->GROWARRAY_ARRAY_MEMBER = NULL; - o->GROWARRAY_CAPACITY_MEMBER = 0; -} - -static void GrowArray_Free (GrowArrayObject *o) -{ - if (o->GROWARRAY_ARRAY_MEMBER) { - BFree(o->GROWARRAY_ARRAY_MEMBER); - } -} - -static int GrowArray_DoubleUp (GrowArrayObject *o) -{ - return GrowArray_DoubleUpLimit(o, SIZE_MAX); -} - -static int GrowArray_DoubleUpLimit (GrowArrayObject *o, size_t limit) -{ - if (o->GROWARRAY_CAPACITY_MEMBER > SIZE_MAX / 2 || o->GROWARRAY_CAPACITY_MEMBER > GROWARRAY_MAX_CAPACITY / 2) { - return 0; - } - - size_t newcap = 2 * o->GROWARRAY_CAPACITY_MEMBER; - if (newcap == 0) { - newcap = 1; - } - - if (newcap > limit) { - newcap = limit; - if (newcap == o->GROWARRAY_CAPACITY_MEMBER) { - return 0; - } - } - - void *newarr = BAllocArray(newcap, sizeof(o->GROWARRAY_ARRAY_MEMBER[0])); - if (!newarr) { - return 0; - } - - memcpy(newarr, o->GROWARRAY_ARRAY_MEMBER, o->GROWARRAY_CAPACITY_MEMBER * sizeof(o->GROWARRAY_ARRAY_MEMBER[0])); - - BFree(o->GROWARRAY_ARRAY_MEMBER); - - o->GROWARRAY_ARRAY_MEMBER = newarr; - o->GROWARRAY_CAPACITY_MEMBER = newcap; - - return 1; -} - -#undef GROWARRAY_NAME -#undef GROWARRAY_OBJECT_TYPE -#undef GROWARRAY_ARRAY_MEMBER -#undef GROWARRAY_CAPACITY_MEMBER -#undef GROWARRAY_MAX_CAPACITY - -#undef GrowArrayObject -#undef GrowArray_Init -#undef GrowArray_InitEmpty -#undef GrowArray_Free -#undef GrowArray_DoubleUp -#undef GrowArray_DoubleUpLimit diff --git a/external/badvpn_dns/misc/hashfun.h b/external/badvpn_dns/misc/hashfun.h deleted file mode 100644 index 5e8956a..0000000 --- a/external/badvpn_dns/misc/hashfun.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file hashfun.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_HASHFUN_H -#define BADVPN_HASHFUN_H - -#include <stdint.h> -#include <stddef.h> - -static size_t badvpn_djb2_hash (const uint8_t *str) -{ - size_t hash = 5381; - int c; - - while (c = *str++) { - hash = ((hash << 5) + hash) + c; - } - - return hash; -} - -static size_t badvpn_djb2_hash_bin (const uint8_t *str, size_t str_len) -{ - size_t hash = 5381; - - while (str_len-- > 0) { - int c = *str++; - hash = ((hash << 5) + hash) + c; - } - - return hash; -} - -#endif diff --git a/external/badvpn_dns/misc/igmp_proto.h b/external/badvpn_dns/misc/igmp_proto.h deleted file mode 100644 index 9188ea0..0000000 --- a/external/badvpn_dns/misc/igmp_proto.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file igmp_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the IGMP protocol. - */ - -#ifndef BADVPN_MISC_IGMP_PROTO_H -#define BADVPN_MISC_IGMP_PROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define IGMP_TYPE_MEMBERSHIP_QUERY 0x11 -#define IGMP_TYPE_V1_MEMBERSHIP_REPORT 0x12 -#define IGMP_TYPE_V2_MEMBERSHIP_REPORT 0x16 -#define IGMP_TYPE_V3_MEMBERSHIP_REPORT 0x22 -#define IGMP_TYPE_V2_LEAVE_GROUP 0x17 - -#define IGMP_RECORD_TYPE_MODE_IS_INCLUDE 1 -#define IGMP_RECORD_TYPE_MODE_IS_EXCLUDE 2 -#define IGMP_RECORD_TYPE_CHANGE_TO_INCLUDE_MODE 3 -#define IGMP_RECORD_TYPE_CHANGE_TO_EXCLUDE_MODE 4 - -B_START_PACKED -struct igmp_source { - uint32_t addr; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct igmp_base { - uint8_t type; - uint8_t max_resp_code; - uint16_t checksum; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct igmp_v3_query_extra { - uint32_t group; - uint8_t reserved4_suppress1_qrv3; - uint8_t qqic; - uint16_t number_of_sources; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct igmp_v3_report_extra { - uint16_t reserved; - uint16_t number_of_group_records; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct igmp_v3_report_record { - uint8_t type; - uint8_t aux_data_len; - uint16_t number_of_sources; - uint32_t group; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct igmp_v2_extra { - uint32_t group; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/misc/ipaddr.h b/external/badvpn_dns/misc/ipaddr.h deleted file mode 100644 index 8c7cb05..0000000 --- a/external/badvpn_dns/misc/ipaddr.h +++ /dev/null @@ -1,218 +0,0 @@ -/** - * @file ipaddr.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IP address parsing functions. - */ - -#ifndef BADVPN_MISC_IPADDR_H -#define BADVPN_MISC_IPADDR_H - -#include <string.h> -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/parse_number.h> -#include <misc/find_char.h> -#include <misc/print_macros.h> - -struct ipv4_ifaddr { - uint32_t addr; - int prefix; -}; - -static int ipaddr_parse_ipv4_addr_bin (const char *name, size_t name_len, uint32_t *out_addr); -static int ipaddr_parse_ipv4_addr (const char *name, uint32_t *out_addr); -static int ipaddr_parse_ipv4_prefix_bin (const char *str, size_t str_len, int *num); -static int ipaddr_parse_ipv4_prefix (const char *str, int *num); -static int ipaddr_parse_ipv4_ifaddr_bin (const char *str, size_t str_len, struct ipv4_ifaddr *out); -static int ipaddr_parse_ipv4_ifaddr (const char *str, struct ipv4_ifaddr *out); -static int ipaddr_ipv4_ifaddr_from_addr_mask (uint32_t addr, uint32_t mask, struct ipv4_ifaddr *out); -static uint32_t ipaddr_ipv4_mask_from_prefix (int prefix); -static int ipaddr_ipv4_prefix_from_mask (uint32_t mask, int *out_prefix); -static int ipaddr_ipv4_addrs_in_network (uint32_t addr1, uint32_t addr2, int netprefix); - -#define IPADDR_PRINT_MAX 19 - -static void ipaddr_print_addr (uint32_t addr, char *out); -static void ipaddr_print_ifaddr (struct ipv4_ifaddr ifaddr, char *out); - -int ipaddr_parse_ipv4_addr_bin (const char *name, size_t name_len, uint32_t *out_addr) -{ - for (size_t i = 0; ; i++) { - size_t j; - for (j = 0; j < name_len && name[j] != '.'; j++); - - if ((j == name_len && i < 3) || (j < name_len && i == 3)) { - return 0; - } - - if (j < 1 || j > 3) { - return 0; - } - - uintmax_t d; - if (!parse_unsigned_integer_bin(name, j, &d)) { - return 0; - } - - if (d > 255) { - return 0; - } - - ((uint8_t *)out_addr)[i] = d; - - if (i == 3) { - return 1; - } - - name += j + 1; - name_len -= j + 1; - } -} - -int ipaddr_parse_ipv4_addr (const char *name, uint32_t *out_addr) -{ - return ipaddr_parse_ipv4_addr_bin(name, strlen(name), out_addr); -} - -int ipaddr_parse_ipv4_prefix_bin (const char *str, size_t str_len, int *num) -{ - uintmax_t d; - if (!parse_unsigned_integer_bin(str, str_len, &d)) { - return 0; - } - if (d > 32) { - return 0; - } - - *num = d; - return 1; -} - -int ipaddr_parse_ipv4_prefix (const char *str, int *num) -{ - return ipaddr_parse_ipv4_prefix_bin(str, strlen(str), num); -} - -int ipaddr_parse_ipv4_ifaddr_bin (const char *str, size_t str_len, struct ipv4_ifaddr *out) -{ - size_t slash_pos; - if (!b_find_char_bin(str, str_len, '/', &slash_pos)) { - return 0; - } - - return (ipaddr_parse_ipv4_addr_bin(str, slash_pos, &out->addr) && - ipaddr_parse_ipv4_prefix_bin(str + slash_pos + 1, str_len - slash_pos - 1, &out->prefix)); -} - -int ipaddr_parse_ipv4_ifaddr (const char *str, struct ipv4_ifaddr *out) -{ - return ipaddr_parse_ipv4_ifaddr_bin(str, strlen(str), out); -} - -int ipaddr_ipv4_ifaddr_from_addr_mask (uint32_t addr, uint32_t mask, struct ipv4_ifaddr *out) -{ - int prefix; - if (!ipaddr_ipv4_prefix_from_mask(mask, &prefix)) { - return 0; - } - - out->addr = addr; - out->prefix = prefix; - return 1; -} - -uint32_t ipaddr_ipv4_mask_from_prefix (int prefix) -{ - ASSERT(prefix >= 0) - ASSERT(prefix <= 32) - - uint32_t t = 0; - for (int i = 0; i < prefix; i++) { - t |= 1 << (32 - i - 1); - } - - return hton32(t); -} - -int ipaddr_ipv4_prefix_from_mask (uint32_t mask, int *out_prefix) -{ - uint32_t t = 0; - int i; - for (i = 0; i <= 32; i++) { - if (ntoh32(mask) == t) { - break; - } - if (i < 32) { - t |= (1 << (32 - i - 1)); - } - } - if (!(i <= 32)) { - return 0; - } - - *out_prefix = i; - return 1; -} - -int ipaddr_ipv4_addrs_in_network (uint32_t addr1, uint32_t addr2, int netprefix) -{ - ASSERT(netprefix >= 0) - ASSERT(netprefix <= 32) - - uint32_t mask = ipaddr_ipv4_mask_from_prefix(netprefix); - - return !!((addr1 & mask) == (addr2 & mask)); -} - -void ipaddr_print_addr (uint32_t addr, char *out) -{ - ASSERT(out) - - uint8_t *b = (uint8_t *)&addr; - - sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, - b[0], b[1], b[2], b[3]); -} - -void ipaddr_print_ifaddr (struct ipv4_ifaddr ifaddr, char *out) -{ - ASSERT(ifaddr.prefix >= 0) - ASSERT(ifaddr.prefix <= 32) - ASSERT(out) - - uint8_t *b = (uint8_t *)&ifaddr.addr; - - sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d", - b[0], b[1], b[2], b[3], ifaddr.prefix); -} - -#endif diff --git a/external/badvpn_dns/misc/ipaddr6.h b/external/badvpn_dns/misc/ipaddr6.h deleted file mode 100644 index ebacd94..0000000 --- a/external/badvpn_dns/misc/ipaddr6.h +++ /dev/null @@ -1,400 +0,0 @@ -/** - * @file ipaddr6.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IPv6 address parsing functions. - */ - -#ifndef BADVPN_MISC_IPADDR6_H -#define BADVPN_MISC_IPADDR6_H - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/parse_number.h> -#include <misc/find_char.h> -#include <misc/print_macros.h> - -struct ipv6_addr { - uint8_t bytes[16]; -}; - -struct ipv6_ifaddr { - struct ipv6_addr addr; - int prefix; -}; - -static int ipaddr6_parse_ipv6_addr_bin (const char *name, size_t name_len, struct ipv6_addr *out_addr); -static int ipaddr6_parse_ipv6_addr (const char *name, struct ipv6_addr *out_addr); -static int ipaddr6_parse_ipv6_prefix_bin (const char *str, size_t str_len, int *out_num); -static int ipaddr6_parse_ipv6_prefix (const char *str, int *out_num); -static int ipaddr6_parse_ipv6_ifaddr_bin (const char *str, size_t str_len, struct ipv6_ifaddr *out); -static int ipaddr6_parse_ipv6_ifaddr (const char *str, struct ipv6_ifaddr *out); -static int ipaddr6_ipv6_ifaddr_from_addr_mask (struct ipv6_addr addr, struct ipv6_addr mask, struct ipv6_ifaddr *out); -static void ipaddr6_ipv6_mask_from_prefix (int prefix, struct ipv6_addr *out_mask); -static int ipaddr6_ipv6_prefix_from_mask (struct ipv6_addr mask, int *out_prefix); -static int ipaddr6_ipv6_addrs_in_network (struct ipv6_addr addr1, struct ipv6_addr addr2, int netprefix); - -#define IPADDR6_PRINT_MAX 44 - -static void ipaddr6_print_addr (struct ipv6_addr addr, char *out_buf); -static void ipaddr6_print_ifaddr (struct ipv6_ifaddr addr, char *out_buf); - -int ipaddr6_parse_ipv6_addr_bin (const char *name, size_t name_len, struct ipv6_addr *out_addr) -{ - int num_blocks = 0; - int compress_pos = -1; - uint16_t block = 0; - int empty = 1; - - size_t i = 0; - - while (i < name_len) { - if (name[i] == '.') { - goto ipv4_ending; - } else if (name[i] == ':') { - int is_double = (i + 1 < name_len && name[i + 1] == ':'); - - if (i > 0) { - if (empty || num_blocks == 7) { - return 0; - } - out_addr->bytes[2 * num_blocks + 0] = block >> 8; - out_addr->bytes[2 * num_blocks + 1] = block & 0xFF; - num_blocks++; - block = 0; - empty = 1; - } - else if (!is_double) { - return 0; - } - - if (is_double) { - if (compress_pos != -1) { - return 0; - } - compress_pos = num_blocks; - } - - i += 1 + is_double; - } else { - int digit = decode_hex_digit(name[i]); - if (digit < 0) { - return 0; - } - if (block > UINT16_MAX / 16) { - return 0; - } - block *= 16; - if (digit > UINT16_MAX - block) { - return 0; - } - block += digit; - empty = 0; - i += 1; - } - } - - if (!empty) { - out_addr->bytes[2 * num_blocks + 0] = block >> 8; - out_addr->bytes[2 * num_blocks + 1] = block & 0xFF; - num_blocks++; - } - else if (num_blocks != compress_pos) { - return 0; - } - -ipv4_done: - if (compress_pos == -1) { - if (num_blocks != 8) { - return 0; - } - compress_pos = 0; - } - - int num_rear = num_blocks - compress_pos; - memmove(out_addr->bytes + 2 * (8 - num_rear), out_addr->bytes + 2 * compress_pos, 2 * num_rear); - memset(out_addr->bytes + 2 * compress_pos, 0, 2 * (8 - num_rear - compress_pos)); - - return 1; - -ipv4_ending: - if (empty || (num_blocks == 0 && compress_pos == -1)) { - return 0; - } - - while (name[i - 1] != ':') { - i--; - } - - uint8_t bytes[4]; - int cur_byte = 0; - uint8_t byte = 0; - empty = 1; - - while (i < name_len) { - if (name[i] == '.') { - if (empty || cur_byte == 3) { - return 0; - } - bytes[cur_byte] = byte; - cur_byte++; - byte = 0; - empty = 1; - } else { - if (!empty && byte == 0) { - return 0; - } - int digit = decode_decimal_digit(name[i]); - if (digit < 0) { - return 0; - } - if (byte > UINT8_MAX / 10) { - return 0; - } - byte *= 10; - if (digit > UINT8_MAX - byte) { - return 0; - } - byte += digit; - empty = 0; - } - i++; - } - - if (cur_byte != 3 || empty) { - return 0; - } - bytes[cur_byte] = byte; - - if (8 - num_blocks < 2) { - return 0; - } - memcpy(out_addr->bytes + 2 * num_blocks, bytes, 4); - num_blocks += 2; - - goto ipv4_done; -} - -int ipaddr6_parse_ipv6_addr (const char *name, struct ipv6_addr *out_addr) -{ - return ipaddr6_parse_ipv6_addr_bin(name, strlen(name), out_addr); -} - -int ipaddr6_parse_ipv6_prefix_bin (const char *str, size_t str_len, int *out_num) -{ - uintmax_t d; - if (!parse_unsigned_integer_bin(str, str_len, &d)) { - return 0; - } - if (d > 128) { - return 0; - } - - *out_num = d; - return 1; -} - -int ipaddr6_parse_ipv6_prefix (const char *str, int *out_num) -{ - return ipaddr6_parse_ipv6_prefix_bin(str, strlen(str), out_num); -} - -int ipaddr6_parse_ipv6_ifaddr_bin (const char *str, size_t str_len, struct ipv6_ifaddr *out) -{ - size_t slash_pos; - if (!b_find_char_bin(str, str_len, '/', &slash_pos)) { - return 0; - } - - return (ipaddr6_parse_ipv6_addr_bin(str, slash_pos, &out->addr) && - ipaddr6_parse_ipv6_prefix_bin(str + slash_pos + 1, str_len - slash_pos - 1, &out->prefix)); -} - -int ipaddr6_parse_ipv6_ifaddr (const char *str, struct ipv6_ifaddr *out) -{ - return ipaddr6_parse_ipv6_ifaddr_bin(str, strlen(str), out); -} - -int ipaddr6_ipv6_ifaddr_from_addr_mask (struct ipv6_addr addr, struct ipv6_addr mask, struct ipv6_ifaddr *out) -{ - int prefix; - if (!ipaddr6_ipv6_prefix_from_mask(mask, &prefix)) { - return 0; - } - - out->addr = addr; - out->prefix = prefix; - return 1; -} - -void ipaddr6_ipv6_mask_from_prefix (int prefix, struct ipv6_addr *out_mask) -{ - ASSERT(prefix >= 0) - ASSERT(prefix <= 128) - - int quot = prefix / 8; - int rem = prefix % 8; - - if (quot > 0) { - memset(out_mask->bytes, UINT8_MAX, quot); - } - if (16 - quot > 0) { - memset(out_mask->bytes + quot, 0, 16 - quot); - } - - for (int i = 0; i < rem; i++) { - out_mask->bytes[quot] |= (uint8_t)1 << (8 - i - 1); - } -} - -int ipaddr6_ipv6_prefix_from_mask (struct ipv6_addr mask, int *out_prefix) -{ - int prefix = 0; - int i = 0; - - while (i < 16 && mask.bytes[i] == UINT8_MAX) { - prefix += 8; - i++; - } - - if (i < 16) { - uint8_t t = 0; - int j; - for (j = 0; j <= 8; j++) { - if (mask.bytes[i] == t) { - break; - } - if (j < 8) { - t |= ((uint8_t)1 << (8 - j - 1)); - } - } - if (!(j <= 8)) { - return 0; - } - - prefix += j; - i++; - - while (i < 16) { - if (mask.bytes[i] != 0) { - return 0; - } - i++; - } - } - - *out_prefix = prefix; - return 1; -} - -int ipaddr6_ipv6_addrs_in_network (struct ipv6_addr addr1, struct ipv6_addr addr2, int netprefix) -{ - ASSERT(netprefix >= 0) - ASSERT(netprefix <= 128) - - int quot = netprefix / 8; - int rem = netprefix % 8; - - if (memcmp(addr1.bytes, addr2.bytes, quot)) { - return 0; - } - - if (rem == 0) { - return 1; - } - - uint8_t t = 0; - for (int i = 0; i < rem; i++) { - t |= (uint8_t)1 << (8 - i - 1); - } - - return ((addr1.bytes[quot] & t) == (addr2.bytes[quot] & t)); -} - -void ipaddr6_print_addr (struct ipv6_addr addr, char *out_buf) -{ - int largest_start = 0; - int largest_len = 0; - int current_start = 0; - int current_len = 0; - - for (int i = 0; i < 8; i++) { - if (addr.bytes[2 * i] == 0 && addr.bytes[2 * i + 1] == 0) { - current_len++; - if (current_len > largest_len) { - largest_start = current_start; - largest_len = current_len; - } - } else { - current_start = i + 1; - current_len = 0; - } - } - - if (largest_len > 1) { - for (int i = 0; i < largest_start; i++) { - uint16_t block = ((uint16_t)addr.bytes[2 * i] << 8) | addr.bytes[2 * i + 1]; - out_buf += sprintf(out_buf, "%"PRIx16":", block); - } - if (largest_start == 0) { - out_buf += sprintf(out_buf, ":"); - } - - for (int i = largest_start + largest_len; i < 8; i++) { - uint16_t block = ((uint16_t)addr.bytes[2 * i] << 8) | addr.bytes[2 * i + 1]; - out_buf += sprintf(out_buf, ":%"PRIx16, block); - } - if (largest_start + largest_len == 8) { - out_buf += sprintf(out_buf, ":"); - } - } else { - const char *prefix = ""; - for (int i = 0; i < 8; i++) { - uint16_t block = ((uint16_t)addr.bytes[2 * i] << 8) | addr.bytes[2 * i + 1]; - out_buf += sprintf(out_buf, "%s%"PRIx16, prefix, block); - prefix = ":"; - } - } -} - -void ipaddr6_print_ifaddr (struct ipv6_ifaddr addr, char *out_buf) -{ - ASSERT(addr.prefix >= 0) - ASSERT(addr.prefix <= 128) - - ipaddr6_print_addr(addr.addr, out_buf); - sprintf(out_buf + strlen(out_buf), "/%d", addr.prefix); -} - -#endif diff --git a/external/badvpn_dns/misc/ipv4_proto.h b/external/badvpn_dns/misc/ipv4_proto.h deleted file mode 100644 index fea7260..0000000 --- a/external/badvpn_dns/misc/ipv4_proto.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file ipv4_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the IPv4 protocol. - */ - -#ifndef BADVPN_MISC_IPV4_PROTO_H -#define BADVPN_MISC_IPV4_PROTO_H - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/packed.h> -#include <misc/read_write_int.h> - -#define IPV4_PROTOCOL_IGMP 2 -#define IPV4_PROTOCOL_UDP 17 - -B_START_PACKED -struct ipv4_header { - uint8_t version4_ihl4; - uint8_t ds; - uint16_t total_length; - // - uint16_t identification; - uint16_t flags3_fragmentoffset13; - // - uint8_t ttl; - uint8_t protocol; - uint16_t checksum; - // - uint32_t source_address; - // - uint32_t destination_address; -} B_PACKED; -B_END_PACKED - -#define IPV4_GET_VERSION(_header) (((_header).version4_ihl4&0xF0)>>4) -#define IPV4_GET_IHL(_header) (((_header).version4_ihl4&0x0F)>>0) - -#define IPV4_MAKE_VERSION_IHL(size) (((size)/4) + (4 << 4)) - -static uint16_t ipv4_checksum (const struct ipv4_header *header, const char *extra, uint16_t extra_len) -{ - ASSERT(extra_len % 2 == 0) - ASSERT(extra_len == 0 || extra) - - uint32_t t = 0; - - for (uint16_t i = 0; i < sizeof(*header) / 2; i++) { - t += badvpn_read_be16((const char *)header + 2 * i); - } - - for (uint16_t i = 0; i < extra_len / 2; i++) { - t += badvpn_read_be16((const char *)extra + 2 * i); - } - - while (t >> 16) { - t = (t & 0xFFFF) + (t >> 16); - } - - return hton16(~t); -} - -static int ipv4_check (uint8_t *data, int data_len, struct ipv4_header *out_header, uint8_t **out_payload, int *out_payload_len) -{ - ASSERT(data_len >= 0) - ASSERT(out_header) - ASSERT(out_payload) - ASSERT(out_payload_len) - - // check base header - if (data_len < sizeof(struct ipv4_header)) { - return 0; - } - memcpy(out_header, data, sizeof(*out_header)); - - // check version - if (IPV4_GET_VERSION(*out_header) != 4) { - return 0; - } - - // check options - uint16_t header_len = IPV4_GET_IHL(*out_header) * 4; - if (header_len < sizeof(struct ipv4_header)) { - return 0; - } - if (header_len > data_len) { - return 0; - } - - // check total length - uint16_t total_length = ntoh16(out_header->total_length); - if (total_length < header_len) { - return 0; - } - if (total_length > data_len) { - return 0; - } - - // check checksum - uint16_t checksum_in_packet = out_header->checksum; - out_header->checksum = hton16(0); - uint16_t checksum_computed = ipv4_checksum(out_header, (char *)data + sizeof(*out_header), header_len - sizeof(*out_header)); - out_header->checksum = checksum_in_packet; - if (checksum_in_packet != checksum_computed) { - return 0; - } - - *out_payload = data + header_len; - *out_payload_len = total_length - header_len; - - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/ipv6_proto.h b/external/badvpn_dns/misc/ipv6_proto.h deleted file mode 100644 index b255541..0000000 --- a/external/badvpn_dns/misc/ipv6_proto.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file ipv6_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_IPV6_PROTO_H -#define BADVPN_IPV6_PROTO_H - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/packed.h> - -#define IPV6_NEXT_IGMP 2 -#define IPV6_NEXT_UDP 17 - -B_START_PACKED -struct ipv6_header { - uint8_t version4_tc4; - uint8_t tc4_fl4; - uint16_t fl; - uint16_t payload_length; - uint8_t next_header; - uint8_t hop_limit; - uint8_t source_address[16]; - uint8_t destination_address[16]; -} B_PACKED; -B_END_PACKED - -static int ipv6_check (uint8_t *data, int data_len, struct ipv6_header *out_header, uint8_t **out_payload, int *out_payload_len) -{ - ASSERT(data_len >= 0) - ASSERT(out_header) - ASSERT(out_payload) - ASSERT(out_payload_len) - - // check base header - if (data_len < sizeof(struct ipv6_header)) { - return 0; - } - memcpy(out_header, data, sizeof(*out_header)); - - // check version - if ((ntoh8(out_header->version4_tc4) >> 4) != 6) { - return 0; - } - - // check payload length - uint16_t payload_length = ntoh16(out_header->payload_length); - if (payload_length > data_len - sizeof(struct ipv6_header)) { - return 0; - } - - *out_payload = data + sizeof(struct ipv6_header); - *out_payload_len = payload_length; - - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/loggers_string.h b/external/badvpn_dns/misc/loggers_string.h deleted file mode 100644 index 66986b8..0000000 --- a/external/badvpn_dns/misc/loggers_string.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file loggers_string.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * List of available loggers. - */ - -#ifndef BADVPN_MISC_LOGGERSSTRING_H -#define BADVPN_MISC_LOGGERSSTRING_H - -#ifdef BADVPN_USE_WINAPI -#define LOGGERS_STRING "stdout" -#else -#define LOGGERS_STRING "stdout/syslog" -#endif - -#endif diff --git a/external/badvpn_dns/misc/loglevel.h b/external/badvpn_dns/misc/loglevel.h deleted file mode 100644 index 6e9f911..0000000 --- a/external/badvpn_dns/misc/loglevel.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file loglevel.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Log level specification parsing function. - */ - -#ifndef BADVPN_MISC_LOGLEVEL_H -#define BADVPN_MISC_LOGLEVEL_H - -#include <string.h> - -#include <base/BLog.h> - -/** - * Parses the log level string. - * - * @param str log level string. Recognizes none, error, warning, notice, - * info, debug. - * @return 0 for none, one of BLOG_* for some log level, -1 for unrecognized - */ -static int parse_loglevel (char *str); - -int parse_loglevel (char *str) -{ - if (!strcmp(str, "none")) { - return 0; - } - if (!strcmp(str, "error")) { - return BLOG_ERROR; - } - if (!strcmp(str, "warning")) { - return BLOG_WARNING; - } - if (!strcmp(str, "notice")) { - return BLOG_NOTICE; - } - if (!strcmp(str, "info")) { - return BLOG_INFO; - } - if (!strcmp(str, "debug")) { - return BLOG_DEBUG; - } - - char *endptr; - long int res = strtol(str, &endptr, 10); - if (*str && !*endptr && res >= 0 && res <= BLOG_DEBUG) { - return res; - } - - return -1; -} - -#endif diff --git a/external/badvpn_dns/misc/maxalign.h b/external/badvpn_dns/misc/maxalign.h deleted file mode 100644 index cb1f460..0000000 --- a/external/badvpn_dns/misc/maxalign.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file maxalign.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_MAXALIGN_H -#define BADVPN_MAXALIGN_H - -#include <stddef.h> -#include <stdint.h> - -typedef union { - short a; - long b; - long long c; - double d; - long double e; - void *f; - uint8_t g; - uint16_t h; - uint32_t i; - uint64_t j; - size_t k; - void (*l) (void); -} bmax_align_t; - -#define BMAX_ALIGN (__alignof(bmax_align_t)) - -#endif diff --git a/external/badvpn_dns/misc/merge.h b/external/badvpn_dns/misc/merge.h deleted file mode 100644 index 5322771..0000000 --- a/external/badvpn_dns/misc/merge.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file merge.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_MERGE_H -#define BADVPN_MERGE_H - -#define MERGE_HELPER(x, y) x ## y -#define MERGE(x, y) MERGE_HELPER(x, y) - -#endif diff --git a/external/badvpn_dns/misc/minmax.h b/external/badvpn_dns/misc/minmax.h deleted file mode 100644 index ca82055..0000000 --- a/external/badvpn_dns/misc/minmax.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file minmax.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Minimum and maximum macros. - */ - -#ifndef BADVPN_MISC_MINMAX_H -#define BADVPN_MISC_MINMAX_H - -#include <stddef.h> -#include <stdint.h> - -#define DEFINE_BMINMAX(name, type) \ -static type bmin ## name (type a, type b) { return (a < b ? a : b); } \ -static type bmax ## name (type a, type b) { return (a > b ? a : b); } - -DEFINE_BMINMAX(_size, size_t) -DEFINE_BMINMAX(_int, int) -DEFINE_BMINMAX(_int8, int8_t) -DEFINE_BMINMAX(_int16, int16_t) -DEFINE_BMINMAX(_int32, int32_t) -DEFINE_BMINMAX(_int64, int64_t) -DEFINE_BMINMAX(_uint, unsigned int) -DEFINE_BMINMAX(_uint8, uint8_t) -DEFINE_BMINMAX(_uint16, uint16_t) -DEFINE_BMINMAX(_uint32, uint32_t) -DEFINE_BMINMAX(_uint64, uint64_t) - -#endif diff --git a/external/badvpn_dns/misc/modadd.h b/external/badvpn_dns/misc/modadd.h deleted file mode 100644 index 4e4f04a..0000000 --- a/external/badvpn_dns/misc/modadd.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file modadd.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Modular addition macro. - * - * Calculates (x + y) mod m, assuming - * 0 <= x < m and 0 <= y < m. - */ - -#ifndef BADVPN_MISC_MODADD_H -#define BADVPN_MISC_MODADD_H - -#include <misc/debug.h> - -#define DECLARE_BMODADD(type, name) \ -static type bmodadd_##name (type x, type y, type m) \ -{ \ - ASSERT(x >= 0) \ - ASSERT(x < m) \ - ASSERT(y >= 0) \ - ASSERT(y < m) \ - \ - if (y >= m - x) { \ - return (y - (m - x)); \ - } else { \ - return (x + y); \ - } \ -} \ - -DECLARE_BMODADD(int, int) - -#endif diff --git a/external/badvpn_dns/misc/mswsock.h b/external/badvpn_dns/misc/mswsock.h deleted file mode 100644 index 4f4c38d..0000000 --- a/external/badvpn_dns/misc/mswsock.h +++ /dev/null @@ -1,229 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the w64 mingw-runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include <winsock2.h> - -#ifndef _MSWSOCK_ -#define _MSWSOCK_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SO_CONNDATA 0x7000 -#define SO_CONNOPT 0x7001 -#define SO_DISCDATA 0x7002 -#define SO_DISCOPT 0x7003 -#define SO_CONNDATALEN 0x7004 -#define SO_CONNOPTLEN 0x7005 -#define SO_DISCDATALEN 0x7006 -#define SO_DISCOPTLEN 0x7007 - -#define SO_OPENTYPE 0x7008 - -#define SO_SYNCHRONOUS_ALERT 0x10 -#define SO_SYNCHRONOUS_NONALERT 0x20 - -#define SO_MAXDG 0x7009 -#define SO_MAXPATHDG 0x700A -#define SO_UPDATE_ACCEPT_CONTEXT 0x700B -#define SO_CONNECT_TIME 0x700C -#define SO_UPDATE_CONNECT_CONTEXT 0x7010 - -#define TCP_BSDURGENT 0x7000 - -#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) -#if (_WIN32_WINNT < 0x0600) && (_WIN32_WINNT >= 0x0501) -#define SIO_SOCKET_CLOSE_NOTIFY _WSAIOW(IOC_VENDOR,13) -#endif /* >= XP && < VISTA */ -#if (_WIN32_WINNT >= 0x0600) -#define SIO_BSP_HANDLE _WSAIOR(IOC_WS2,27) -#define SIO_BSP_HANDLE_SELECT _WSAIOR(IOC_WS2,28) -#define SIO_BSP_HANDLE_POLL _WSAIOR(IOC_WS2,29) - -#define SIO_EXT_SELECT _WSAIORW(IOC_WS2,30) -#define SIO_EXT_POLL _WSAIORW(IOC_WS2,31) -#define SIO_EXT_SENDMSG _WSAIORW(IOC_WS2,32) - -#define SIO_BASE_HANDLE _WSAIOR(IOC_WS2,34) -#endif /* _WIN32_WINNT >= 0x0600 */ - -#ifndef __MSWSOCK_WS1_SHARED - int WINAPI WSARecvEx(SOCKET s,char *buf,int len,int *flags); -#endif /* __MSWSOCK_WS1_SHARED */ - -#define TF_DISCONNECT 0x01 -#define TF_REUSE_SOCKET 0x02 -#define TF_WRITE_BEHIND 0x04 -#define TF_USE_DEFAULT_WORKER 0x00 -#define TF_USE_SYSTEM_THREAD 0x10 -#define TF_USE_KERNEL_APC 0x20 - -#include <psdk_inc/_xmitfile.h> -#ifndef __MSWSOCK_WS1_SHARED - WINBOOL WINAPI TransmitFile(SOCKET hSocket,HANDLE hFile,DWORD nNumberOfBytesToWrite,DWORD nNumberOfBytesPerSend,LPOVERLAPPED lpOverlapped,LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,DWORD dwReserved); - WINBOOL WINAPI AcceptEx(SOCKET sListenSocket,SOCKET sAcceptSocket,PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPDWORD lpdwBytesReceived,LPOVERLAPPED lpOverlapped); - VOID WINAPI GetAcceptExSockaddrs(PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,struct sockaddr **LocalSockaddr,LPINT LocalSockaddrLength,struct sockaddr **RemoteSockaddr,LPINT RemoteSockaddrLength); -#endif /* __MSWSOCK_WS1_SHARED */ - - typedef WINBOOL (WINAPI *LPFN_TRANSMITFILE)(SOCKET hSocket,HANDLE hFile,DWORD nNumberOfBytesToWrite,DWORD nNumberOfBytesPerSend,LPOVERLAPPED lpOverlapped,LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,DWORD dwReserved); - -#define WSAID_TRANSMITFILE {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} - - typedef WINBOOL (WINAPI *LPFN_ACCEPTEX)(SOCKET sListenSocket,SOCKET sAcceptSocket,PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,LPDWORD lpdwBytesReceived,LPOVERLAPPED lpOverlapped); - -#define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} - - typedef VOID (WINAPI *LPFN_GETACCEPTEXSOCKADDRS)(PVOID lpOutputBuffer,DWORD dwReceiveDataLength,DWORD dwLocalAddressLength,DWORD dwRemoteAddressLength,struct sockaddr **LocalSockaddr,LPINT LocalSockaddrLength,struct sockaddr **RemoteSockaddr,LPINT RemoteSockaddrLength); - -#define WSAID_GETACCEPTEXSOCKADDRS {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} - - typedef struct _TRANSMIT_PACKETS_ELEMENT { - ULONG dwElFlags; -#define TP_ELEMENT_MEMORY 1 -#define TP_ELEMENT_FILE 2 -#define TP_ELEMENT_EOP 4 - ULONG cLength; - __MINGW_EXTENSION union { - __MINGW_EXTENSION struct { - LARGE_INTEGER nFileOffset; - HANDLE hFile; - }; - PVOID pBuffer; - }; - } TRANSMIT_PACKETS_ELEMENT,*PTRANSMIT_PACKETS_ELEMENT,*LPTRANSMIT_PACKETS_ELEMENT; - -#define TP_DISCONNECT TF_DISCONNECT -#define TP_REUSE_SOCKET TF_REUSE_SOCKET -#define TP_USE_DEFAULT_WORKER TF_USE_DEFAULT_WORKER -#define TP_USE_SYSTEM_THREAD TF_USE_SYSTEM_THREAD -#define TP_USE_KERNEL_APC TF_USE_KERNEL_APC - - typedef WINBOOL (WINAPI *LPFN_TRANSMITPACKETS) (SOCKET hSocket,LPTRANSMIT_PACKETS_ELEMENT lpPacketArray,DWORD nElementCount,DWORD nSendSize,LPOVERLAPPED lpOverlapped,DWORD dwFlags); - -#define WSAID_TRANSMITPACKETS {0xd9689da0,0x1f90,0x11d3,{0x99,0x71,0x00,0xc0,0x4f,0x68,0xc8,0x76}} - - typedef WINBOOL (WINAPI *LPFN_CONNECTEX)(SOCKET s,const struct sockaddr *name,int namelen,PVOID lpSendBuffer,DWORD dwSendDataLength,LPDWORD lpdwBytesSent,LPOVERLAPPED lpOverlapped); - -#define WSAID_CONNECTEX {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}} - - typedef WINBOOL (WINAPI *LPFN_DISCONNECTEX)(SOCKET s,LPOVERLAPPED lpOverlapped,DWORD dwFlags,DWORD dwReserved); - -#define WSAID_DISCONNECTEX {0x7fda2e11,0x8630,0x436f,{0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57}} - -#define DE_REUSE_SOCKET TF_REUSE_SOCKET - -#define NLA_NAMESPACE_GUID {0x6642243a,0x3ba8,0x4aa6,{0xba,0xa5,0x2e,0xb,0xd7,0x1f,0xdd,0x83}} - -#define NLA_SERVICE_CLASS_GUID {0x37e515,0xb5c9,0x4a43,{0xba,0xda,0x8b,0x48,0xa8,0x7a,0xd2,0x39}} - -#define NLA_ALLUSERS_NETWORK 0x00000001 -#define NLA_FRIENDLY_NAME 0x00000002 - - typedef enum _NLA_BLOB_DATA_TYPE { - NLA_RAW_DATA = 0,NLA_INTERFACE = 1,NLA_802_1X_LOCATION = 2,NLA_CONNECTIVITY = 3,NLA_ICS = 4 - } NLA_BLOB_DATA_TYPE,*PNLA_BLOB_DATA_TYPE; - - typedef enum _NLA_CONNECTIVITY_TYPE { - NLA_NETWORK_AD_HOC = 0,NLA_NETWORK_MANAGED = 1,NLA_NETWORK_UNMANAGED = 2,NLA_NETWORK_UNKNOWN = 3 - } NLA_CONNECTIVITY_TYPE,*PNLA_CONNECTIVITY_TYPE; - - typedef enum _NLA_INTERNET { - NLA_INTERNET_UNKNOWN = 0,NLA_INTERNET_NO = 1,NLA_INTERNET_YES = 2 - } NLA_INTERNET,*PNLA_INTERNET; - - typedef struct _NLA_BLOB { - struct { - NLA_BLOB_DATA_TYPE type; - DWORD dwSize; - DWORD nextOffset; - } header; - union { - CHAR rawData[1]; - struct { - DWORD dwType; - DWORD dwSpeed; - CHAR adapterName[1]; - } interfaceData; - struct { - CHAR information[1]; - } locationData; - struct { - NLA_CONNECTIVITY_TYPE type; - NLA_INTERNET internet; - } connectivity; - struct { - struct { - DWORD speed; - DWORD type; - DWORD state; - WCHAR machineName[256]; - WCHAR sharedAdapterName[256]; - } remote; - } ICS; - } data; - } NLA_BLOB,*PNLA_BLOB,*LPNLA_BLOB; - -#ifdef BADVPN_SHIPPED_MSWSOCK_DECLARE_WSAMSG - typedef struct _WSAMSG { - LPSOCKADDR name; - INT namelen; - LPWSABUF lpBuffers; - DWORD dwBufferCount; - WSABUF Control; - DWORD dwFlags; - } WSAMSG,*PWSAMSG,*LPWSAMSG; -#endif - - typedef struct _WSACMSGHDR { - SIZE_T cmsg_len; - INT cmsg_level; - INT cmsg_type; - } WSACMSGHDR,*PWSACMSGHDR,*LPWSACMSGHDR; - -#define WSA_CMSGHDR_ALIGN(length) (((length) + TYPE_ALIGNMENT(WSACMSGHDR)-1) & (~(TYPE_ALIGNMENT(WSACMSGHDR)-1))) -#define WSA_CMSGDATA_ALIGN(length) (((length) + MAX_NATURAL_ALIGNMENT-1) & (~(MAX_NATURAL_ALIGNMENT-1))) -#define WSA_CMSG_FIRSTHDR(msg) (((msg)->Control.len >= sizeof(WSACMSGHDR)) ? (LPWSACMSGHDR)(msg)->Control.buf : (LPWSACMSGHDR)NULL) -#define WSA_CMSG_NXTHDR(msg,cmsg) ((!(cmsg)) ? WSA_CMSG_FIRSTHDR(msg) : ((((u_char *)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len) + sizeof(WSACMSGHDR)) > (u_char *)((msg)->Control.buf) + (msg)->Control.len) ? (LPWSACMSGHDR)NULL : (LPWSACMSGHDR)((u_char *)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len)))) -#define WSA_CMSG_DATA(cmsg) ((u_char *)(cmsg) + WSA_CMSGDATA_ALIGN(sizeof(WSACMSGHDR))) -#define WSA_CMSG_SPACE(length) (WSA_CMSGDATA_ALIGN(sizeof(WSACMSGHDR) + WSA_CMSGHDR_ALIGN(length))) -#define WSA_CMSG_LEN(length) (WSA_CMSGDATA_ALIGN(sizeof(WSACMSGHDR)) + length) - -#define MSG_TRUNC 0x0100 -#define MSG_CTRUNC 0x0200 -#define MSG_BCAST 0x0400 -#define MSG_MCAST 0x0800 - - typedef INT (WINAPI *LPFN_WSARECVMSG)(SOCKET s, LPWSAMSG lpMsg, - LPDWORD lpdwNumberOfBytesRecvd, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); - -#define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}} - -#if(_WIN32_WINNT >= 0x0600) - typedef struct { - LPWSAMSG lpMsg; - DWORD dwFlags; - LPDWORD lpNumberOfBytesSent; - LPWSAOVERLAPPED lpOverlapped; - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine; - } WSASENDMSG, *LPWSASENDMSG; - - typedef INT (WSAAPI *LPFN_WSASENDMSG)(SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags, - LPDWORD lpNumberOfBytesSent, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); - -#define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}} - -#endif /* (_WIN32_WINNT >= 0x0600) */ - -#ifdef __cplusplus -} -#endif - -#endif /* _MSWSOCK_ */ diff --git a/external/badvpn_dns/misc/nonblocking.h b/external/badvpn_dns/misc/nonblocking.h deleted file mode 100644 index fe82584..0000000 --- a/external/badvpn_dns/misc/nonblocking.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file nonblocking.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function for enabling non-blocking mode for a file descriptor. - */ - -#ifndef BADVPN_MISC_NONBLOCKING_H -#define BADVPN_MISC_NONBLOCKING_H - -#include <unistd.h> -#include <fcntl.h> - -static int badvpn_set_nonblocking (int fd); - -int badvpn_set_nonblocking (int fd) -{ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - return 0; - } - - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/nsskey.h b/external/badvpn_dns/misc/nsskey.h deleted file mode 100644 index 8268235..0000000 --- a/external/badvpn_dns/misc/nsskey.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file nsskey.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function for opening a NSS certificate and its private key. - */ - -#ifndef BADVPN_MISC_NSSKEY_H -#define BADVPN_MISC_NSSKEY_H - -#include <stdlib.h> - -#include <prerror.h> -#include <cert.h> -#include <keyhi.h> -#include <pk11func.h> - -#include <base/BLog.h> - -#include <generated/blog_channel_nsskey.h> - -/** - * Opens a NSS certificate and its private key. - * - * @param name name of the certificate - * @param out_cert on success, the certificate will be returned here. Should be - * released with CERT_DestroyCertificate. - * @param out_key on success, the private key will be returned here. Should be - * released with SECKEY_DestroyPrivateKey. - * @return 1 on success, 0 on failure - */ -static int open_nss_cert_and_key (char *name, CERTCertificate **out_cert, SECKEYPrivateKey **out_key) WARN_UNUSED; - -static SECKEYPrivateKey * find_nss_private_key (char *name) -{ - SECKEYPrivateKey *key = NULL; - - PK11SlotList *slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL); - if (!slot_list) { - return NULL; - } - - PK11SlotListElement *slot_entry; - for (slot_entry = slot_list->head; !key && slot_entry; slot_entry = slot_entry->next) { - SECKEYPrivateKeyList *key_list = PK11_ListPrivKeysInSlot(slot_entry->slot, name, NULL); - if (!key_list) { - BLog(BLOG_ERROR, "PK11_ListPrivKeysInSlot failed"); - continue; - } - - SECKEYPrivateKeyListNode *key_node; - for (key_node = PRIVKEY_LIST_HEAD(key_list); !key && !PRIVKEY_LIST_END(key_node, key_list); key_node = PRIVKEY_LIST_NEXT(key_node)) { - char *key_name = PK11_GetPrivateKeyNickname(key_node->key); - if (!key_name || strcmp(key_name, name)) { - PORT_Free((void *)key_name); - continue; - } - PORT_Free((void *)key_name); - - key = SECKEY_CopyPrivateKey(key_node->key); - } - - SECKEY_DestroyPrivateKeyList(key_list); - } - - PK11_FreeSlotList(slot_list); - - return key; -} - -int open_nss_cert_and_key (char *name, CERTCertificate **out_cert, SECKEYPrivateKey **out_key) -{ - CERTCertificate *cert; - cert = CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(), name); - if (!cert) { - BLog(BLOG_ERROR, "CERT_FindCertByName failed (%d)", (int)PR_GetError()); - return 0; - } - - SECKEYPrivateKey *key = find_nss_private_key(name); - if (!key) { - BLog(BLOG_ERROR, "Failed to find private key"); - CERT_DestroyCertificate(cert); - return 0; - } - - *out_cert = cert; - *out_key = key; - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/offset.h b/external/badvpn_dns/misc/offset.h deleted file mode 100644 index 23b7683..0000000 --- a/external/badvpn_dns/misc/offset.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file offset.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Macros for determining offsets of members in structs. - */ - -#ifndef BADVPN_MISC_OFFSET_H -#define BADVPN_MISC_OFFSET_H - -#include <stddef.h> -#include <stdint.h> - -/** - * Returns a pointer to a struct, given a pointer to its member. - */ -#define UPPER_OBJECT(_ptr, _object_type, _field_name) ((_object_type *)((char *)(_ptr) - offsetof(_object_type, _field_name))) - -/** - * Returns the offset of one struct member from another. - * Expands to an int. - */ -#define OFFSET_DIFF(_object_type, _field1, _field2) ((int)offsetof(_object_type, _field1) - (int)offsetof(_object_type, _field2)) - -#endif diff --git a/external/badvpn_dns/misc/open_standard_streams.h b/external/badvpn_dns/misc/open_standard_streams.h deleted file mode 100644 index 7fd6d41..0000000 --- a/external/badvpn_dns/misc/open_standard_streams.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file open_standard_streams.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_OPEN_STANDARD_STREAMS_H -#define BADVPN_OPEN_STANDARD_STREAMS_H - -#ifndef BADVPN_USE_WINAPI -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#endif - -static void open_standard_streams (void) -{ -#ifndef BADVPN_USE_WINAPI - int fd; - - do { - fd = open("/dev/null", O_RDWR); - if (fd > 2) { - close(fd); - } - } while (fd >= 0 && fd <= 2); -#endif -} - -#endif diff --git a/external/badvpn_dns/misc/overflow.h b/external/badvpn_dns/misc/overflow.h deleted file mode 100644 index 9fde52a..0000000 --- a/external/badvpn_dns/misc/overflow.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file overflow.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Functions for checking for overflow of integer addition. - */ - -#ifndef BADVPN_MISC_OVERFLOW_H -#define BADVPN_MISC_OVERFLOW_H - -#include <limits.h> -#include <stdint.h> - -#define DEFINE_UNSIGNED_OVERFLOW(_name, _type, _max) \ -static int add_ ## _name ## _overflows (_type a, _type b) \ -{\ - return (b > _max - a); \ -} - -#define DEFINE_SIGNED_OVERFLOW(_name, _type, _min, _max) \ -static int add_ ## _name ## _overflows (_type a, _type b) \ -{\ - if ((a < 0) ^ (b < 0)) return 0; \ - if (a < 0) return -(a < _min - b); \ - return (a > _max - b); \ -} - -DEFINE_UNSIGNED_OVERFLOW(uint, unsigned int, UINT_MAX) -DEFINE_UNSIGNED_OVERFLOW(uint8, uint8_t, UINT8_MAX) -DEFINE_UNSIGNED_OVERFLOW(uint16, uint16_t, UINT16_MAX) -DEFINE_UNSIGNED_OVERFLOW(uint32, uint32_t, UINT32_MAX) -DEFINE_UNSIGNED_OVERFLOW(uint64, uint64_t, UINT64_MAX) - -DEFINE_SIGNED_OVERFLOW(int, int, INT_MIN, INT_MAX) -DEFINE_SIGNED_OVERFLOW(int8, int8_t, INT8_MIN, INT8_MAX) -DEFINE_SIGNED_OVERFLOW(int16, int16_t, INT16_MIN, INT16_MAX) -DEFINE_SIGNED_OVERFLOW(int32, int32_t, INT32_MIN, INT32_MAX) -DEFINE_SIGNED_OVERFLOW(int64, int64_t, INT64_MIN, INT64_MAX) - -#endif diff --git a/external/badvpn_dns/misc/packed.h b/external/badvpn_dns/misc/packed.h deleted file mode 100644 index 2175536..0000000 --- a/external/badvpn_dns/misc/packed.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file packed.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Structure packing macros. - */ - -#ifndef BADVPN_PACKED_H -#define BADVPN_PACKED_H - -#ifdef _MSC_VER - -#define B_START_PACKED __pragma(pack(push, 1)) -#define B_END_PACKED __pragma(pack(pop)) -#define B_PACKED - -#else - -#define B_START_PACKED -#define B_END_PACKED -#define B_PACKED __attribute__((packed)) - -#endif - -#endif diff --git a/external/badvpn_dns/misc/parse_number.h b/external/badvpn_dns/misc/parse_number.h deleted file mode 100644 index 2601ebb..0000000 --- a/external/badvpn_dns/misc/parse_number.h +++ /dev/null @@ -1,304 +0,0 @@ -/** - * @file parse_number.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Numeric string parsing. - */ - -#ifndef BADVPN_MISC_PARSE_NUMBER_H -#define BADVPN_MISC_PARSE_NUMBER_H - -#include <stdint.h> -#include <string.h> -#include <stddef.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/cstring.h> - -// public parsing functions -static int decode_decimal_digit (char c); -static int decode_hex_digit (char c); -static int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out) WARN_UNUSED; -static int parse_unsigned_integer (const char *str, uintmax_t *out) WARN_UNUSED; -static int parse_unsigned_integer_cstr (b_cstring cstr, size_t offset, size_t length, uintmax_t *out) WARN_UNUSED; -static int parse_unsigned_hex_integer_bin (const char *str, size_t str_len, uintmax_t *out) WARN_UNUSED; -static int parse_unsigned_hex_integer (const char *str, uintmax_t *out) WARN_UNUSED; -static int parse_signmag_integer_bin (const char *str, size_t str_len, int *out_sign, uintmax_t *out_mag) WARN_UNUSED; -static int parse_signmag_integer (const char *str, int *out_sign, uintmax_t *out_mag) WARN_UNUSED; -static int parse_signmag_integer_cstr (b_cstring cstr, size_t offset, size_t length, int *out_sign, uintmax_t *out_mag) WARN_UNUSED; - -// public generation functions -static int compute_decimal_repr_size (uintmax_t x); -static void generate_decimal_repr (uintmax_t x, char *out, int repr_size); -static int generate_decimal_repr_string (uintmax_t x, char *out); - -// implementation follows - -// decimal representation of UINTMAX_MAX -static const char parse_number__uintmax_max_str[] = "18446744073709551615"; - -// make sure UINTMAX_MAX is what we think it is -static const char parse_number__uintmax_max_str_assert[(UINTMAX_MAX == UINTMAX_C(18446744073709551615)) ? 1 : -1]; - -static int decode_decimal_digit (char c) -{ - switch (c) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - } - - return -1; -} - -static int decode_hex_digit (char c) -{ - switch (c) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'A': case 'a': return 10; - case 'B': case 'b': return 11; - case 'C': case 'c': return 12; - case 'D': case 'd': return 13; - case 'E': case 'e': return 14; - case 'F': case 'f': return 15; - } - - return -1; -} - -static int parse__no_overflow (const char *str, size_t str_len, uintmax_t *out) -{ - uintmax_t n = 0; - - while (str_len > 0) { - if (*str < '0' || *str > '9') { - return 0; - } - - n = 10 * n + (*str - '0'); - - str++; - str_len--; - } - - *out = n; - return 1; -} - -int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out) -{ - // we do not allow empty strings - if (str_len == 0) { - return 0; - } - - // remove leading zeros - while (str_len > 0 && *str == '0') { - str++; - str_len--; - } - - // detect overflow - if (str_len > sizeof(parse_number__uintmax_max_str) - 1 || - (str_len == sizeof(parse_number__uintmax_max_str) - 1 && memcmp(str, parse_number__uintmax_max_str, sizeof(parse_number__uintmax_max_str) - 1) > 0)) { - return 0; - } - - // will not overflow (but can still have invalid characters) - return parse__no_overflow(str, str_len, out); -} - -int parse_unsigned_integer (const char *str, uintmax_t *out) -{ - return parse_unsigned_integer_bin(str, strlen(str), out); -} - -int parse_unsigned_integer_cstr (b_cstring cstr, size_t offset, size_t length, uintmax_t *out) -{ - b_cstring_assert_range(cstr, offset, length); - - if (length == 0) { - return 0; - } - - uintmax_t n = 0; - - B_CSTRING_LOOP_RANGE(cstr, offset, length, pos, chunk_data, chunk_length, { - for (size_t i = 0; i < chunk_length; i++) { - int digit = decode_decimal_digit(chunk_data[i]); - if (digit < 0) { - return 0; - } - if (n > UINTMAX_MAX / 10) { - return 0; - } - n *= 10; - if (digit > UINTMAX_MAX - n) { - return 0; - } - n += digit; - } - }) - - *out = n; - return 1; -} - -int parse_unsigned_hex_integer_bin (const char *str, size_t str_len, uintmax_t *out) -{ - uintmax_t n = 0; - - if (str_len == 0) { - return 0; - } - - while (str_len > 0) { - int digit = decode_hex_digit(*str); - if (digit < 0) { - return 0; - } - - if (n > UINTMAX_MAX / 16) { - return 0; - } - n *= 16; - - if (digit > UINTMAX_MAX - n) { - return 0; - } - n += digit; - - str++; - str_len--; - } - - *out = n; - return 1; -} - -int parse_unsigned_hex_integer (const char *str, uintmax_t *out) -{ - return parse_unsigned_hex_integer_bin(str, strlen(str), out); -} - -int parse_signmag_integer_bin (const char *str, size_t str_len, int *out_sign, uintmax_t *out_mag) -{ - int sign = 1; - if (str_len > 0 && (str[0] == '+' || str[0] == '-')) { - sign = 1 - 2 * (str[0] == '-'); - str++; - str_len--; - } - - if (!parse_unsigned_integer_bin(str, str_len, out_mag)) { - return 0; - } - - *out_sign = sign; - return 1; -} - -int parse_signmag_integer (const char *str, int *out_sign, uintmax_t *out_mag) -{ - return parse_signmag_integer_bin(str, strlen(str), out_sign, out_mag); -} - -int parse_signmag_integer_cstr (b_cstring cstr, size_t offset, size_t length, int *out_sign, uintmax_t *out_mag) -{ - b_cstring_assert_range(cstr, offset, length); - - int sign = 1; - if (length > 0 && (b_cstring_at(cstr, offset) == '+' || b_cstring_at(cstr, offset) == '-')) { - sign = 1 - 2 * (b_cstring_at(cstr, offset) == '-'); - offset++; - length--; - } - - if (!parse_unsigned_integer_cstr(cstr, offset, length, out_mag)) { - return 0; - } - - *out_sign = sign; - return 1; -} - -int compute_decimal_repr_size (uintmax_t x) -{ - int size = 0; - - do { - size++; - x /= 10; - } while (x > 0); - - return size; -} - -void generate_decimal_repr (uintmax_t x, char *out, int repr_size) -{ - ASSERT(out) - ASSERT(repr_size == compute_decimal_repr_size(x)) - - out += repr_size; - - do { - *(--out) = '0' + (x % 10); - x /= 10; - } while (x > 0); -} - -int generate_decimal_repr_string (uintmax_t x, char *out) -{ - ASSERT(out) - - int repr_size = compute_decimal_repr_size(x); - generate_decimal_repr(x, out, repr_size); - out[repr_size] = '\0'; - - return repr_size; -} - -#endif diff --git a/external/badvpn_dns/misc/print_macros.h b/external/badvpn_dns/misc/print_macros.h deleted file mode 100644 index a07fdbe..0000000 --- a/external/badvpn_dns/misc/print_macros.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file print_macros.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Format macros for printf() for non-standard compilers. - */ - -#ifndef BADVPN_PRINT_MACROS -#define BADVPN_PRINT_MACROS - -#ifdef _MSC_VER - -// size_t -#define PRIsz "Iu" - -// signed exact width (intN_t) -#define PRId8 "d" -#define PRIi8 "i" -#define PRId16 "d" -#define PRIi16 "i" -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRId64 "I64d" -#define PRIi64 "I64i" - -// unsigned exact width (uintN_t) -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIo16 "o" -#define PRIu16 "u" -#define PRIx16 "x" -#define PRIX16 "X" -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" - -// signed maximum width (intmax_t) -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -// unsigned maximum width (uintmax_t) -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -// signed pointer (intptr_t) -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// unsigned pointer (uintptr_t) -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -#else - -#include <inttypes.h> - -#define PRIsz "zu" - -#endif - -#endif diff --git a/external/badvpn_dns/misc/read_file.h b/external/badvpn_dns/misc/read_file.h deleted file mode 100644 index e1862e5..0000000 --- a/external/badvpn_dns/misc/read_file.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file read_file.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function for reading a file into memory using stdio. - */ - -#ifndef BADVPN_MISC_READ_FILE_H -#define BADVPN_MISC_READ_FILE_H - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> - -static int read_file (const char *file, uint8_t **out_data, size_t *out_len) -{ - FILE *f = fopen(file, "r"); - if (!f) { - goto fail0; - } - - size_t buf_len = 0; - size_t buf_size = 128; - - uint8_t *buf = (uint8_t *)malloc(buf_size); - if (!buf) { - goto fail1; - } - - while (1) { - if (buf_len == buf_size) { - if (2 > SIZE_MAX / buf_size) { - goto fail; - } - size_t newsize = 2 * buf_size; - - uint8_t *newbuf = (uint8_t *)realloc(buf, newsize); - if (!newbuf) { - goto fail; - } - - buf = newbuf; - buf_size = newsize; - } - - size_t bytes = fread(buf + buf_len, 1, buf_size - buf_len, f); - if (bytes == 0) { - if (feof(f)) { - break; - } - goto fail; - } - - buf_len += bytes; - } - - fclose(f); - - *out_data = buf; - *out_len = buf_len; - return 1; - -fail: - free(buf); -fail1: - fclose(f); -fail0: - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/read_write_int.h b/external/badvpn_dns/misc/read_write_int.h deleted file mode 100644 index bc4ed2c..0000000 --- a/external/badvpn_dns/misc/read_write_int.h +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @file read_write_int.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_READ_WRITE_INT_H -#define BADVPN_READ_WRITE_INT_H - -#include <stdint.h> - -static uint8_t badvpn_read_le8 (const char *c_ptr); -static uint16_t badvpn_read_le16 (const char *c_ptr); -static uint32_t badvpn_read_le32 (const char *c_ptr); -static uint64_t badvpn_read_le64 (const char *c_ptr); - -static uint8_t badvpn_read_be8 (const char *c_ptr); -static uint16_t badvpn_read_be16 (const char *c_ptr); -static uint32_t badvpn_read_be32 (const char *c_ptr); -static uint64_t badvpn_read_be64 (const char *c_ptr); - -static void badvpn_write_le8 (uint8_t x, char *c_ptr); -static void badvpn_write_le16 (uint16_t x, char *c_ptr); -static void badvpn_write_le32 (uint32_t x, char *c_ptr); -static void badvpn_write_le64 (uint64_t x, char *c_ptr); - -static void badvpn_write_be8 (uint8_t x, char *c_ptr); -static void badvpn_write_be16 (uint16_t x, char *c_ptr); -static void badvpn_write_be32 (uint32_t x, char *c_ptr); -static void badvpn_write_be64 (uint64_t x, char *c_ptr); - -static uint8_t badvpn_read_le8 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint8_t)ptr[0] << 0); -} - -static uint16_t badvpn_read_le16 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint16_t)ptr[1] << 8) | ((uint16_t)ptr[0] << 0); -} - -static uint32_t badvpn_read_le32 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint32_t)ptr[3] << 24) | ((uint32_t)ptr[2] << 16) | - ((uint32_t)ptr[1] << 8) | ((uint32_t)ptr[0] << 0); -} - -static uint64_t badvpn_read_le64 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint64_t)ptr[7] << 56) | ((uint64_t)ptr[6] << 48) | - ((uint64_t)ptr[5] << 40) | ((uint64_t)ptr[4] << 32) | - ((uint64_t)ptr[3] << 24) | ((uint64_t)ptr[2] << 16) | - ((uint64_t)ptr[1] << 8) | ((uint64_t)ptr[0] << 0); -} - -static uint8_t badvpn_read_be8 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint8_t)ptr[0] << 0); -} - -static uint16_t badvpn_read_be16 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint16_t)ptr[0] << 8) | ((uint16_t)ptr[1] << 0); -} - -static uint32_t badvpn_read_be32 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint32_t)ptr[0] << 24) | ((uint32_t)ptr[1] << 16) | - ((uint32_t)ptr[2] << 8) | ((uint32_t)ptr[3] << 0); -} - -static uint64_t badvpn_read_be64 (const char *c_ptr) -{ - const uint8_t *ptr = (const uint8_t *)c_ptr; - return ((uint64_t)ptr[0] << 56) | ((uint64_t)ptr[1] << 48) | - ((uint64_t)ptr[2] << 40) | ((uint64_t)ptr[3] << 32) | - ((uint64_t)ptr[4] << 24) | ((uint64_t)ptr[5] << 16) | - ((uint64_t)ptr[6] << 8) | ((uint64_t)ptr[7] << 0); -} - -static void badvpn_write_le8 (uint8_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[0] = x >> 0; -} - -static void badvpn_write_le16 (uint16_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[1] = x >> 8; - ptr[0] = x >> 0; -} - -static void badvpn_write_le32 (uint32_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[3] = x >> 24; - ptr[2] = x >> 16; - ptr[1] = x >> 8; - ptr[0] = x >> 0; -} - -static void badvpn_write_le64 (uint64_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[7] = x >> 56; - ptr[6] = x >> 48; - ptr[5] = x >> 40; - ptr[4] = x >> 32; - ptr[3] = x >> 24; - ptr[2] = x >> 16; - ptr[1] = x >> 8; - ptr[0] = x >> 0; -} - -static void badvpn_write_be8 (uint8_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[0] = x >> 0; -} - -static void badvpn_write_be16 (uint16_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[0] = x >> 8; - ptr[1] = x >> 0; -} - -static void badvpn_write_be32 (uint32_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[0] = x >> 24; - ptr[1] = x >> 16; - ptr[2] = x >> 8; - ptr[3] = x >> 0; -} - -static void badvpn_write_be64 (uint64_t x, char *c_ptr) -{ - uint8_t *ptr = (uint8_t *)c_ptr; - ptr[0] = x >> 56; - ptr[1] = x >> 48; - ptr[2] = x >> 40; - ptr[3] = x >> 32; - ptr[4] = x >> 24; - ptr[5] = x >> 16; - ptr[6] = x >> 8; - ptr[7] = x >> 0; -} - -#endif diff --git a/external/badvpn_dns/misc/socks_proto.h b/external/badvpn_dns/misc/socks_proto.h deleted file mode 100644 index 41f5a1f..0000000 --- a/external/badvpn_dns/misc/socks_proto.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file socks_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the SOCKS protocol. - */ - -#ifndef BADVPN_MISC_SOCKS_PROTO_H -#define BADVPN_MISC_SOCKS_PROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define SOCKS_VERSION 0x05 - -#define SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED 0x00 -#define SOCKS_METHOD_GSSAPI 0x01 -#define SOCKS_METHOD_USERNAME_PASSWORD 0x02 -#define SOCKS_METHOD_NO_ACCEPTABLE_METHODS 0xFF - -#define SOCKS_CMD_CONNECT 0x01 -#define SOCKS_CMD_BIND 0x02 -#define SOCKS_CMD_UDP_ASSOCIATE 0x03 - -#define SOCKS_ATYP_IPV4 0x01 -#define SOCKS_ATYP_DOMAINNAME 0x03 -#define SOCKS_ATYP_IPV6 0x04 - -#define SOCKS_REP_SUCCEEDED 0x00 -#define SOCKS_REP_GENERAL_FAILURE 0x01 -#define SOCKS_REP_CONNECTION_NOT_ALLOWED 0x02 -#define SOCKS_REP_NETWORK_UNREACHABLE 0x03 -#define SOCKS_REP_HOST_UNREACHABLE 0x04 -#define SOCKS_REP_CONNECTION_REFUSED 0x05 -#define SOCKS_REP_TTL_EXPIRED 0x06 -#define SOCKS_REP_COMMAND_NOT_SUPPORTED 0x07 -#define SOCKS_REP_ADDRESS_TYPE_NOT_SUPPORTED 0x08 - -B_START_PACKED -struct socks_client_hello_header { - uint8_t ver; - uint8_t nmethods; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_client_hello_method { - uint8_t method; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_server_hello { - uint8_t ver; - uint8_t method; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_request_header { - uint8_t ver; - uint8_t cmd; - uint8_t rsv; - uint8_t atyp; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_reply_header { - uint8_t ver; - uint8_t rep; - uint8_t rsv; - uint8_t atyp; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_addr_ipv4 { - uint32_t addr; - uint16_t port; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct socks_addr_ipv6 { - uint8_t addr[16]; - uint16_t port; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/misc/sslsocket.h b/external/badvpn_dns/misc/sslsocket.h deleted file mode 100644 index 71e43c2..0000000 --- a/external/badvpn_dns/misc/sslsocket.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @file sslsocket.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Structure for moving around sockets, possibly together with SSL compoments. - */ - -#ifndef BADVPN_MISC_SSLSOCKET_H -#define BADVPN_MISC_SSLSOCKET_H - -#include <prio.h> - -#include <system/BConnection.h> -#include <nspr_support/BSSLConnection.h> - -typedef struct { - BConnection con; - PRFileDesc bottom_prfd; - PRFileDesc *ssl_prfd; -} sslsocket; - -#endif diff --git a/external/badvpn_dns/misc/stdbuf_cmdline.h b/external/badvpn_dns/misc/stdbuf_cmdline.h deleted file mode 100644 index 8459c64..0000000 --- a/external/badvpn_dns/misc/stdbuf_cmdline.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file stdbuf_cmdline.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Builds command line for running a program via stdbuf. - */ - -#ifndef BADVPN_STDBUF_CMDLINE_H -#define BADVPN_STDBUF_CMDLINE_H - -#include <string.h> - -#include <misc/debug.h> -#include <misc/cmdline.h> -#include <misc/balloc.h> - -/** - * Builds the initial part of command line for calling a program via stdbuf - * with standard output buffering set to line-buffered. - * - * @param out {@link CmdLine} to append the result to. Note than on failure, only - * some part of the cmdline may have been appended. - * @param stdbuf_exec full path to stdbuf executable - * @param exec path to the executable. Must not contain nulls. - * @param exec_len number of characters in exec - * @return 1 on success, 0 on failure - */ -static int build_stdbuf_cmdline (CmdLine *out, const char *stdbuf_exec, const char *exec, size_t exec_len) WARN_UNUSED; - -int build_stdbuf_cmdline (CmdLine *out, const char *stdbuf_exec, const char *exec, size_t exec_len) -{ - ASSERT(!memchr(exec, '\0', exec_len)) - - if (!CmdLine_AppendMulti(out, 3, stdbuf_exec, "-o", "L")) { - goto fail1; - } - - if (exec[0] == '/') { - if (!CmdLine_AppendNoNull(out, exec, exec_len)) { - goto fail1; - } - } else { - bsize_t size = bsize_add(bsize_fromsize(exec_len), bsize_fromsize(3)); - char *real_exec = BAllocSize(size); - if (!real_exec) { - goto fail1; - } - - memcpy(real_exec, "./", 2); - memcpy(real_exec + 2, exec, exec_len); - real_exec[2 + exec_len] = '\0'; - - int res = CmdLine_Append(out, real_exec); - free(real_exec); - if (!res) { - goto fail1; - } - } - - return 1; - -fail1: - return 0; -} - -#endif diff --git a/external/badvpn_dns/misc/strdup.h b/external/badvpn_dns/misc/strdup.h deleted file mode 100644 index 2e475bb..0000000 --- a/external/badvpn_dns/misc/strdup.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file strdup.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Allocate memory for a string and copy it there. - */ - -#ifndef BADVPN_STRDUP_H -#define BADVPN_STRDUP_H - -#include <string.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/debug.h> - -/** - * Allocate and copy a null-terminated string. - */ -static char * b_strdup (const char *str) -{ - ASSERT(str) - - size_t len = strlen(str); - - char *s = (char *)malloc(len + 1); - if (!s) { - return NULL; - } - - memcpy(s, str, len + 1); - - return s; -} - -/** - * Allocate memory for a null-terminated string and use the - * given data as its contents. A null terminator is appended - * after the specified data. - */ -static char * b_strdup_bin (const char *str, size_t len) -{ - ASSERT(str) - - if (len == SIZE_MAX) { - return NULL; - } - - char *s = (char *)malloc(len + 1); - if (!s) { - return NULL; - } - - memcpy(s, str, len); - s[len] = '\0'; - - return s; -} - -#endif diff --git a/external/badvpn_dns/misc/string_begins_with.h b/external/badvpn_dns/misc/string_begins_with.h deleted file mode 100644 index 3c9c5e9..0000000 --- a/external/badvpn_dns/misc/string_begins_with.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file string_begins_with.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Function for checking if a string begins with a given string. - */ - -#ifndef BADVPN_MISC_STRING_BEGINS_WITH -#define BADVPN_MISC_STRING_BEGINS_WITH - -#include <stddef.h> -#include <string.h> - -#include <misc/debug.h> - -static size_t data_begins_with (const char *str, size_t str_len, const char *needle) -{ - ASSERT(strlen(needle) > 0) - - size_t len = 0; - - while (str_len > 0 && *needle) { - if (*str != *needle) { - return 0; - } - str++; - str_len--; - needle++; - len++; - } - - if (*needle) { - return 0; - } - - return len; -} - -static size_t string_begins_with (const char *str, const char *needle) -{ - ASSERT(strlen(needle) > 0) - - return data_begins_with(str, strlen(str), needle); -} - -static size_t data_begins_with_bin (const char *str, size_t str_len, const char *needle, size_t needle_len) -{ - ASSERT(needle_len > 0) - - size_t len = 0; - - while (str_len > 0 && needle_len > 0) { - if (*str != *needle) { - return 0; - } - str++; - str_len--; - needle++; - needle_len--; - len++; - } - - if (needle_len > 0) { - return 0; - } - - return len; -} - -#endif diff --git a/external/badvpn_dns/misc/substring.h b/external/badvpn_dns/misc/substring.h deleted file mode 100644 index b3a8fff..0000000 --- a/external/badvpn_dns/misc/substring.h +++ /dev/null @@ -1,81 +0,0 @@ -#include <stddef.h> - -#include <misc/debug.h> - -static void build_substring_backtrack_table (const char *str, size_t len, size_t *out_table) -{ - ASSERT(len > 0) - - size_t x = 0; - - for (size_t i = 1; i < len; i++) { - out_table[i] = x; - while (x > 0 && str[i] != str[x]) { - x = out_table[x]; - } - if (str[i] == str[x]) { - x++; - } - } -} - -static int find_substring (const char *text, size_t text_len, const char *word, size_t word_len, const size_t *table, size_t *out_position) -{ - ASSERT(word_len > 0) - - size_t x = 0; - - for (size_t i = 0; i < text_len; i++) { - while (x > 0 && text[i] != word[x]) { - x = table[x]; - } - if (text[i] == word[x]) { - if (x + 1 == word_len) { - *out_position = i - x; - return 1; - } - x++; - } - } - - return 0; -} - -static void build_substring_backtrack_table_reverse (const char *str, size_t len, size_t *out_table) -{ - ASSERT(len > 0) - - size_t x = 0; - - for (size_t i = 1; i < len; i++) { - out_table[i] = x; - while (x > 0 && str[len - 1 - i] != str[len - 1 - x]) { - x = out_table[x]; - } - if (str[len - 1 - i] == str[len - 1 - x]) { - x++; - } - } -} - -static int find_substring_reverse (const char *text, size_t text_len, const char *word, size_t word_len, const size_t *table, size_t *out_position) -{ - ASSERT(word_len > 0) - - size_t x = 0; - - for (size_t i = 0; i < text_len; i++) { - while (x > 0 && text[text_len - 1 - i] != word[word_len - 1 - x]) { - x = table[x]; - } - if (text[text_len - 1 - i] == word[word_len - 1 - x]) { - if (x + 1 == word_len) { - *out_position = (text_len - 1 - i); - return 1; - } - x++; - } - } - - return 0; -} diff --git a/external/badvpn_dns/misc/udp_proto.h b/external/badvpn_dns/misc/udp_proto.h deleted file mode 100644 index 23ec69a..0000000 --- a/external/badvpn_dns/misc/udp_proto.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file udp_proto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for the UDP protocol. - */ - -#ifndef BADVPN_MISC_UDP_PROTO_H -#define BADVPN_MISC_UDP_PROTO_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <misc/ipv4_proto.h> -#include <misc/ipv6_proto.h> -#include <misc/read_write_int.h> - -B_START_PACKED -struct udp_header { - uint16_t source_port; - uint16_t dest_port; - uint16_t length; - uint16_t checksum; -} B_PACKED; -B_END_PACKED - -static uint32_t udp_checksum_summer (const char *data, uint16_t len) -{ - ASSERT(len % 2 == 0) - - uint32_t t = 0; - - for (uint16_t i = 0; i < len / 2; i++) { - t += badvpn_read_be16(data + 2 * i); - } - - return t; -} - -static uint16_t udp_checksum (const struct udp_header *header, const uint8_t *payload, uint16_t payload_len, uint32_t source_addr, uint32_t dest_addr) -{ - uint32_t t = 0; - - t += udp_checksum_summer((char *)&source_addr, sizeof(source_addr)); - t += udp_checksum_summer((char *)&dest_addr, sizeof(dest_addr)); - - uint16_t x; - x = hton16(IPV4_PROTOCOL_UDP); - t += udp_checksum_summer((char *)&x, sizeof(x)); - x = hton16(sizeof(*header) + payload_len); - t += udp_checksum_summer((char *)&x, sizeof(x)); - - t += udp_checksum_summer((const char *)header, sizeof(*header)); - - if (payload_len % 2 == 0) { - t += udp_checksum_summer((const char *)payload, payload_len); - } else { - t += udp_checksum_summer((const char *)payload, payload_len - 1); - - x = hton16(((uint16_t)payload[payload_len - 1]) << 8); - t += udp_checksum_summer((char *)&x, sizeof(x)); - } - - while (t >> 16) { - t = (t & 0xFFFF) + (t >> 16); - } - - if (t == 0) { - t = UINT16_MAX; - } - - return hton16(~t); -} - -static uint16_t udp_ip6_checksum (const struct udp_header *header, const uint8_t *payload, uint16_t payload_len, const uint8_t *source_addr, const uint8_t *dest_addr) -{ - uint32_t t = 0; - - t += udp_checksum_summer((const char *)source_addr, 16); - t += udp_checksum_summer((const char *)dest_addr, 16); - - uint32_t x; - x = hton32(sizeof(*header) + payload_len); - t += udp_checksum_summer((char *)&x, sizeof(x)); - x = hton32(IPV6_NEXT_UDP); - t += udp_checksum_summer((char *)&x, sizeof(x)); - - t += udp_checksum_summer((const char *)header, sizeof(*header)); - - if (payload_len % 2 == 0) { - t += udp_checksum_summer((const char *)payload, payload_len); - } else { - t += udp_checksum_summer((const char *)payload, payload_len - 1); - - uint16_t y; - y = hton16(((uint16_t)payload[payload_len - 1]) << 8); - t += udp_checksum_summer((char *)&y, sizeof(y)); - } - - while (t >> 16) { - t = (t & 0xFFFF) + (t >> 16); - } - - if (t == 0) { - t = UINT16_MAX; - } - - return hton16(~t); -} - -static int udp_check (const uint8_t *data, int data_len, struct udp_header *out_header, uint8_t **out_payload, int *out_payload_len) -{ - ASSERT(data_len >= 0) - ASSERT(out_header) - ASSERT(out_payload) - ASSERT(out_payload_len) - - // parse UDP header - if (data_len < sizeof(struct udp_header)) { - return 0; - } - memcpy(out_header, data, sizeof(*out_header)); - data += sizeof(*out_header); - data_len -= sizeof(*out_header); - - // verify UDP payload - int udp_length = ntoh16(out_header->length); - if (udp_length < sizeof(*out_header)) { - return 0; - } - if (udp_length > sizeof(*out_header) + data_len) { - return 0; - } - - // ignore stray data - data_len = udp_length - sizeof(*out_header); - - *out_payload = (uint8_t *)data; - *out_payload_len = data_len; - return 1; -} - -#endif diff --git a/external/badvpn_dns/misc/unicode_funcs.h b/external/badvpn_dns/misc/unicode_funcs.h deleted file mode 100644 index 2442e7f..0000000 --- a/external/badvpn_dns/misc/unicode_funcs.h +++ /dev/null @@ -1,232 +0,0 @@ -/** - * @file unicode_funcs.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UNICODE_FUNCS_H -#define BADVPN_UNICODE_FUNCS_H - -#include <misc/expstring.h> -#include <misc/bsize.h> -#include <misc/Utf8Encoder.h> -#include <misc/Utf8Decoder.h> -#include <misc/Utf16Encoder.h> -#include <misc/Utf16Decoder.h> - -/** - * Decodes UTF-16 data as bytes into an allocated null-terminated UTF-8 string. - * - * @param data UTF-16 data, in big endian - * @param data_len size of data in bytes - * @param out_is_error if not NULL and the function returns a string, - * *out_is_error will be set to 0 or 1, indicating - * whether there have been errors decoding the input. - * A null decoded character is treated as an error. - * @return An UTF-8 null-terminated string which can be freed with free(), - * or NULL if out of memory. - */ -static char * unicode_decode_utf16_to_utf8 (const uint8_t *data, size_t data_len, int *out_is_error); - -/** - * Decodes UTF-8 data into UTF-16 data as bytes. - * - * @param data UTF-8 data - * @param data_len size of data in bytes - * @param out output buffer - * @param out_avail number of bytes available in output buffer - * @param out_len if not NULL, *out_len will contain the number of bytes - * required to store the resulting data (or overflow) - * @param out_is_error if not NULL, *out_is_error will contain 0 or 1, - * indicating whether there have been errors decoding - * the input - */ -static void unicode_decode_utf8_to_utf16 (const uint8_t *data, size_t data_len, uint8_t *out, size_t out_avail, bsize_t *out_len, int *out_is_error); - -static char * unicode_decode_utf16_to_utf8 (const uint8_t *data, size_t data_len, int *out_is_error) -{ - // will build the resulting UTF-8 string by appending to ExpString - ExpString str; - if (!ExpString_Init(&str)) { - goto fail0; - } - - // init UTF-16 decoder - Utf16Decoder decoder; - Utf16Decoder_Init(&decoder); - - // set initial input and input matching positions - size_t i_in = 0; - size_t i_ch = 0; - - int error = 0; - - while (i_in < data_len) { - // read two input bytes from the input position - uint8_t x = data[i_in++]; - if (i_in == data_len) { - break; - } - uint8_t y = data[i_in++]; - - // combine them into a 16-bit value - uint16_t xy = (((uint16_t)x << 8) | (uint16_t)y); - - // give the 16-bit value to the UTF-16 decoder and maybe - // receive a Unicode character back - uint32_t ch; - if (!Utf16Decoder_Input(&decoder, xy, &ch)) { - continue; - } - - if (!error) { - // encode the Unicode character back into UTF-16 - uint16_t chenc[2]; - int chenc_n = Utf16Encoder_EncodeCharacter(ch, chenc); - ASSERT(chenc_n > 0) - - // match the result with input - for (int chenc_i = 0; chenc_i < chenc_n; chenc_i++) { - uint8_t cx = (chenc[chenc_i] >> 8); - uint8_t cy = (chenc[chenc_i] & 0xFF); - - if (i_ch >= data_len || data[i_ch] != cx) { - error = 1; - break; - } - i_ch++; - - if (i_ch >= data_len || data[i_ch] != cy) { - error = 1; - break; - } - i_ch++; - } - } - - // we don't like null Unicode characters because we're building a - // null-terminated UTF-8 string - if (ch == 0) { - error = 1; - continue; - } - - // encode the Unicode character into UTF-8 - uint8_t enc[5]; - int enc_n = Utf8Encoder_EncodeCharacter(ch, enc); - ASSERT(enc_n > 0) - - // append the resulting UTF-8 bytes to the result string - enc[enc_n] = 0; - if (!ExpString_Append(&str, enc)) { - goto fail1; - } - } - - // check if we matched the whole input string when encoding back - if (i_ch < data_len) { - error = 1; - } - - if (out_is_error) { - *out_is_error = error; - } - return ExpString_Get(&str); - -fail1: - ExpString_Free(&str); -fail0: - return NULL; -} - -static void unicode_decode_utf8_to_utf16 (const uint8_t *data, size_t data_len, uint8_t *out, size_t out_avail, bsize_t *out_len, int *out_is_error) -{ - Utf8Decoder decoder; - Utf8Decoder_Init(&decoder); - - size_t i_in = 0; - size_t i_ch = 0; - - bsize_t len = bsize_fromsize(0); - - int error = 0; - - while (i_in < data_len) { - uint8_t x = data[i_in++]; - - uint32_t ch; - if (!Utf8Decoder_Input(&decoder, x, &ch)) { - continue; - } - - if (!error) { - uint8_t chenc[4]; - int chenc_n = Utf8Encoder_EncodeCharacter(ch, chenc); - ASSERT(chenc_n > 0) - - for (int chenc_i = 0; chenc_i < chenc_n; chenc_i++) { - if (i_ch >= data_len || data[i_ch] != chenc[chenc_i]) { - error = 1; - break; - } - i_ch++; - } - } - - uint16_t enc[2]; - int enc_n = Utf16Encoder_EncodeCharacter(ch, enc); - ASSERT(enc_n > 0) - - len = bsize_add(len, bsize_fromsize(2 * enc_n)); - - for (int enc_i = 0; enc_i < enc_n; enc_i++) { - if (out_avail == 0) { - break; - } - *(out++) = (enc[enc_i] >> 8); - out_avail--; - - if (out_avail == 0) { - break; - } - *(out++) = (enc[enc_i] & 0xFF); - out_avail--; - } - } - - if (i_ch < data_len) { - error = 1; - } - - if (out_len) { - *out_len = len; - } - if (out_is_error) { - *out_is_error = error; - } -} - -#endif diff --git a/external/badvpn_dns/misc/version.h b/external/badvpn_dns/misc/version.h deleted file mode 100644 index a90523f..0000000 --- a/external/badvpn_dns/misc/version.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file version.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Product information definitions. - */ - -#ifndef BADVPN_MISC_VERSION_H -#define BADVPN_MISC_VERSION_H - -#define GLOBAL_PRODUCT_NAME "BadVPN" -#define GLOBAL_VERSION "1.999.129" -#define GLOBAL_COPYRIGHT_NOTICE "Copyright (C) 2010 Ambroz Bizjak ambrop7@gmail.com" - -#endif diff --git a/external/badvpn_dns/misc/write_file.h b/external/badvpn_dns/misc/write_file.h deleted file mode 100644 index 97b1c19..0000000 --- a/external/badvpn_dns/misc/write_file.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file write_file.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_WRITE_FILE_H -#define BADVPN_WRITE_FILE_H - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <misc/cstring.h> - -static int write_file (const char *file, const uint8_t *data, size_t len) -{ - FILE *f = fopen(file, "w"); - if (!f) { - goto fail0; - } - - while (len > 0) { - size_t res = fwrite(data, 1, len, f); - if (res == 0) { - goto fail1; - } - - ASSERT(res <= len) - - data += res; - len -= res; - } - - if (fclose(f) != 0) { - return 0; - } - - return 1; - -fail1: - fclose(f); -fail0: - return 0; -} - -static int write_file_cstring (const char *file, b_cstring cstr, size_t offset, size_t length) -{ - b_cstring_assert_range(cstr, offset, length); - - FILE *f = fopen(file, "w"); - if (!f) { - goto fail0; - } - - B_CSTRING_LOOP_RANGE(cstr, offset, length, pos, chunk_data, chunk_length, { - size_t chunk_pos = 0; - while (chunk_pos < chunk_length) { - size_t res = fwrite(chunk_data + chunk_pos, 1, chunk_length - chunk_pos, f); - if (res == 0) { - goto fail1; - } - ASSERT(res <= chunk_length - chunk_pos) - chunk_pos += res; - } - }) - - if (fclose(f) != 0) { - return 0; - } - - return 1; - -fail1: - fclose(f); -fail0: - return 0; -} - -#endif diff --git a/external/badvpn_dns/ncd-request/CMakeLists.txt b/external/badvpn_dns/ncd-request/CMakeLists.txt deleted file mode 100644 index 61447fd..0000000 --- a/external/badvpn_dns/ncd-request/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_executable(badvpn-ncd-request - ncd-request.c -) -target_link_libraries(badvpn-ncd-request ncdrequest ncdvalgenerator ncdvalparser) - -install( - TARGETS badvpn-ncd-request - RUNTIME DESTINATION bin -) diff --git a/external/badvpn_dns/ncd-request/ncd-request.c b/external/badvpn_dns/ncd-request/ncd-request.c deleted file mode 100644 index 5b44bdb..0000000 --- a/external/badvpn_dns/ncd-request/ncd-request.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file ncd-request.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include <misc/string_begins_with.h> -#include <base/BLog.h> -#include <base/DebugObject.h> -#include <system/BNetwork.h> -#include <system/BReactor.h> -#include <system/BAddr.h> -#include <ncd/NCDValParser.h> -#include <ncd/NCDValGenerator.h> -#include <ncd/extra/NCDRequestClient.h> - -#include <generated/blog_channel_ncd_request.h> - -static void client_handler_error (void *user); -static void client_handler_connected (void *user); -static void request_handler_sent (void *user); -static void request_handler_reply (void *user, NCDValMem reply_mem, NCDValRef reply_value); -static void request_handler_finished (void *user, int is_error); -static int write_all (int fd, const uint8_t *data, size_t len); -static int make_connect_addr (const char *str, struct BConnection_addr *out_addr); - -NCDValMem request_mem; -NCDValRef request_value; -BReactor reactor; -NCDRequestClient client; -NCDRequestClientRequest request; -int have_request; - -int main (int argc, char *argv[]) -{ - int res = 1; - - if (argc != 3) { - fprintf(stderr, "Usage: %s < unix:<socket_path> / tcp:<address>:<port> > <request_payload>\n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - char *connect_address = argv[1]; - char *request_payload_string = argv[2]; - - BLog_InitStderr(); - - BTime_Init(); - - NCDValMem_Init(&request_mem); - - if (!NCDValParser_Parse(request_payload_string, strlen(request_payload_string), &request_mem, &request_value)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_Init failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - struct BConnection_addr addr; - if (!make_connect_addr(connect_address, &addr)) { - goto fail2; - } - - if (!NCDRequestClient_Init(&client, addr, &reactor, NULL, client_handler_error, client_handler_connected)) { - BLog(BLOG_ERROR, "NCDRequestClient_Init failed"); - goto fail2; - } - - have_request = 0; - - res = BReactor_Exec(&reactor); - - if (have_request) { - NCDRequestClientRequest_Free(&request); - } - NCDRequestClient_Free(&client); -fail2: - BReactor_Free(&reactor); -fail1: - NCDValMem_Free(&request_mem); - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - return res; -} - -static int make_connect_addr (const char *str, struct BConnection_addr *out_addr) -{ - size_t i; - - if (i = string_begins_with(str, "unix:")) { - *out_addr = BConnection_addr_unix(str + i, strlen(str + i)); - } - else if (i = string_begins_with(str, "tcp:")) { - BAddr baddr; - if (!BAddr_Parse2(&baddr, (char *)str + i, NULL, 0, 1)) { - BLog(BLOG_ERROR, "failed to parse tcp address"); - return 0; - } - - *out_addr = BConnection_addr_baddr(baddr); - } - else { - BLog(BLOG_ERROR, "address must start with unix: or tcp:"); - return 0; - } - - return 1; -} - -static void client_handler_error (void *user) -{ - BLog(BLOG_ERROR, "client error"); - - BReactor_Quit(&reactor, 1); -} - -static void client_handler_connected (void *user) -{ - ASSERT(!have_request) - - if (!NCDRequestClientRequest_Init(&request, &client, request_value, NULL, request_handler_sent, request_handler_reply, request_handler_finished)) { - BLog(BLOG_ERROR, "NCDRequestClientRequest_Init failed"); - BReactor_Quit(&reactor, 1); - return; - } - - have_request = 1; -} - -static void request_handler_sent (void *user) -{ - ASSERT(have_request) -} - -static void request_handler_reply (void *user, NCDValMem reply_mem, NCDValRef reply_value) -{ - ASSERT(have_request) - - char *str = NCDValGenerator_Generate(reply_value); - if (!str) { - BLog(BLOG_ERROR, "NCDValGenerator_Generate failed"); - goto fail0; - } - - if (!write_all(1, (uint8_t *)str, strlen(str))) { - goto fail1; - } - if (!write_all(1, (const uint8_t *)"\n", 1)) { - goto fail1; - } - - free(str); - NCDValMem_Free(&reply_mem); - return; - -fail1: - free(str); -fail0: - NCDValMem_Free(&reply_mem); - BReactor_Quit(&reactor, 1); -} - -static void request_handler_finished (void *user, int is_error) -{ - if (is_error) { - BLog(BLOG_ERROR, "request error"); - BReactor_Quit(&reactor, 1); - return; - } - - BReactor_Quit(&reactor, 0); -} - -static int write_all (int fd, const uint8_t *data, size_t len) -{ - while (len > 0) { - ssize_t res = write(fd, data, len); - if (res <= 0) { - BLog(BLOG_ERROR, "write failed"); - return 0; - } - data += res; - len -= res; - } - - return 1; -} diff --git a/external/badvpn_dns/ncd/CMakeLists.txt b/external/badvpn_dns/ncd/CMakeLists.txt deleted file mode 100644 index 8c384ae..0000000 --- a/external/badvpn_dns/ncd/CMakeLists.txt +++ /dev/null @@ -1,211 +0,0 @@ -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(NCD_ADDITIONAL_SOURCES) -set(NCD_ADDITIONAL_LIBS) - -if (NOT EMSCRIPTEN) - if (BADVPN_USE_LINUX_RFKILL) - list(APPEND NCD_ADDITIONAL_SOURCES - extra/NCDRfkillMonitor.c - modules/net_backend_rfkill.c - ) - endif () - - if (BADVPN_USE_LINUX_INPUT) - list(APPEND NCD_ADDITIONAL_SOURCES - modules/sys_evdev.c - ) - endif () - - if (BADVPN_USE_INOTIFY) - list(APPEND NCD_ADDITIONAL_SOURCES - modules/sys_watch_directory.c - ) - endif () - - badvpn_add_library(ncdinterfacemonitor "base;system" "" extra/NCDInterfaceMonitor.c) - - badvpn_add_library(ncdrequest "base;system;ncdvalgenerator;ncdvalparser" "" extra/NCDRequestClient.c) - - list(APPEND NCD_ADDITIONAL_SOURCES - extra/NCDIfConfig.c - extra/build_cmdline.c - extra/NCDBProcessOpts.c - modules/command_template.c - modules/event_template.c - modules/regex_match.c - modules/run.c - modules/runonce.c - modules/daemon.c - modules/net_backend_waitdevice.c - modules/net_backend_waitlink.c - modules/net_backend_badvpn.c - modules/net_backend_wpa_supplicant.c - modules/net_up.c - modules/net_dns.c - modules/net_iptables.c - modules/net_ipv4_addr.c - modules/net_ipv4_route.c - modules/net_ipv4_dhcp.c - modules/net_ipv4_arp_probe.c - modules/net_watch_interfaces.c - modules/sys_watch_input.c - modules/sys_watch_usb.c - modules/sys_request_server.c - modules/net_ipv6_wait_dynamic_addr.c - modules/sys_request_client.c - modules/reboot.c - modules/net_ipv6_addr.c - modules/net_ipv6_route.c - modules/socket.c - modules/sys_start_process.c - modules/load_module.c - ) - - list(APPEND NCD_ADDITIONAL_LIBS - dhcpclient arpprobe ncdinterfacemonitor ncdrequest udevmonitor badvpn_random dl - ) -endif () - -badvpn_add_library(ncdtokenizer "base" "" NCDConfigTokenizer.c) - -badvpn_add_library(ncdstringindex "base" "" NCDStringIndex.c) - -badvpn_add_library(ncdval "base;ncdstringindex" "" NCDVal.c) - -badvpn_add_library(ncdvalgenerator "base;ncdval" "" NCDValGenerator.c) - -badvpn_add_library(ncdvalparser "base;ncdval;ncdtokenizer;ncdvalcons" "" NCDValParser.c) - -badvpn_add_library(ncdast "" "" NCDAst.c) - -badvpn_add_library(ncdconfigparser "base;ncdtokenizer;ncdast" "" NCDConfigParser.c) - -badvpn_add_library(ncdsugar "ncdast" "" NCDSugar.c) - -badvpn_add_library(ncdvalcons "ncdval" "" NCDValCons.c) - -badvpn_add_library(ncdbuildprogram "base;ncdast;ncdconfigparser" "" NCDBuildProgram.c) - -badvpn_add_library(ncdobject "" "" NCDObject.c) - -badvpn_add_library(ncdmodule "base;ncdobject;ncdstringindex;ncdval" "" NCDModule.c) - -set(NCDINTERPRETER_SOURCES - NCDInterpreter.c - NCDModuleIndex.c - NCDInterpProcess.c - NCDInterpProg.c - NCDPlaceholderDb.c - NCDMethodIndex.c - extra/BEventLock.c - extra/NCDBuf.c - modules/var.c - modules/list.c - modules/depend.c - modules/multidepend.c - modules/dynamic_depend.c - modules/concat.c - modules/if.c - modules/strcmp.c - modules/logical.c - modules/sleep.c - modules/print.c - modules/blocker.c - modules/spawn.c - modules/imperative.c - modules/ref.c - modules/index.c - modules/alias.c - modules/process_manager.c - modules/ondemand.c - modules/foreach.c - modules/choose.c - modules/from_string.c - modules/to_string.c - modules/value.c - modules/try.c - modules/exit.c - modules/getargs.c - modules/arithmetic.c - modules/parse.c - modules/valuemetic.c - modules/file.c - modules/netmask.c - modules/implode.c - modules/call2.c - modules/assert.c - modules/explode.c - modules/net_ipv4_addr_in_network.c - modules/net_ipv6_addr_in_network.c - modules/timer.c - modules/file_open.c - modules/backtrack.c - modules/depend_scope.c - modules/substr.c - modules/log.c - modules/buffer.c - modules/getenv.c - ${NCD_ADDITIONAL_SOURCES} -) -set(NCDINTERPRETER_LIBS - base system flow flowextra ncdval ncdstringindex ncdvalgenerator ncdvalparser - ncdconfigparser ncdsugar ncdobject ncdmodule ${NCD_ADDITIONAL_LIBS}) -badvpn_add_library(ncdinterpreter "${NCDINTERPRETER_LIBS}" "" "${NCDINTERPRETER_SOURCES}") - -if (BADVPN_USE_LINUX_INPUT) - string(REPLACE " " ";" FLAGS_LIST "${CMAKE_C_FLAGS}") - execute_process(COMMAND ${CMAKE_C_COMPILER} ${FLAGS_LIST} -E ${CMAKE_CURRENT_SOURCE_DIR}/include_linux_input.c - RESULT_VARIABLE LINUX_INPUT_PREPROCESS_RESULT - OUTPUT_VARIABLE LINUX_INPUT_PREPROCESS_OUTPUT) - if (NOT LINUX_INPUT_PREPROCESS_RESULT EQUAL 0) - message(FATAL_ERROR "failed to preprocess linux/input.h include") - endif () - - string(REGEX MATCH ""(/[^"]+/linux/input.h)"" LINUX_INPUT_MATCH ${LINUX_INPUT_PREPROCESS_OUTPUT}) - if (NOT LINUX_INPUT_MATCH) - message(FATAL_ERROR "failed to match preprocessor output for path of linux/input.h") - endif () - set(LINUX_INPUT_H_PATH ${CMAKE_MATCH_1}) - - message(STATUS "Generating linux_input_names.h from ${LINUX_INPUT_H_PATH}") - - execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/parse_linux_input.sh - ${LINUX_INPUT_H_PATH} - ${CMAKE_CURRENT_BINARY_DIR}/linux_input_names.h - RESULT_VARIABLE LINUX_INPUT_PARSE_RESULT) - if (NOT LINUX_INPUT_PARSE_RESULT EQUAL 0) - message(FATAL_ERROR "failed to generate linux_input_names.h") - endif () -endif () - -if (NOT EMSCRIPTEN) - add_executable(badvpn-ncd ncd.c) - target_link_libraries(badvpn-ncd ncdinterpreter ncdbuildprogram) - - install( - TARGETS badvpn-ncd - RUNTIME DESTINATION bin - ) -endif () - -if (EMSCRIPTEN) - add_executable(emncd emncd.c) - target_link_libraries(emncd ncdinterpreter) - - add_custom_command( - OUTPUT emncd.bc - DEPENDS emncd - COMMAND cp emncd emncd.bc - ) - - add_custom_command( - OUTPUT emncd.js - DEPENDS emncd.bc - COMMAND - ${CMAKE_C_COMPILER} emncd.bc -o emncd.js -O2 - -s EXPORTED_FUNCTIONS="['_breactor_timer_cb','_main','_emncd_start','_emncd_stop']" - ) - - add_custom_target(emncd_js ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/emncd.js) -endif () diff --git a/external/badvpn_dns/ncd/NCDAst.c b/external/badvpn_dns/ncd/NCDAst.c deleted file mode 100644 index 2b229e3..0000000 --- a/external/badvpn_dns/ncd/NCDAst.c +++ /dev/null @@ -1,1022 +0,0 @@ -/** - * @file NCDAst.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <limits.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/strdup.h> - -#include "NCDAst.h" - -struct NCDValue__list_element { - LinkedList1Node list_node; - NCDValue v; -}; - -struct NCDValue__map_element { - LinkedList1Node list_node; - NCDValue key; - NCDValue val; -}; - -struct ProgramElem { - LinkedList1Node elems_list_node; - NCDProgramElem elem; -}; - -struct BlockStatement { - LinkedList1Node statements_list_node; - NCDStatement s; -}; - -struct IfBlockIf { - LinkedList1Node ifs_list_node; - NCDIf ifc; -}; - -static void value_assert (NCDValue *o) -{ - switch (o->type) { - case NCDVALUE_STRING: - case NCDVALUE_LIST: - case NCDVALUE_MAP: - case NCDVALUE_VAR: - return; - default: - ASSERT(0); - } -} - -void NCDValue_Free (NCDValue *o) -{ - switch (o->type) { - case NCDVALUE_STRING: { - free(o->string); - } break; - - case NCDVALUE_LIST: { - LinkedList1Node *n; - while (n = LinkedList1_GetFirst(&o->list)) { - struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node); - - NCDValue_Free(&e->v); - LinkedList1_Remove(&o->list, &e->list_node); - free(e); - } - } break; - - case NCDVALUE_MAP: { - LinkedList1Node *n; - while (n = LinkedList1_GetFirst(&o->map_list)) { - struct NCDValue__map_element *e = UPPER_OBJECT(n, struct NCDValue__map_element, list_node); - - LinkedList1_Remove(&o->map_list, &e->list_node); - NCDValue_Free(&e->key); - NCDValue_Free(&e->val); - free(e); - } - } break; - - case NCDVALUE_VAR: { - free(o->var_name); - } break; - - default: - ASSERT(0); - } -} - -int NCDValue_Type (NCDValue *o) -{ - value_assert(o); - - return o->type; -} - -int NCDValue_InitString (NCDValue *o, const char *str) -{ - return NCDValue_InitStringBin(o, (const uint8_t *)str, strlen(str)); -} - -int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len) -{ - if (len == SIZE_MAX) { - return 0; - } - - if (!(o->string = malloc(len + 1))) { - return 0; - } - - memcpy(o->string, str, len); - o->string[len] = '\0'; - o->string_len = len; - - o->type = NCDVALUE_STRING; - - return 1; -} - -const char * NCDValue_StringValue (NCDValue *o) -{ - ASSERT(o->type == NCDVALUE_STRING) - - return (char *)o->string; -} - -size_t NCDValue_StringLength (NCDValue *o) -{ - ASSERT(o->type == NCDVALUE_STRING) - - return o->string_len; -} - -void NCDValue_InitList (NCDValue *o) -{ - o->type = NCDVALUE_LIST; - LinkedList1_Init(&o->list); - o->list_count = 0; -} - -size_t NCDValue_ListCount (NCDValue *o) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_LIST) - - return o->list_count; -} - -int NCDValue_ListAppend (NCDValue *o, NCDValue v) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_LIST) - value_assert(&v); - - if (o->list_count == SIZE_MAX) { - return 0; - } - - struct NCDValue__list_element *e = malloc(sizeof(*e)); - if (!e) { - return 0; - } - - e->v = v; - LinkedList1_Append(&o->list, &e->list_node); - - o->list_count++; - - return 1; -} - -int NCDValue_ListPrepend (NCDValue *o, NCDValue v) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_LIST) - value_assert(&v); - - if (o->list_count == SIZE_MAX) { - return 0; - } - - struct NCDValue__list_element *e = malloc(sizeof(*e)); - if (!e) { - return 0; - } - - e->v = v; - LinkedList1_Prepend(&o->list, &e->list_node); - - o->list_count++; - - return 1; -} - -NCDValue * NCDValue_ListFirst (NCDValue *o) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_LIST) - - LinkedList1Node *ln = LinkedList1_GetFirst(&o->list); - - if (!ln) { - return NULL; - } - - struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node); - - return &e->v; -} - -NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_LIST) - - struct NCDValue__list_element *cur_e = UPPER_OBJECT(ev, struct NCDValue__list_element, v); - LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->list_node); - - if (!ln) { - return NULL; - } - - struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node); - - return &e->v; -} - -void NCDValue_InitMap (NCDValue *o) -{ - o->type = NCDVALUE_MAP; - LinkedList1_Init(&o->map_list); - o->map_count = 0; -} - -size_t NCDValue_MapCount (NCDValue *o) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_MAP) - - return o->map_count; -} - -int NCDValue_MapPrepend (NCDValue *o, NCDValue key, NCDValue val) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_MAP) - value_assert(&key); - value_assert(&val); - - if (o->map_count == SIZE_MAX) { - return 0; - } - - struct NCDValue__map_element *e = malloc(sizeof(*e)); - if (!e) { - return 0; - } - - e->key = key; - e->val = val; - LinkedList1_Prepend(&o->map_list, &e->list_node); - - o->map_count++; - - return 1; -} - -NCDValue * NCDValue_MapFirstKey (NCDValue *o) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_MAP) - - LinkedList1Node *ln = LinkedList1_GetFirst(&o->map_list); - - if (!ln) { - return NULL; - } - - struct NCDValue__map_element *e = UPPER_OBJECT(ln, struct NCDValue__map_element, list_node); - - value_assert(&e->key); - value_assert(&e->val); - - return &e->key; -} - -NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_MAP) - - struct NCDValue__map_element *e0 = UPPER_OBJECT(ekey, struct NCDValue__map_element, key); - value_assert(&e0->key); - value_assert(&e0->val); - - LinkedList1Node *ln = LinkedList1Node_Next(&e0->list_node); - - if (!ln) { - return NULL; - } - - struct NCDValue__map_element *e = UPPER_OBJECT(ln, struct NCDValue__map_element, list_node); - - value_assert(&e->key); - value_assert(&e->val); - - return &e->key; -} - -NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_MAP) - - struct NCDValue__map_element *e = UPPER_OBJECT(ekey, struct NCDValue__map_element, key); - value_assert(&e->key); - value_assert(&e->val); - - return &e->val; -} - -int NCDValue_InitVar (NCDValue *o, const char *var_name) -{ - ASSERT(var_name) - - if (!(o->var_name = strdup(var_name))) { - return 0; - } - - o->type = NCDVALUE_VAR; - - return 1; -} - -const char * NCDValue_VarName (NCDValue *o) -{ - value_assert(o); - ASSERT(o->type == NCDVALUE_VAR) - - return o->var_name; -} - -void NCDProgram_Init (NCDProgram *o) -{ - LinkedList1_Init(&o->elems_list); - o->num_elems = 0; -} - -void NCDProgram_Free (NCDProgram *o) -{ - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->elems_list)) { - struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); - NCDProgramElem_Free(&e->elem); - LinkedList1_Remove(&o->elems_list, &e->elems_list_node); - free(e); - } -} - -NCDProgramElem * NCDProgram_PrependElem (NCDProgram *o, NCDProgramElem elem) -{ - if (o->num_elems == SIZE_MAX) { - return NULL; - } - - struct ProgramElem *e = malloc(sizeof(*e)); - if (!e) { - return NULL; - } - - LinkedList1_Prepend(&o->elems_list, &e->elems_list_node); - e->elem = elem; - - o->num_elems++; - - return &e->elem; -} - -NCDProgramElem * NCDProgram_FirstElem (NCDProgram *o) -{ - LinkedList1Node *ln = LinkedList1_GetFirst(&o->elems_list); - if (!ln) { - return NULL; - } - - struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); - - return &e->elem; -} - -NCDProgramElem * NCDProgram_NextElem (NCDProgram *o, NCDProgramElem *ee) -{ - ASSERT(ee) - - struct ProgramElem *cur_e = UPPER_OBJECT(ee, struct ProgramElem, elem); - - LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->elems_list_node); - if (!ln) { - return NULL; - } - - struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); - - return &e->elem; -} - -size_t NCDProgram_NumElems (NCDProgram *o) -{ - return o->num_elems; -} - -int NCDProgram_ContainsElemType (NCDProgram *o, int elem_type) -{ - for (NCDProgramElem *elem = NCDProgram_FirstElem(o); elem; elem = NCDProgram_NextElem(o, elem)) { - if (NCDProgramElem_Type(elem) == elem_type) { - return 1; - } - } - - return 0; -} - -void NCDProgram_RemoveElem (NCDProgram *o, NCDProgramElem *ee) -{ - ASSERT(ee) - - struct ProgramElem *e = UPPER_OBJECT(ee, struct ProgramElem, elem); - NCDProgramElem_Free(&e->elem); - LinkedList1_Remove(&o->elems_list, &e->elems_list_node); - free(e); - - ASSERT(o->num_elems > 0) - o->num_elems--; -} - -int NCDProgram_ReplaceElemWithProgram (NCDProgram *o, NCDProgramElem *ee, NCDProgram replace_prog) -{ - ASSERT(ee) - - if (replace_prog.num_elems > SIZE_MAX - o->num_elems) { - return 0; - } - - struct ProgramElem *e = UPPER_OBJECT(ee, struct ProgramElem, elem); - - LinkedList1_InsertListAfter(&o->elems_list, replace_prog.elems_list, &e->elems_list_node); - o->num_elems += replace_prog.num_elems; - - NCDProgram_RemoveElem(o, ee); - - return 1; -} - -void NCDProgramElem_InitProcess (NCDProgramElem *o, NCDProcess process) -{ - o->type = NCDPROGRAMELEM_PROCESS; - o->process = process; -} - -int NCDProgramElem_InitInclude (NCDProgramElem *o, const char *path_data, size_t path_length) -{ - if (!(o->include.path_data = b_strdup_bin(path_data, path_length))) { - return 0; - } - - o->type = NCDPROGRAMELEM_INCLUDE; - o->include.path_length = path_length; - - return 1; -} - -int NCDProgramElem_InitIncludeGuard (NCDProgramElem *o, const char *id_data, size_t id_length) -{ - if (!(o->include_guard.id_data = b_strdup_bin(id_data, id_length))) { - return 0; - } - - o->type = NCDPROGRAMELEM_INCLUDE_GUARD; - o->include_guard.id_length = id_length; - - return 1; -} - - -void NCDProgramElem_Free (NCDProgramElem *o) -{ - switch (o->type) { - case NCDPROGRAMELEM_PROCESS: { - NCDProcess_Free(&o->process); - } break; - - case NCDPROGRAMELEM_INCLUDE: { - free(o->include.path_data); - } break; - - case NCDPROGRAMELEM_INCLUDE_GUARD: { - free(o->include_guard.id_data); - } break; - - default: ASSERT(0); - } -} - -int NCDProgramElem_Type (NCDProgramElem *o) -{ - return o->type; -} - -NCDProcess * NCDProgramElem_Process (NCDProgramElem *o) -{ - ASSERT(o->type == NCDPROGRAMELEM_PROCESS) - - return &o->process; -} - -const char * NCDProgramElem_IncludePathData (NCDProgramElem *o) -{ - ASSERT(o->type == NCDPROGRAMELEM_INCLUDE) - - return o->include.path_data; -} - -size_t NCDProgramElem_IncludePathLength (NCDProgramElem *o) -{ - ASSERT(o->type == NCDPROGRAMELEM_INCLUDE) - - return o->include.path_length; -} - -const char * NCDProgramElem_IncludeGuardIdData (NCDProgramElem *o) -{ - ASSERT(o->type == NCDPROGRAMELEM_INCLUDE_GUARD) - - return o->include_guard.id_data; -} - -size_t NCDProgramElem_IncludeGuardIdLength (NCDProgramElem *o) -{ - ASSERT(o->type == NCDPROGRAMELEM_INCLUDE_GUARD) - - return o->include_guard.id_length; -} - -int NCDProcess_Init (NCDProcess *o, int is_template, const char *name, NCDBlock block) -{ - ASSERT(is_template == !!is_template) - ASSERT(name) - - if (!(o->name = strdup(name))) { - return 0; - } - - o->is_template = is_template; - o->block = block; - - return 1; -} - -void NCDProcess_Free (NCDProcess *o) -{ - NCDBlock_Free(&o->block); - free(o->name); -} - -int NCDProcess_IsTemplate (NCDProcess *o) -{ - return o->is_template; -} - -const char * NCDProcess_Name (NCDProcess *o) -{ - return o->name; -} - -NCDBlock * NCDProcess_Block (NCDProcess *o) -{ - return &o->block; -} - -void NCDBlock_Init (NCDBlock *o) -{ - LinkedList1_Init(&o->statements_list); - o->count = 0; -} - -void NCDBlock_Free (NCDBlock *o) -{ - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->statements_list)) { - struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); - NCDStatement_Free(&e->s); - LinkedList1_Remove(&o->statements_list, &e->statements_list_node); - free(e); - } -} - -int NCDBlock_PrependStatement (NCDBlock *o, NCDStatement s) -{ - return NCDBlock_InsertStatementAfter(o, NULL, s); -} - -int NCDBlock_InsertStatementAfter (NCDBlock *o, NCDStatement *after, NCDStatement s) -{ - struct BlockStatement *after_e = NULL; - if (after) { - after_e = UPPER_OBJECT(after, struct BlockStatement, s); - } - - if (o->count == SIZE_MAX) { - return 0; - } - - struct BlockStatement *e = malloc(sizeof(*e)); - if (!e) { - return 0; - } - - if (after_e) { - LinkedList1_InsertAfter(&o->statements_list, &e->statements_list_node, &after_e->statements_list_node); - } else { - LinkedList1_Prepend(&o->statements_list, &e->statements_list_node); - } - e->s = s; - - o->count++; - - return 1; -} - -NCDStatement * NCDBlock_ReplaceStatement (NCDBlock *o, NCDStatement *es, NCDStatement s) -{ - ASSERT(es) - - struct BlockStatement *e = UPPER_OBJECT(es, struct BlockStatement, s); - - NCDStatement_Free(&e->s); - e->s = s; - - return &e->s; -} - -NCDStatement * NCDBlock_FirstStatement (NCDBlock *o) -{ - LinkedList1Node *ln = LinkedList1_GetFirst(&o->statements_list); - if (!ln) { - return NULL; - } - - struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); - - return &e->s; -} - -NCDStatement * NCDBlock_NextStatement (NCDBlock *o, NCDStatement *es) -{ - ASSERT(es) - - struct BlockStatement *cur_e = UPPER_OBJECT(es, struct BlockStatement, s); - - LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->statements_list_node); - if (!ln) { - return NULL; - } - - struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); - - return &e->s; -} - -size_t NCDBlock_NumStatements (NCDBlock *o) -{ - return o->count; -} - -int NCDStatement_InitReg (NCDStatement *o, const char *name, const char *objname, const char *cmdname, NCDValue args) -{ - ASSERT(cmdname) - ASSERT(NCDValue_Type(&args) == NCDVALUE_LIST) - - o->name = NULL; - o->reg.objname = NULL; - o->reg.cmdname = NULL; - - if (name && !(o->name = strdup(name))) { - goto fail; - } - - if (objname && !(o->reg.objname = strdup(objname))) { - goto fail; - } - - if (!(o->reg.cmdname = strdup(cmdname))) { - goto fail; - } - - o->type = NCDSTATEMENT_REG; - o->reg.args = args; - - return 1; - -fail: - free(o->name); - free(o->reg.objname); - free(o->reg.cmdname); - return 0; -} - -int NCDStatement_InitIf (NCDStatement *o, const char *name, NCDIfBlock ifblock) -{ - o->name = NULL; - - if (name && !(o->name = strdup(name))) { - return 0; - } - - o->type = NCDSTATEMENT_IF; - o->ifc.ifblock = ifblock; - o->ifc.have_else = 0; - - return 1; -} - -int NCDStatement_InitForeach (NCDStatement *o, const char *name, NCDValue collection, const char *name1, const char *name2, NCDBlock block) -{ - ASSERT(name1) - - o->name = NULL; - o->foreach.name1 = NULL; - o->foreach.name2 = NULL; - - if (name && !(o->name = strdup(name))) { - goto fail; - } - - if (!(o->foreach.name1 = strdup(name1))) { - goto fail; - } - - if (name2 && !(o->foreach.name2 = strdup(name2))) { - goto fail; - } - - o->type = NCDSTATEMENT_FOREACH; - o->foreach.collection = collection; - o->foreach.block = block; - o->foreach.is_grabbed = 0; - - return 1; - -fail: - free(o->name); - free(o->foreach.name1); - free(o->foreach.name2); - return 0; -} - -void NCDStatement_Free (NCDStatement *o) -{ - switch (o->type) { - case NCDSTATEMENT_REG: { - NCDValue_Free(&o->reg.args); - free(o->reg.cmdname); - free(o->reg.objname); - } break; - - case NCDSTATEMENT_IF: { - if (o->ifc.have_else) { - NCDBlock_Free(&o->ifc.else_block); - } - - NCDIfBlock_Free(&o->ifc.ifblock); - } break; - - case NCDSTATEMENT_FOREACH: { - if (!o->foreach.is_grabbed) { - NCDBlock_Free(&o->foreach.block); - NCDValue_Free(&o->foreach.collection); - } - free(o->foreach.name2); - free(o->foreach.name1); - } break; - - default: ASSERT(0); - } - - free(o->name); -} - -int NCDStatement_Type (NCDStatement *o) -{ - return o->type; -} - -const char * NCDStatement_Name (NCDStatement *o) -{ - return o->name; -} - -const char * NCDStatement_RegObjName (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_REG) - - return o->reg.objname; -} - -const char * NCDStatement_RegCmdName (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_REG) - - return o->reg.cmdname; -} - -NCDValue * NCDStatement_RegArgs (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_REG) - - return &o->reg.args; -} - -NCDIfBlock * NCDStatement_IfBlock (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_IF) - - return &o->ifc.ifblock; -} - -void NCDStatement_IfAddElse (NCDStatement *o, NCDBlock else_block) -{ - ASSERT(o->type == NCDSTATEMENT_IF) - ASSERT(!o->ifc.have_else) - - o->ifc.have_else = 1; - o->ifc.else_block = else_block; -} - -NCDBlock * NCDStatement_IfElse (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_IF) - - if (!o->ifc.have_else) { - return NULL; - } - - return &o->ifc.else_block; -} - -NCDBlock NCDStatement_IfGrabElse (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_IF) - ASSERT(o->ifc.have_else) - - o->ifc.have_else = 0; - - return o->ifc.else_block; -} - -NCDValue * NCDStatement_ForeachCollection (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_FOREACH) - ASSERT(!o->foreach.is_grabbed) - - return &o->foreach.collection; -} - -const char * NCDStatement_ForeachName1 (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_FOREACH) - - return o->foreach.name1; -} - -const char * NCDStatement_ForeachName2 (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_FOREACH) - - return o->foreach.name2; -} - -NCDBlock * NCDStatement_ForeachBlock (NCDStatement *o) -{ - ASSERT(o->type == NCDSTATEMENT_FOREACH) - ASSERT(!o->foreach.is_grabbed) - - return &o->foreach.block; -} - -void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlock *out_block) -{ - ASSERT(o->type == NCDSTATEMENT_FOREACH) - ASSERT(!o->foreach.is_grabbed) - - *out_collection = o->foreach.collection; - *out_block = o->foreach.block; - o->foreach.is_grabbed = 1; -} - -void NCDIfBlock_Init (NCDIfBlock *o) -{ - LinkedList1_Init(&o->ifs_list); -} - -void NCDIfBlock_Free (NCDIfBlock *o) -{ - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->ifs_list)) { - struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); - NCDIf_Free(&e->ifc); - LinkedList1_Remove(&o->ifs_list, &e->ifs_list_node); - free(e); - } -} - -int NCDIfBlock_PrependIf (NCDIfBlock *o, NCDIf ifc) -{ - struct IfBlockIf *e = malloc(sizeof(*e)); - if (!e) { - return 0; - } - - LinkedList1_Prepend(&o->ifs_list, &e->ifs_list_node); - e->ifc = ifc; - - return 1; -} - -NCDIf * NCDIfBlock_FirstIf (NCDIfBlock *o) -{ - LinkedList1Node *ln = LinkedList1_GetFirst(&o->ifs_list); - if (!ln) { - return NULL; - } - - struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); - - return &e->ifc; -} - -NCDIf * NCDIfBlock_NextIf (NCDIfBlock *o, NCDIf *ei) -{ - ASSERT(ei) - - struct IfBlockIf *cur_e = UPPER_OBJECT(ei, struct IfBlockIf, ifc); - - LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->ifs_list_node); - if (!ln) { - return NULL; - } - - struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); - - return &e->ifc; -} - -NCDIf NCDIfBlock_GrabIf (NCDIfBlock *o, NCDIf *ei) -{ - ASSERT(ei) - - struct IfBlockIf *e = UPPER_OBJECT(ei, struct IfBlockIf, ifc); - - NCDIf old_ifc = e->ifc; - - LinkedList1_Remove(&o->ifs_list, &e->ifs_list_node); - free(e); - - return old_ifc; -} - -void NCDIf_Init (NCDIf *o, NCDValue cond, NCDBlock block) -{ - o->cond = cond; - o->block = block; -} - -void NCDIf_Free (NCDIf *o) -{ - NCDValue_Free(&o->cond); - NCDBlock_Free(&o->block); -} - -void NCDIf_FreeGrab (NCDIf *o, NCDValue *out_cond, NCDBlock *out_block) -{ - *out_cond = o->cond; - *out_block = o->block; -} - -NCDValue * NCDIf_Cond (NCDIf *o) -{ - return &o->cond; -} - -NCDBlock * NCDIf_Block (NCDIf *o) -{ - return &o->block; -} diff --git a/external/badvpn_dns/ncd/NCDAst.h b/external/badvpn_dns/ncd/NCDAst.h deleted file mode 100644 index 95ca9e4..0000000 --- a/external/badvpn_dns/ncd/NCDAst.h +++ /dev/null @@ -1,237 +0,0 @@ -/** - * @file NCDAst.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDAST_H -#define BADVPN_NCDAST_H - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <structure/LinkedList1.h> - -typedef struct NCDValue_s NCDValue; -typedef struct NCDProgram_s NCDProgram; -typedef struct NCDProgramElem_s NCDProgramElem; -typedef struct NCDProcess_s NCDProcess; -typedef struct NCDBlock_s NCDBlock; -typedef struct NCDStatement_s NCDStatement; -typedef struct NCDIfBlock_s NCDIfBlock; -typedef struct NCDIf_s NCDIf; - -struct NCDValue_s { - int type; - union { - struct { - uint8_t *string; - size_t string_len; - }; - struct { - LinkedList1 list; - size_t list_count; - }; - struct { - LinkedList1 map_list; - size_t map_count; - }; - struct { - char *var_name; - }; - }; -}; - -struct NCDProgram_s { - LinkedList1 elems_list; - size_t num_elems; -}; - -struct NCDBlock_s { - LinkedList1 statements_list; - size_t count; -}; - -struct NCDProcess_s { - int is_template; - char *name; - NCDBlock block; -}; - -struct NCDProgramElem_s { - int type; - union { - NCDProcess process; - struct { - char *path_data; - size_t path_length; - } include; - struct { - char *id_data; - size_t id_length; - } include_guard; - }; -}; - -struct NCDIfBlock_s { - LinkedList1 ifs_list; -}; - -struct NCDStatement_s { - int type; - char *name; - union { - struct { - char *objname; - char *cmdname; - NCDValue args; - } reg; - struct { - NCDIfBlock ifblock; - int have_else; - NCDBlock else_block; - } ifc; - struct { - NCDValue collection; - char *name1; - char *name2; - NCDBlock block; - int is_grabbed; - } foreach; - }; -}; - -struct NCDIf_s { - NCDValue cond; - NCDBlock block; -}; - -// - -#define NCDVALUE_STRING 1 -#define NCDVALUE_LIST 2 -#define NCDVALUE_MAP 3 -#define NCDVALUE_VAR 4 - -#define NCDPROGRAMELEM_PROCESS 1 -#define NCDPROGRAMELEM_INCLUDE 2 -#define NCDPROGRAMELEM_INCLUDE_GUARD 3 - -#define NCDSTATEMENT_REG 1 -#define NCDSTATEMENT_IF 2 -#define NCDSTATEMENT_FOREACH 3 - -void NCDValue_Free (NCDValue *o); -int NCDValue_Type (NCDValue *o); -int NCDValue_InitString (NCDValue *o, const char *str) WARN_UNUSED; -int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len) WARN_UNUSED; -const char * NCDValue_StringValue (NCDValue *o); -size_t NCDValue_StringLength (NCDValue *o); -void NCDValue_InitList (NCDValue *o); -size_t NCDValue_ListCount (NCDValue *o); -int NCDValue_ListAppend (NCDValue *o, NCDValue v) WARN_UNUSED; -int NCDValue_ListPrepend (NCDValue *o, NCDValue v) WARN_UNUSED; -NCDValue * NCDValue_ListFirst (NCDValue *o); -NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev); -void NCDValue_InitMap (NCDValue *o); -size_t NCDValue_MapCount (NCDValue *o); -int NCDValue_MapPrepend (NCDValue *o, NCDValue key, NCDValue val) WARN_UNUSED; -NCDValue * NCDValue_MapFirstKey (NCDValue *o); -NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey); -NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey); -int NCDValue_InitVar (NCDValue *o, const char *var_name) WARN_UNUSED; -const char * NCDValue_VarName (NCDValue *o); - -void NCDProgram_Init (NCDProgram *o); -void NCDProgram_Free (NCDProgram *o); -NCDProgramElem * NCDProgram_PrependElem (NCDProgram *o, NCDProgramElem elem) WARN_UNUSED; -NCDProgramElem * NCDProgram_FirstElem (NCDProgram *o); -NCDProgramElem * NCDProgram_NextElem (NCDProgram *o, NCDProgramElem *ee); -size_t NCDProgram_NumElems (NCDProgram *o); -int NCDProgram_ContainsElemType (NCDProgram *o, int elem_type); -void NCDProgram_RemoveElem (NCDProgram *o, NCDProgramElem *ee); -int NCDProgram_ReplaceElemWithProgram (NCDProgram *o, NCDProgramElem *ee, NCDProgram replace_prog) WARN_UNUSED; - -void NCDProgramElem_InitProcess (NCDProgramElem *o, NCDProcess process); -int NCDProgramElem_InitInclude (NCDProgramElem *o, const char *path_data, size_t path_length) WARN_UNUSED; -int NCDProgramElem_InitIncludeGuard (NCDProgramElem *o, const char *id_data, size_t id_length) WARN_UNUSED; -void NCDProgramElem_Free (NCDProgramElem *o); -int NCDProgramElem_Type (NCDProgramElem *o); -NCDProcess * NCDProgramElem_Process (NCDProgramElem *o); -const char * NCDProgramElem_IncludePathData (NCDProgramElem *o); -size_t NCDProgramElem_IncludePathLength (NCDProgramElem *o); -const char * NCDProgramElem_IncludeGuardIdData (NCDProgramElem *o); -size_t NCDProgramElem_IncludeGuardIdLength (NCDProgramElem *o); - -int NCDProcess_Init (NCDProcess *o, int is_template, const char *name, NCDBlock block) WARN_UNUSED; -void NCDProcess_Free (NCDProcess *o); -int NCDProcess_IsTemplate (NCDProcess *o); -const char * NCDProcess_Name (NCDProcess *o); -NCDBlock * NCDProcess_Block (NCDProcess *o); - -void NCDBlock_Init (NCDBlock *o); -void NCDBlock_Free (NCDBlock *o); -int NCDBlock_PrependStatement (NCDBlock *o, NCDStatement s) WARN_UNUSED; -int NCDBlock_InsertStatementAfter (NCDBlock *o, NCDStatement *after, NCDStatement s) WARN_UNUSED; -NCDStatement * NCDBlock_ReplaceStatement (NCDBlock *o, NCDStatement *es, NCDStatement s); -NCDStatement * NCDBlock_FirstStatement (NCDBlock *o); -NCDStatement * NCDBlock_NextStatement (NCDBlock *o, NCDStatement *es); -size_t NCDBlock_NumStatements (NCDBlock *o); - -int NCDStatement_InitReg (NCDStatement *o, const char *name, const char *objname, const char *cmdname, NCDValue args) WARN_UNUSED; -int NCDStatement_InitIf (NCDStatement *o, const char *name, NCDIfBlock ifblock) WARN_UNUSED; -int NCDStatement_InitForeach (NCDStatement *o, const char *name, NCDValue collection, const char *name1, const char *name2, NCDBlock block) WARN_UNUSED; -void NCDStatement_Free (NCDStatement *o); -int NCDStatement_Type (NCDStatement *o); -const char * NCDStatement_Name (NCDStatement *o); -const char * NCDStatement_RegObjName (NCDStatement *o); -const char * NCDStatement_RegCmdName (NCDStatement *o); -NCDValue * NCDStatement_RegArgs (NCDStatement *o); -NCDIfBlock * NCDStatement_IfBlock (NCDStatement *o); -void NCDStatement_IfAddElse (NCDStatement *o, NCDBlock else_block); -NCDBlock * NCDStatement_IfElse (NCDStatement *o); -NCDBlock NCDStatement_IfGrabElse (NCDStatement *o); -NCDValue * NCDStatement_ForeachCollection (NCDStatement *o); -const char * NCDStatement_ForeachName1 (NCDStatement *o); -const char * NCDStatement_ForeachName2 (NCDStatement *o); -NCDBlock * NCDStatement_ForeachBlock (NCDStatement *o); -void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlock *out_block); - -void NCDIfBlock_Init (NCDIfBlock *o); -void NCDIfBlock_Free (NCDIfBlock *o); -int NCDIfBlock_PrependIf (NCDIfBlock *o, NCDIf ifc) WARN_UNUSED; -NCDIf * NCDIfBlock_FirstIf (NCDIfBlock *o); -NCDIf * NCDIfBlock_NextIf (NCDIfBlock *o, NCDIf *ei); -NCDIf NCDIfBlock_GrabIf (NCDIfBlock *o, NCDIf *ei); - -void NCDIf_Init (NCDIf *o, NCDValue cond, NCDBlock block); -void NCDIf_Free (NCDIf *o); -void NCDIf_FreeGrab (NCDIf *o, NCDValue *out_cond, NCDBlock *out_block); -NCDValue * NCDIf_Cond (NCDIf *o); -NCDBlock * NCDIf_Block (NCDIf *o); - -#endif diff --git a/external/badvpn_dns/ncd/NCDBuildProgram.c b/external/badvpn_dns/ncd/NCDBuildProgram.c deleted file mode 100644 index 941a142..0000000 --- a/external/badvpn_dns/ncd/NCDBuildProgram.c +++ /dev/null @@ -1,316 +0,0 @@ -/** - * @file NCDBuildProgram.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/read_file.h> -#include <misc/strdup.h> -#include <misc/concat_strings.h> -#include <base/BLog.h> -#include <ncd/NCDConfigParser.h> - -#include "NCDBuildProgram.h" - -#include <generated/blog_channel_NCDBuildProgram.h> - -#define MAX_INCLUDE_DEPTH 32 - -struct guard { - char *id_data; - size_t id_length; - struct guard *next; -}; - -struct build_state { - struct guard *top_guard; -}; - -static int add_guard (struct guard **first, const char *id_data, size_t id_length) -{ - struct guard *g = malloc(sizeof(*g)); - if (!g) { - goto fail0; - } - - if (!(g->id_data = b_strdup_bin(id_data, id_length))) { - goto fail1; - } - - g->id_length = id_length; - - g->next = *first; - *first = g; - - return 1; - -fail1: - free(g); -fail0: - return 0; -} - -static void prepend_guards (struct guard **first, struct guard *guards) -{ - if (!guards) { - return; - } - - struct guard *last = guards; - while (last->next) { - last = last->next; - } - - last->next = *first; - *first = guards; -} - -static void free_guards (struct guard *g) -{ - while (g) { - struct guard *next_g = g->next; - free(g->id_data); - free(g); - g = next_g; - } -} - -static int guard_exists (struct guard *top_guard, const char *id_data, size_t id_length) -{ - for (struct guard *g = top_guard; g; g = g->next) { - if (g->id_length == id_length && !memcmp(g->id_data, id_data, id_length)) { - return 1; - } - } - - return 0; -} - -static char * make_dir_path (const char *file_path) -{ - int found_slash = 0; - size_t last_slash = 0; // initialize to remove warning - - for (size_t i = 0; file_path[i]; i++) { - if (file_path[i] == '/') { - found_slash = 1; - last_slash = i; - } - } - - char *dir_path; - - if (!found_slash) { - if (!file_path[0]) { - BLog(BLOG_ERROR, "file '%s': file path must not be empty", file_path); - return NULL; - } - dir_path = b_strdup(""); - } else { - if (!file_path[last_slash + 1]) { - BLog(BLOG_ERROR, "file '%s': file path must not end in a slash", file_path); - return NULL; - } - dir_path = b_strdup_bin(file_path, last_slash + 1); - } - - if (!dir_path) { - BLog(BLOG_ERROR, "file '%s': b_strdup/b_strdup_bin failed", file_path); - return NULL; - } - - return dir_path; -} - -static char * make_include_path (const char *file_path, const char *dir_path, const char *target, size_t target_len) -{ - ASSERT(target_len == strlen(target)) - - if (target_len == 0) { - BLog(BLOG_ERROR, "file '%s': include target must not be empty", file_path); - return NULL; - } - - if (target[target_len - 1] == '/') { - BLog(BLOG_ERROR, "file '%s': include target must not end in a slash", file_path); - return NULL; - } - - char *real_target; - - if (target[0] == '/') { - real_target = b_strdup(target); - } else { - real_target = concat_strings(2, dir_path, target); - } - - if (!real_target) { - BLog(BLOG_ERROR, "file '%s': b_strdup/concat_strings failed", file_path); - return NULL; - } - - return real_target; -} - -static int process_file (struct build_state *st, int depth, const char *file_path, NCDProgram *out_program, int *out_guarded) -{ - int ret_val = 0; - - if (depth > MAX_INCLUDE_DEPTH) { - BLog(BLOG_ERROR, "file '%s': maximum include depth (%d) exceeded (include cycle?)", file_path, (int)MAX_INCLUDE_DEPTH); - goto fail0; - } - - char *dir_path = make_dir_path(file_path); - if (!dir_path) { - goto fail0; - } - - uint8_t *data; - size_t len; - if (!read_file(file_path, &data, &len)) { - BLog(BLOG_ERROR, "file '%s': failed to read contents", file_path); - goto fail1; - } - - NCDProgram program; - int res = NCDConfigParser_Parse((char *)data, len, &program); - free(data); - if (!res) { - BLog(BLOG_ERROR, "file '%s': failed to parse", file_path); - goto fail1; - } - - struct guard *our_guards = NULL; - - NCDProgramElem *elem = NCDProgram_FirstElem(&program); - while (elem) { - NCDProgramElem *next_elem = NCDProgram_NextElem(&program, elem); - if (NCDProgramElem_Type(elem) != NCDPROGRAMELEM_INCLUDE_GUARD) { - elem = next_elem; - continue; - } - - const char *id_data = NCDProgramElem_IncludeGuardIdData(elem); - size_t id_length = NCDProgramElem_IncludeGuardIdLength(elem); - - if (guard_exists(st->top_guard, id_data, id_length)) { - *out_guarded = 1; - ret_val = 1; - goto fail2; - } - - if (!add_guard(&our_guards, id_data, id_length)) { - BLog(BLOG_ERROR, "file '%s': add_guard failed", file_path); - goto fail2; - } - - NCDProgram_RemoveElem(&program, elem); - elem = next_elem; - } - - prepend_guards(&st->top_guard, our_guards); - our_guards = NULL; - - elem = NCDProgram_FirstElem(&program); - while (elem) { - NCDProgramElem *next_elem = NCDProgram_NextElem(&program, elem); - if (NCDProgramElem_Type(elem) != NCDPROGRAMELEM_INCLUDE) { - elem = next_elem; - continue; - } - - const char *target = NCDProgramElem_IncludePathData(elem); - size_t target_len = NCDProgramElem_IncludePathLength(elem); - - if (strlen(target) != target_len) { - BLog(BLOG_ERROR, "file '%s': include path must not contain null characters", file_path); - goto fail2; - } - - char *real_target = make_include_path(file_path, dir_path, target, target_len); - if (!real_target) { - goto fail2; - } - - NCDProgram included_program; - int included_guarded; - int res = process_file(st, depth + 1, real_target, &included_program, &included_guarded); - free(real_target); - if (!res) { - goto fail2; - } - - if (included_guarded) { - NCDProgram_RemoveElem(&program, elem); - } else { - if (!NCDProgram_ReplaceElemWithProgram(&program, elem, included_program)) { - BLog(BLOG_ERROR, "file '%s': NCDProgram_ReplaceElemWithProgram failed", file_path); - NCDProgram_Free(&included_program); - goto fail2; - } - } - - elem = next_elem; - } - - free(dir_path); - - *out_program = program; - *out_guarded = 0; - return 1; - -fail2: - free_guards(our_guards); - NCDProgram_Free(&program); -fail1: - free(dir_path); -fail0: - return ret_val; -} - -int NCDBuildProgram_Build (const char *file_path, NCDProgram *out_program) -{ - ASSERT(file_path) - ASSERT(out_program) - - struct build_state st; - st.top_guard = NULL; - - int guarded; - int res = process_file(&st, 0, file_path, out_program, &guarded); - - ASSERT(!res || !guarded) - - free_guards(st.top_guard); - - return res; -} diff --git a/external/badvpn_dns/ncd/NCDBuildProgram.h b/external/badvpn_dns/ncd/NCDBuildProgram.h deleted file mode 100644 index dff6685..0000000 --- a/external/badvpn_dns/ncd/NCDBuildProgram.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file NCDBuildProgram.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_BUILD_PROGRAM_H -#define NCD_BUILD_PROGRAM_H - -#include <misc/debug.h> -#include <ncd/NCDAst.h> - -/** - * Builds an NCD program in AST form suitable for passing to {@link NCDInterpreter}, - * by opening and parsing it, as well as recursively processing any included files. - * The resulting program will not contain any 'include' or 'include_guard' elements; - * these will be resolved and removed. - * - * @param file_path path to the main file of the program - * @param out_program on success, *out_program will contain the resulting program. - * On failure, *out_program will be unchanged. - * @return 1 on success, 0 on failure - */ -int NCDBuildProgram_Build (const char *file_path, NCDProgram *out_program) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDConfigParser.c b/external/badvpn_dns/ncd/NCDConfigParser.c deleted file mode 100644 index f883f72..0000000 --- a/external/badvpn_dns/ncd/NCDConfigParser.c +++ /dev/null @@ -1,214 +0,0 @@ -/** - * @file NCDConfigParser.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <base/BLog.h> -#include <ncd/NCDConfigTokenizer.h> - -#include "ncd/NCDConfigParser.h" - -#include <generated/blog_channel_NCDConfigParser.h> - -#include "../generated/NCDConfigParser_parse.c" -#include "../generated/NCDConfigParser_parse.h" - -struct parser_state { - struct parser_out out; - int error; - void *parser; -}; - -static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char) -{ - struct parser_state *state = user; - ASSERT(!state->out.out_of_memory) - ASSERT(!state->out.syntax_error) - ASSERT(!state->error) - - if (token == NCD_ERROR) { - BLog(BLOG_ERROR, "line %zu, character %zu: tokenizer error", line, line_char); - state->error = 1; - return 0; - } - - struct token minor; - minor.str = value; - minor.len = value_len; - - switch (token) { - case NCD_EOF: { - Parse(state->parser, 0, minor, &state->out); - } break; - - case NCD_TOKEN_CURLY_OPEN: { - Parse(state->parser, CURLY_OPEN, minor, &state->out); - } break; - - case NCD_TOKEN_CURLY_CLOSE: { - Parse(state->parser, CURLY_CLOSE, minor, &state->out); - } break; - - case NCD_TOKEN_ROUND_OPEN: { - Parse(state->parser, ROUND_OPEN, minor, &state->out); - } break; - - case NCD_TOKEN_ROUND_CLOSE: { - Parse(state->parser, ROUND_CLOSE, minor, &state->out); - } break; - - case NCD_TOKEN_SEMICOLON: { - Parse(state->parser, SEMICOLON, minor, &state->out); - } break; - - case NCD_TOKEN_DOT: { - Parse(state->parser, DOT, minor, &state->out); - } break; - - case NCD_TOKEN_COMMA: { - Parse(state->parser, COMMA, minor, &state->out); - } break; - - case NCD_TOKEN_ARROW: { - Parse(state->parser, ARROW, minor, &state->out); - } break; - - case NCD_TOKEN_PROCESS: { - Parse(state->parser, PROCESS, minor, &state->out); - } break; - - case NCD_TOKEN_TEMPLATE: { - Parse(state->parser, TEMPLATE, minor, &state->out); - } break; - - case NCD_TOKEN_NAME: { - Parse(state->parser, NAME, minor, &state->out); - } break; - - case NCD_TOKEN_STRING: { - Parse(state->parser, STRING, minor, &state->out); - } break; - - case NCD_TOKEN_COLON: { - Parse(state->parser, COLON, minor, &state->out); - } break; - - case NCD_TOKEN_BRACKET_OPEN: { - Parse(state->parser, BRACKET_OPEN, minor, &state->out); - } break; - - case NCD_TOKEN_BRACKET_CLOSE: { - Parse(state->parser, BRACKET_CLOSE, minor, &state->out); - } break; - - case NCD_TOKEN_IF: { - Parse(state->parser, IF, minor, &state->out); - } break; - - case NCD_TOKEN_ELIF: { - Parse(state->parser, ELIF, minor, &state->out); - } break; - - case NCD_TOKEN_ELSE: { - Parse(state->parser, ELSE, minor, &state->out); - } break; - - case NCD_TOKEN_FOREACH: { - Parse(state->parser, FOREACH, minor, &state->out); - } break; - - case NCD_TOKEN_AS: { - Parse(state->parser, AS, minor, &state->out); - } break; - - case NCD_TOKEN_INCLUDE: { - Parse(state->parser, INCLUDE, minor, &state->out); - } break; - - case NCD_TOKEN_INCLUDE_GUARD: { - Parse(state->parser, INCLUDE_GUARD, minor, &state->out); - } break; - - default: - BLog(BLOG_ERROR, "line %zu, character %zu: invalid token", line, line_char); - free(minor.str); - state->error = 1; - return 0; - } - - // if we got syntax error, stop parsing - if (state->out.syntax_error) { - BLog(BLOG_ERROR, "line %zu, character %zu: syntax error", line, line_char); - state->error = 1; - return 0; - } - - if (state->out.out_of_memory) { - BLog(BLOG_ERROR, "line %zu, character %zu: out of memory", line, line_char); - state->error = 1; - return 0; - } - - return 1; -} - -int NCDConfigParser_Parse (char *config, size_t config_len, NCDProgram *out_ast) -{ - struct parser_state state; - - state.out.out_of_memory = 0; - state.out.syntax_error = 0; - state.out.have_ast = 0; - state.error = 0; - - if (!(state.parser = ParseAlloc(malloc))) { - BLog(BLOG_ERROR, "ParseAlloc failed"); - return 0; - } - - // tokenize and parse - NCDConfigTokenizer_Tokenize(config, config_len, tokenizer_output, &state); - - ParseFree(state.parser, free); - - if (state.error) { - if (state.out.have_ast) { - NCDProgram_Free(&state.out.ast); - } - return 0; - } - - ASSERT(state.out.have_ast) - - *out_ast = state.out.ast; - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDConfigParser.h b/external/badvpn_dns/ncd/NCDConfigParser.h deleted file mode 100644 index 90cee54..0000000 --- a/external/badvpn_dns/ncd/NCDConfigParser.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file NCDConfigParser.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDCONFIG_NCDCONFIGPARSER_H -#define BADVPN_NCDCONFIG_NCDCONFIGPARSER_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <ncd/NCDAst.h> - -int NCDConfigParser_Parse (char *config, size_t config_len, NCDProgram *out_ast) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDConfigParser_parse.y b/external/badvpn_dns/ncd/NCDConfigParser_parse.y deleted file mode 100644 index fdf89f6..0000000 --- a/external/badvpn_dns/ncd/NCDConfigParser_parse.y +++ /dev/null @@ -1,718 +0,0 @@ -/** - * @file NCDConfigParser.y - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -%include { - -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/concat_strings.h> -#include <ncd/NCDAst.h> - -struct parser_out { - int out_of_memory; - int syntax_error; - int have_ast; - NCDProgram ast; -}; - -struct token { - char *str; - size_t len; -}; - -struct program { - int have; - NCDProgram v; -}; - -struct block { - int have; - NCDBlock v; -}; - -struct statement { - int have; - NCDStatement v; -}; - -struct ifblock { - int have; - NCDIfBlock v; -}; - -struct value { - int have; - NCDValue v; -}; - -static void free_token (struct token o) { free(o.str); } -static void free_program (struct program o) { if (o.have) NCDProgram_Free(&o.v); } -static void free_block (struct block o) { if (o.have) NCDBlock_Free(&o.v); } -static void free_statement (struct statement o) { if (o.have) NCDStatement_Free(&o.v); } -static void free_ifblock (struct ifblock o) { if (o.have) NCDIfBlock_Free(&o.v); } -static void free_value (struct value o) { if (o.have) NCDValue_Free(&o.v); } - -} - -%extra_argument { struct parser_out *parser_out } - -%token_type { struct token } - -%token_destructor { free_token($$); } - -%type processes { struct program } -%type statement { struct statement } -%type elif_maybe { struct ifblock } -%type elif { struct ifblock } -%type else_maybe { struct block } -%type statements { struct block } -%type dotted_name { char * } -%type statement_args_maybe { struct value } -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type value { struct value } -%type name_maybe { char * } -%type process_or_template { int } - -// mention parser_out in some destructor to a void unused variable warning -%destructor processes { (void)parser_out; free_program($$); } -%destructor statement { free_statement($$); } -%destructor elif_maybe { free_ifblock($$); } -%destructor elif { free_ifblock($$); } -%destructor else_maybe { free_block($$); } -%destructor statements { free_block($$); } -%destructor dotted_name { free($$); } -%destructor statement_args_maybe { free_value($$); } -%destructor list_contents { free_value($$); } -%destructor list { free_value($$); } -%destructor map_contents { free_value($$); } -%destructor map { free_value($$); } -%destructor value { free_value($$); } -%destructor name_maybe { free($$); } - -%stack_size 0 - -%syntax_error { - parser_out->syntax_error = 1; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= processes(A). { - ASSERT(!parser_out->have_ast) - - if (A.have) { - parser_out->have_ast = 1; - parser_out->ast = A.v; - } -} - -processes(R) ::= . { - NCDProgram prog; - NCDProgram_Init(&prog); - - R.have = 1; - R.v = prog; -} - -processes(R) ::= INCLUDE STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failA0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitInclude(&elem, A.str, A.len)) { - goto failA0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failA1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneA; - -failA1: - NCDProgramElem_Free(&elem); -failA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneA: - free_token(A); - free_program(N); -} - -processes(R) ::= INCLUDE_GUARD STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failZ0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitIncludeGuard(&elem, A.str, A.len)) { - goto failZ0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failZ1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneZ; - -failZ1: - NCDProgramElem_Free(&elem); -failZ0: - R.have = 0; - parser_out->out_of_memory = 1; -doneZ: - free_token(A); - free_program(N); -} - -processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE processes(N). { - ASSERT(A.str) - if (!B.have || !N.have) { - goto failB0; - } - - NCDProcess proc; - if (!NCDProcess_Init(&proc, T, A.str, B.v)) { - goto failB0; - } - B.have = 0; - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc); - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failB1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneB; - -failB1: - NCDProgramElem_Free(&elem); -failB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneB: - free_token(A); - free_block(B); - free_program(N); -} - -statement(R) ::= dotted_name(A) ROUND_OPEN statement_args_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!A || !B.have) { - goto failC0; - } - - if (!NCDStatement_InitReg(&R.v, C, NULL, A, B.v)) { - goto failC0; - } - B.have = 0; - - R.have = 1; - goto doneC; - -failC0: - R.have = 0; - parser_out->out_of_memory = 1; -doneC: - free(A); - free_value(B); - free(C); -} - -statement(R) ::= dotted_name(M) ARROW dotted_name(A) ROUND_OPEN statement_args_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!M || !A || !B.have) { - goto failD0; - } - - if (!NCDStatement_InitReg(&R.v, C, M, A, B.v)) { - goto failD0; - } - B.have = 0; - - R.have = 1; - goto doneD; - -failD0: - R.have = 0; - parser_out->out_of_memory = 1; -doneD: - free(M); - free(A); - free_value(B); - free(C); -} - -statement(R) ::= IF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif_maybe(I) else_maybe(E) name_maybe(C) SEMICOLON. { - if (!A.have || !B.have || !I.have) { - goto failE0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&I.v, ifc)) { - NCDIf_Free(&ifc); - goto failE0; - } - - if (!NCDStatement_InitIf(&R.v, C, I.v)) { - goto failE0; - } - I.have = 0; - - if (E.have) { - NCDStatement_IfAddElse(&R.v, E.v); - E.have = 0; - } - - R.have = 1; - goto doneE; - -failE0: - R.have = 0; - parser_out->out_of_memory = 1; -doneE: - free_value(A); - free_block(B); - free_ifblock(I); - free_block(E); - free(C); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !S.have) { - goto failEA0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, NULL, S.v)) { - goto failEA0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEA0; - -failEA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEA0: - free_value(A); - free_token(B); - free_block(S); - free(N); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) COLON NAME(C) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !C.str || !S.have) { - goto failEB0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, C.str, S.v)) { - goto failEB0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEB0; - -failEB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEB0: - free_value(A); - free_token(B); - free_token(C); - free_block(S); - free(N); -} - -elif_maybe(R) ::= . { - NCDIfBlock_Init(&R.v); - R.have = 1; -} - -elif_maybe(R) ::= elif(A). { - R = A; -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE. { - if (!A.have || !B.have) { - goto failF0; - } - - NCDIfBlock_Init(&R.v); - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&R.v, ifc)) { - goto failF1; - } - - R.have = 1; - goto doneF0; - -failF1: - NCDIf_Free(&ifc); - NCDIfBlock_Free(&R.v); -failF0: - R.have = 0; - parser_out->out_of_memory = 1; -doneF0: - free_value(A); - free_block(B); -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif(N). { - if (!A.have || !B.have || !N.have) { - goto failG0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&N.v, ifc)) { - goto failG1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneG0; - -failG1: - NCDIf_Free(&ifc); -failG0: - R.have = 0; - parser_out->out_of_memory = 1; -doneG0: - free_value(A); - free_block(B); - free_ifblock(N); -} - -else_maybe(R) ::= . { - R.have = 0; -} - -else_maybe(R) ::= ELSE CURLY_OPEN statements(B) CURLY_CLOSE. { - R = B; -} - -statements(R) ::= statement(A). { - if (!A.have) { - goto failH0; - } - - NCDBlock_Init(&R.v); - - if (!NCDBlock_PrependStatement(&R.v, A.v)) { - goto failH1; - } - A.have = 0; - - R.have = 1; - goto doneH; - -failH1: - NCDBlock_Free(&R.v); -failH0: - R.have = 0; - parser_out->out_of_memory = 1; -doneH: - free_statement(A); -} - -statements(R) ::= statement(A) statements(N). { - if (!A.have || !N.have) { - goto failI0; - } - - if (!NCDBlock_PrependStatement(&N.v, A.v)) { - goto failI1; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneI; - -failI1: - NCDBlock_Free(&R.v); -failI0: - R.have = 0; - parser_out->out_of_memory = 1; -doneI: - free_statement(A); - free_block(N); -} - -dotted_name(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -dotted_name(R) ::= NAME(A) DOT dotted_name(N). { - ASSERT(A.str) - if (!N) { - goto failJ0; - } - - if (!(R = concat_strings(3, A.str, ".", N))) { - goto failJ0; - } - - goto doneJ; - -failJ0: - R = NULL; - parser_out->out_of_memory = 1; -doneJ: - free_token(A); - free(N); -} - -statement_args_maybe(R) ::= . { - R.have = 1; - NCDValue_InitList(&R.v); -} - -statement_args_maybe(R) ::= list_contents(A). { - R = A; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValue_InitList(&R.v); - - if (!NCDValue_ListPrepend(&R.v, A.v)) { - goto failL1; - } - A.have = 0; - - R.have = 1; - goto doneL; - -failL1: - NCDValue_Free(&R.v); -failL0: - R.have = 0; - parser_out->out_of_memory = 1; -doneL: - free_value(A); -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValue_ListPrepend(&N.v, A.v)) { - goto failM0; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneM; - -failM0: - R.have = 0; - parser_out->out_of_memory = 1; -doneM: - free_value(A); - free_value(N); -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - R.have = 1; - NCDValue_InitList(&R.v); -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValue_InitMap(&R.v); - - if (!NCDValue_MapPrepend(&R.v, A.v, B.v)) { - goto failS1; - } - A.have = 0; - B.have = 0; - - R.have = 1; - goto doneS; - -failS1: - NCDValue_Free(&R.v); -failS0: - R.have = 0; - parser_out->out_of_memory = 1; -doneS: - free_value(A); - free_value(B); -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValue_MapPrepend(&N.v, A.v, B.v)) { - goto failT0; - } - A.have = 0; - B.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneT; - -failT0: - R.have = 0; - parser_out->out_of_memory = 1; -doneT: - free_value(A); - free_value(B); - free_value(N); -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - R.have = 1; - NCDValue_InitMap(&R.v); -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValue_InitStringBin(&R.v, (uint8_t *)A.str, A.len)) { - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; - parser_out->out_of_memory = 1; -doneU: - free_token(A); -} - -value(R) ::= dotted_name(A). { - if (!A) { - goto failV0; - } - - if (!NCDValue_InitVar(&R.v, A)) { - goto failV0; - } - - R.have = 1; - goto doneV; - -failV0: - R.have = 0; - parser_out->out_of_memory = 1; -doneV: - free(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} - -name_maybe(R) ::= . { - R = NULL; -} - -name_maybe(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -process_or_template(R) ::= PROCESS. { - R = 0; -} - -process_or_template(R) ::= TEMPLATE. { - R = 1; -} diff --git a/external/badvpn_dns/ncd/NCDConfigTokenizer.c b/external/badvpn_dns/ncd/NCDConfigTokenizer.c deleted file mode 100644 index 5ba31b4..0000000 --- a/external/badvpn_dns/ncd/NCDConfigTokenizer.c +++ /dev/null @@ -1,321 +0,0 @@ -/** - * @file NCDConfigTokenizer.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stddef.h> -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/string_begins_with.h> -#include <misc/balloc.h> -#include <misc/expstring.h> -#include <misc/parse_number.h> -#include <base/BLog.h> - -#include <ncd/NCDConfigTokenizer.h> - -#include <generated/blog_channel_NCDConfigTokenizer.h> - -static int is_name_char (char c) -{ - return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'); -} - -static int is_name_first_char (char c) -{ - return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'); -} - -static int is_space_char (char c) -{ - return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); -} - -static int string_equals (char *str, int str_len, char *needle) -{ - return (str_len == strlen(needle) && !memcmp(str, needle, str_len)); -} - -void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user) -{ - size_t line = 1; - size_t line_char = 1; - - while (left > 0) { - size_t l; - int error = 0; - int token; - void *token_val = NULL; - size_t token_len = 0; - - if (*str == '#') { - l = 1; - while (l < left && str[l] != '\n') { - l++; - } - token = 0; - } - else if (l = data_begins_with(str, left, "{")) { - token = NCD_TOKEN_CURLY_OPEN; - } - else if (l = data_begins_with(str, left, "}")) { - token = NCD_TOKEN_CURLY_CLOSE; - } - else if (l = data_begins_with(str, left, "(")) { - token = NCD_TOKEN_ROUND_OPEN; - } - else if (l = data_begins_with(str, left, ")")) { - token = NCD_TOKEN_ROUND_CLOSE; - } - else if (l = data_begins_with(str, left, ";")) { - token = NCD_TOKEN_SEMICOLON; - } - else if (l = data_begins_with(str, left, ".")) { - token = NCD_TOKEN_DOT; - } - else if (l = data_begins_with(str, left, ",")) { - token = NCD_TOKEN_COMMA; - } - else if (l = data_begins_with(str, left, ":")) { - token = NCD_TOKEN_COLON; - } - else if (l = data_begins_with(str, left, "[")) { - token = NCD_TOKEN_BRACKET_OPEN; - } - else if (l = data_begins_with(str, left, "]")) { - token = NCD_TOKEN_BRACKET_CLOSE; - } - else if (l = data_begins_with(str, left, "->")) { - token = NCD_TOKEN_ARROW; - } - else if (l = data_begins_with(str, left, "If")) { - token = NCD_TOKEN_IF; - } - else if (l = data_begins_with(str, left, "Elif")) { - token = NCD_TOKEN_ELIF; - } - else if (l = data_begins_with(str, left, "elif")) { - token = NCD_TOKEN_ELIF; - } - else if (l = data_begins_with(str, left, "Else")) { - token = NCD_TOKEN_ELSE; - } - else if (l = data_begins_with(str, left, "else")) { - token = NCD_TOKEN_ELSE; - } - else if (l = data_begins_with(str, left, "Foreach")) { - token = NCD_TOKEN_FOREACH; - } - else if (l = data_begins_with(str, left, "As")) { - token = NCD_TOKEN_AS; - } - else if (l = data_begins_with(str, left, "include_guard")) { - token = NCD_TOKEN_INCLUDE_GUARD; - } - else if (l = data_begins_with(str, left, "include")) { - token = NCD_TOKEN_INCLUDE; - } - else if (is_name_first_char(*str)) { - l = 1; - while (l < left && is_name_char(str[l])) { - l++; - } - - // allocate buffer - bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1)); - char *buf; - if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) { - BLog(BLOG_ERROR, "malloc failed"); - error = 1; - goto out; - } - - // copy and terminate - memcpy(buf, str, l); - buf[l] = '\0'; - - if (!strcmp(buf, "process")) { - token = NCD_TOKEN_PROCESS; - free(buf); - } - else if (!strcmp(buf, "template")) { - token = NCD_TOKEN_TEMPLATE; - free(buf); - } - else { - token = NCD_TOKEN_NAME; - token_val = buf; - token_len = l; - } - } - else if (*str == '"') do { - // init string - ExpString estr; - if (!ExpString_Init(&estr)) { - BLog(BLOG_ERROR, "ExpString_Init failed"); - goto string_fail0; - } - - // skip start quote - l = 1; - - // decode string - while (l < left) { - uint8_t dec_ch; - - // get character - if (str[l] == '\') { - if (left - l < 2) { - BLog(BLOG_ERROR, "escape character found in string but nothing follows"); - goto string_fail1; - } - - size_t extra = 0; - - switch (str[l + 1]) { - case ''': - case '"': - case '\': - case '?': - dec_ch = str[l + 1]; break; - - case 'a': - dec_ch = '\a'; break; - case 'b': - dec_ch = '\b'; break; - case 'f': - dec_ch = '\f'; break; - case 'n': - dec_ch = '\n'; break; - case 'r': - dec_ch = '\r'; break; - case 't': - dec_ch = '\t'; break; - case 'v': - dec_ch = '\v'; break; - - case '0': - dec_ch = 0; break; - - case 'x': { - if (left - l < 4) { - BLog(BLOG_ERROR, "hexadecimal escape found in string but too little characters follow"); - goto string_fail1; - } - - uintmax_t hex_val; - if (!parse_unsigned_hex_integer_bin(&str[l + 2], 2, &hex_val)) { - BLog(BLOG_ERROR, "hexadecimal escape found in string but two hex characters don't follow"); - goto string_fail1; - } - - dec_ch = hex_val; - extra = 2; - } break; - - default: - BLog(BLOG_ERROR, "bad escape sequence in string"); - goto string_fail1; - } - - l += 2 + extra; - } - else if (str[l] == '"') { - break; - } - else { - dec_ch = str[l]; - l++; - } - - // append character to string - if (!ExpString_AppendByte(&estr, dec_ch)) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto string_fail1; - } - } - - // make sure ending quote was found - if (l == left) { - BLog(BLOG_ERROR, "missing ending quote for string"); - goto string_fail1; - } - - // skip ending quote - l++; - - token = NCD_TOKEN_STRING; - token_val = ExpString_Get(&estr); - token_len = ExpString_Length(&estr); - break; - - string_fail1: - ExpString_Free(&estr); - string_fail0: - error = 1; - } while (0); - else if (is_space_char(*str)) { - token = 0; - l = 1; - } - else { - BLog(BLOG_ERROR, "unrecognized character"); - error = 1; - } - - out: - // report error - if (error) { - output(user, NCD_ERROR, NULL, 0, line, line_char); - return; - } - - // output token - if (token) { - if (!output(user, token, token_val, token_len, line, line_char)) { - return; - } - } - - // update line/char counters - for (size_t i = 0; i < l; i++) { - if (str[i] == '\n') { - line++; - line_char = 1; - } else { - line_char++; - } - } - - str += l; - left -= l; - } - - output(user, NCD_EOF, NULL, 0, line, line_char); -} diff --git a/external/badvpn_dns/ncd/NCDConfigTokenizer.h b/external/badvpn_dns/ncd/NCDConfigTokenizer.h deleted file mode 100644 index 38edfad..0000000 --- a/external/badvpn_dns/ncd/NCDConfigTokenizer.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file NCDConfigTokenizer.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDCONFIG_NCDCONFIGTOKENIZER_H -#define BADVPN_NCDCONFIG_NCDCONFIGTOKENIZER_H - -#include <stdlib.h> - -#define NCD_ERROR -1 -#define NCD_EOF 0 -#define NCD_TOKEN_CURLY_OPEN 1 -#define NCD_TOKEN_CURLY_CLOSE 2 -#define NCD_TOKEN_ROUND_OPEN 3 -#define NCD_TOKEN_ROUND_CLOSE 4 -#define NCD_TOKEN_SEMICOLON 5 -#define NCD_TOKEN_DOT 6 -#define NCD_TOKEN_COMMA 7 -#define NCD_TOKEN_PROCESS 8 -#define NCD_TOKEN_NAME 9 -#define NCD_TOKEN_STRING 10 -#define NCD_TOKEN_ARROW 11 -#define NCD_TOKEN_TEMPLATE 12 -#define NCD_TOKEN_COLON 13 -#define NCD_TOKEN_BRACKET_OPEN 14 -#define NCD_TOKEN_BRACKET_CLOSE 15 -#define NCD_TOKEN_IF 16 -#define NCD_TOKEN_ELIF 17 -#define NCD_TOKEN_ELSE 18 -#define NCD_TOKEN_FOREACH 19 -#define NCD_TOKEN_AS 20 -#define NCD_TOKEN_INCLUDE 21 -#define NCD_TOKEN_INCLUDE_GUARD 22 - -typedef int (*NCDConfigTokenizer_output) (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char); - -void NCDConfigTokenizer_Tokenize (char *str, size_t str_len, NCDConfigTokenizer_output output, void *user); - -#endif diff --git a/external/badvpn_dns/ncd/NCDInterpProcess.c b/external/badvpn_dns/ncd/NCDInterpProcess.c deleted file mode 100644 index 4462ea6..0000000 --- a/external/badvpn_dns/ncd/NCDInterpProcess.c +++ /dev/null @@ -1,497 +0,0 @@ -/** - * @file NCDInterpProcess.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <limits.h> -#include <string.h> -#include <stdlib.h> - -#include <misc/balloc.h> -#include <misc/maxalign.h> -#include <misc/strdup.h> -#include <base/BLog.h> -#include <ncd/make_name_indices.h> - -#include "NCDInterpProcess.h" - -#include <generated/blog_channel_ncd.h> - -static int compute_prealloc (NCDInterpProcess *o) -{ - int size = 0; - - for (int i = 0; i < o->num_stmts; i++) { - int mod = size % BMAX_ALIGN; - int align_size = (mod == 0 ? 0 : BMAX_ALIGN - mod); - - if (align_size + o->stmts[i].alloc_size > INT_MAX - size) { - return 0; - } - - o->stmts[i].prealloc_offset = size + align_size; - size += align_size + o->stmts[i].alloc_size; - } - - ASSERT(size >= 0) - - o->prealloc_size = size; - - return 1; -} - -static int convert_value_recurser (NCDPlaceholderDb *pdb, NCDStringIndex *string_index, NCDValue *value, NCDValMem *mem, NCDValRef *out) -{ - ASSERT(pdb) - ASSERT(string_index) - ASSERT((NCDValue_Type(value), 1)) - ASSERT(mem) - ASSERT(out) - - switch (NCDValue_Type(value)) { - case NCDVALUE_STRING: { - const char *str = NCDValue_StringValue(value); - size_t len = NCDValue_StringLength(value); - - NCD_string_id_t string_id = NCDStringIndex_GetBin(string_index, str, len); - if (string_id < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_GetBin failed"); - goto fail; - } - - *out = NCDVal_NewIdString(mem, string_id, string_index); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - } break; - - case NCDVALUE_LIST: { - *out = NCDVal_NewList(mem, NCDValue_ListCount(value)); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - - for (NCDValue *e = NCDValue_ListFirst(value); e; e = NCDValue_ListNext(value, e)) { - NCDValRef vval; - if (!convert_value_recurser(pdb, string_index, e, mem, &vval)) { - goto fail; - } - - if (!NCDVal_ListAppend(*out, vval)) { - BLog(BLOG_ERROR, "depth limit exceeded"); - goto fail; - } - } - } break; - - case NCDVALUE_MAP: { - *out = NCDVal_NewMap(mem, NCDValue_MapCount(value)); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - - for (NCDValue *ekey = NCDValue_MapFirstKey(value); ekey; ekey = NCDValue_MapNextKey(value, ekey)) { - NCDValue *eval = NCDValue_MapKeyValue(value, ekey); - - NCDValRef vkey; - NCDValRef vval; - if (!convert_value_recurser(pdb, string_index, ekey, mem, &vkey) || - !convert_value_recurser(pdb, string_index, eval, mem, &vval) - ) { - goto fail; - } - - int inserted; - if (!NCDVal_MapInsert(*out, vkey, vval, &inserted)) { - BLog(BLOG_ERROR, "depth limit exceeded"); - goto fail; - } - if (!inserted) { - BLog(BLOG_ERROR, "duplicate key in map"); - goto fail; - } - } - } break; - - case NCDVALUE_VAR: { - int plid; - if (!NCDPlaceholderDb_AddVariable(pdb, NCDValue_VarName(value), &plid)) { - goto fail; - } - - if (NCDVAL_MINIDX + plid >= -1) { - goto fail; - } - - *out = NCDVal_NewPlaceholder(mem, plid); - } break; - - default: - goto fail; - } - - return 1; - -fail: - return 0; -} - -int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIndex *string_index, NCDPlaceholderDb *pdb, NCDModuleIndex *module_index) -{ - ASSERT(process) - ASSERT(string_index) - ASSERT(pdb) - ASSERT(module_index) - - NCDBlock *block = NCDProcess_Block(process); - - if (NCDBlock_NumStatements(block) > INT_MAX) { - BLog(BLOG_ERROR, "too many statements"); - goto fail0; - } - int num_stmts = NCDBlock_NumStatements(block); - - if (!(o->stmts = BAllocArray(num_stmts, sizeof(o->stmts[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - o->num_hash_buckets = num_stmts; - - if (!(o->hash_buckets = BAllocArray(o->num_hash_buckets, sizeof(o->hash_buckets[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail1; - } - - for (size_t i = 0; i < o->num_hash_buckets; i++) { - o->hash_buckets[i] = -1; - } - - if (!(o->name = b_strdup(NCDProcess_Name(process)))) { - BLog(BLOG_ERROR, "b_strdup failed"); - goto fail2; - } - - o->num_stmts = 0; - o->prealloc_size = -1; - o->is_template = NCDProcess_IsTemplate(process); - o->cache = NULL; - - for (NCDStatement *s = NCDBlock_FirstStatement(block); s; s = NCDBlock_NextStatement(block, s)) { - ASSERT(NCDStatement_Type(s) == NCDSTATEMENT_REG) - struct NCDInterpProcess__stmt *e = &o->stmts[o->num_stmts]; - - e->name = -1; - e->objnames = NULL; - e->num_objnames = 0; - e->alloc_size = 0; - - if (NCDStatement_Name(s)) { - e->name = NCDStringIndex_Get(string_index, NCDStatement_Name(s)); - if (e->name < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto loop_fail0; - } - } - - e->cmdname = NCDStringIndex_Get(string_index, NCDStatement_RegCmdName(s)); - if (e->cmdname < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto loop_fail0; - } - - NCDValMem_Init(&e->arg_mem); - - NCDValRef val; - if (!convert_value_recurser(pdb, string_index, NCDStatement_RegArgs(s), &e->arg_mem, &val)) { - BLog(BLOG_ERROR, "convert_value_recurser failed"); - goto loop_fail1; - } - - e->arg_ref = NCDVal_ToSafe(val); - - if (!NCDValReplaceProg_Init(&e->arg_prog, val)) { - BLog(BLOG_ERROR, "NCDValReplaceProg_Init failed"); - goto loop_fail1; - } - - if (NCDStatement_RegObjName(s)) { - if (!ncd_make_name_indices(string_index, NCDStatement_RegObjName(s), &e->objnames, &e->num_objnames)) { - BLog(BLOG_ERROR, "ncd_make_name_indices failed"); - goto loop_fail2; - } - - e->binding.method_name_id = NCDModuleIndex_GetMethodNameId(module_index, NCDStatement_RegCmdName(s)); - if (e->binding.method_name_id == -1) { - BLog(BLOG_ERROR, "NCDModuleIndex_GetMethodNameId failed"); - goto loop_fail3; - } - } else { - e->binding.simple_module = NCDModuleIndex_FindModule(module_index, NCDStatement_RegCmdName(s)); - } - - if (e->name >= 0) { - size_t bucket_idx = e->name % o->num_hash_buckets; - e->hash_next = o->hash_buckets[bucket_idx]; - o->hash_buckets[bucket_idx] = o->num_stmts; - } - - o->num_stmts++; - continue; - - loop_fail3: - BFree(e->objnames); - loop_fail2: - NCDValReplaceProg_Free(&e->arg_prog); - loop_fail1: - NCDValMem_Free(&e->arg_mem); - loop_fail0: - goto fail3; - } - - ASSERT(o->num_stmts == num_stmts) - - DebugObject_Init(&o->d_obj); - return 1; - -fail3: - while (o->num_stmts-- > 0) { - struct NCDInterpProcess__stmt *e = &o->stmts[o->num_stmts]; - BFree(e->objnames); - NCDValReplaceProg_Free(&e->arg_prog); - NCDValMem_Free(&e->arg_mem); - } - free(o->name); -fail2: - BFree(o->hash_buckets); -fail1: - BFree(o->stmts); -fail0: - return 0; -} - -void NCDInterpProcess_Free (NCDInterpProcess *o) -{ - DebugObject_Free(&o->d_obj); - - while (o->num_stmts-- > 0) { - struct NCDInterpProcess__stmt *e = &o->stmts[o->num_stmts]; - BFree(e->objnames); - NCDValReplaceProg_Free(&e->arg_prog); - NCDValMem_Free(&e->arg_mem); - } - - free(o->name); - BFree(o->hash_buckets); - BFree(o->stmts); -} - -int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, NCD_string_id_t name) -{ - DebugObject_Access(&o->d_obj); - ASSERT(from_index >= 0) - ASSERT(from_index <= o->num_stmts) - - size_t bucket_idx = name % o->num_hash_buckets; - int stmt_idx = o->hash_buckets[bucket_idx]; - ASSERT(stmt_idx >= -1) - ASSERT(stmt_idx < o->num_stmts) - - while (stmt_idx >= 0) { - if (stmt_idx < from_index && o->stmts[stmt_idx].name == name) { - return stmt_idx; - } - - stmt_idx = o->stmts[stmt_idx].hash_next; - ASSERT(stmt_idx >= -1) - ASSERT(stmt_idx < o->num_stmts) - } - - return -1; -} - -const char * NCDInterpProcess_StatementCmdName (NCDInterpProcess *o, int i, NCDStringIndex *string_index) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(string_index) - - return NCDStringIndex_Value(string_index, o->stmts[i].cmdname); -} - -void NCDInterpProcess_StatementObjNames (NCDInterpProcess *o, int i, const NCD_string_id_t **out_objnames, size_t *out_num_objnames) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(out_objnames) - ASSERT(out_num_objnames) - - *out_objnames = o->stmts[i].objnames; - *out_num_objnames = o->stmts[i].num_objnames; -} - -const struct NCDInterpModule * NCDInterpProcess_StatementGetSimpleModule (NCDInterpProcess *o, int i, NCDStringIndex *string_index, NCDModuleIndex *module_index) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(!o->stmts[i].objnames) - - struct NCDInterpProcess__stmt *e = &o->stmts[i]; - - if (!e->binding.simple_module) { - const char *cmdname = NCDStringIndex_Value(string_index, e->cmdname); - e->binding.simple_module = NCDModuleIndex_FindModule(module_index, cmdname); - } - - return e->binding.simple_module; -} - -const struct NCDInterpModule * NCDInterpProcess_StatementGetMethodModule (NCDInterpProcess *o, int i, NCD_string_id_t obj_type, NCDModuleIndex *module_index) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(o->stmts[i].objnames) - ASSERT(obj_type >= 0) - ASSERT(module_index) - - return NCDModuleIndex_GetMethodModule(module_index, obj_type, o->stmts[i].binding.method_name_id); -} - -int NCDInterpProcess_CopyStatementArgs (NCDInterpProcess *o, int i, NCDValMem *out_valmem, NCDValRef *out_val, NCDValReplaceProg *out_prog) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(out_valmem) - ASSERT(out_val) - ASSERT(out_prog) - - struct NCDInterpProcess__stmt *e = &o->stmts[i]; - - if (!NCDValMem_InitCopy(out_valmem, &e->arg_mem)) { - return 0; - } - - *out_val = NCDVal_FromSafe(out_valmem, e->arg_ref); - *out_prog = e->arg_prog; - return 1; -} - -void NCDInterpProcess_StatementBumpAllocSize (NCDInterpProcess *o, int i, int alloc_size) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(alloc_size >= 0) - - if (alloc_size > o->stmts[i].alloc_size) { - o->stmts[i].alloc_size = alloc_size; - o->prealloc_size = -1; - } -} - -int NCDInterpProcess_PreallocSize (NCDInterpProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->prealloc_size == -1 || o->prealloc_size >= 0) - - if (o->prealloc_size < 0 && !compute_prealloc(o)) { - return -1; - } - - return o->prealloc_size; -} - -int NCDInterpProcess_StatementPreallocSize (NCDInterpProcess *o, int i) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(o->prealloc_size >= 0) - - return o->stmts[i].alloc_size; -} - -int NCDInterpProcess_StatementPreallocOffset (NCDInterpProcess *o, int i) -{ - DebugObject_Access(&o->d_obj); - ASSERT(i >= 0) - ASSERT(i < o->num_stmts) - ASSERT(o->prealloc_size >= 0) - - return o->stmts[i].prealloc_offset; -} - -const char * NCDInterpProcess_Name (NCDInterpProcess *o) -{ - DebugObject_Access(&o->d_obj); - - return o->name; -} - -int NCDInterpProcess_IsTemplate (NCDInterpProcess *o) -{ - DebugObject_Access(&o->d_obj); - - return o->is_template; -} - -int NCDInterpProcess_NumStatements (NCDInterpProcess *o) -{ - DebugObject_Access(&o->d_obj); - - return o->num_stmts; -} - -int NCDInterpProcess_CachePush (NCDInterpProcess *o, void *elem) -{ - DebugObject_Access(&o->d_obj); - ASSERT(elem) - - if (o->cache) { - return 0; - } - - o->cache = elem; - - return 1; -} - -void * NCDInterpProcess_CachePull (NCDInterpProcess *o) -{ - DebugObject_Access(&o->d_obj); - - void *elem = o->cache; - o->cache = NULL; - - return elem; -} diff --git a/external/badvpn_dns/ncd/NCDInterpProcess.h b/external/badvpn_dns/ncd/NCDInterpProcess.h deleted file mode 100644 index 49fd2c6..0000000 --- a/external/badvpn_dns/ncd/NCDInterpProcess.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file NCDInterpProcess.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDINTERPPROCESS_H -#define BADVPN_NCDINTERPPROCESS_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <ncd/NCDAst.h> -#include <ncd/NCDVal.h> -#include <ncd/NCDPlaceholderDb.h> -#include <ncd/NCDModule.h> -#include <ncd/NCDModuleIndex.h> -#include <ncd/NCDStringIndex.h> - -struct NCDInterpProcess__stmt { - NCD_string_id_t name; - NCD_string_id_t cmdname; - NCD_string_id_t *objnames; - size_t num_objnames; - union { - const struct NCDInterpModule *simple_module; - int method_name_id; - } binding; - NCDValMem arg_mem; - NCDValSafeRef arg_ref; - NCDValReplaceProg arg_prog; - int alloc_size; - int prealloc_offset; - int hash_next; -}; - -/** - * A data structure which contains information about a process or - * template, suitable for efficient interpretation. These structures - * are built at startup from the program AST for all processes and - * templates by \link NCDInterpProg. They are not modified after - * the program is loaded Inn case of template processes, the same - * NCDInterpProcess is shared by all processes created from the same - * template. - */ -typedef struct { - struct NCDInterpProcess__stmt *stmts; - char *name; - int num_stmts; - int prealloc_size; - int is_template; - int *hash_buckets; - size_t num_hash_buckets; - void *cache; - DebugObject d_obj; -} NCDInterpProcess; - -int NCDInterpProcess_Init (NCDInterpProcess *o, NCDProcess *process, NCDStringIndex *string_index, NCDPlaceholderDb *pdb, NCDModuleIndex *module_index) WARN_UNUSED; -void NCDInterpProcess_Free (NCDInterpProcess *o); -int NCDInterpProcess_FindStatement (NCDInterpProcess *o, int from_index, NCD_string_id_t name); -const char * NCDInterpProcess_StatementCmdName (NCDInterpProcess *o, int i, NCDStringIndex *string_index); -void NCDInterpProcess_StatementObjNames (NCDInterpProcess *o, int i, const NCD_string_id_t **out_objnames, size_t *out_num_objnames); -const struct NCDInterpModule * NCDInterpProcess_StatementGetSimpleModule (NCDInterpProcess *o, int i, NCDStringIndex *string_index, NCDModuleIndex *module_index); -const struct NCDInterpModule * NCDInterpProcess_StatementGetMethodModule (NCDInterpProcess *o, int i, NCD_string_id_t obj_type, NCDModuleIndex *module_index); -int NCDInterpProcess_CopyStatementArgs (NCDInterpProcess *o, int i, NCDValMem *out_valmem, NCDValRef *out_val, NCDValReplaceProg *out_prog) WARN_UNUSED; -void NCDInterpProcess_StatementBumpAllocSize (NCDInterpProcess *o, int i, int alloc_size); -int NCDInterpProcess_PreallocSize (NCDInterpProcess *o); -int NCDInterpProcess_StatementPreallocSize (NCDInterpProcess *o, int i); -int NCDInterpProcess_StatementPreallocOffset (NCDInterpProcess *o, int i); -const char * NCDInterpProcess_Name (NCDInterpProcess *o); -int NCDInterpProcess_IsTemplate (NCDInterpProcess *o); -int NCDInterpProcess_NumStatements (NCDInterpProcess *o); -int NCDInterpProcess_CachePush (NCDInterpProcess *o, void *elem) WARN_UNUSED; -void * NCDInterpProcess_CachePull (NCDInterpProcess *o); - -#endif diff --git a/external/badvpn_dns/ncd/NCDInterpProg.c b/external/badvpn_dns/ncd/NCDInterpProg.c deleted file mode 100644 index 7ee75de..0000000 --- a/external/badvpn_dns/ncd/NCDInterpProg.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file NCDInterpProg.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <limits.h> - -#include <misc/balloc.h> -#include <misc/hashfun.h> -#include <base/BLog.h> - -#include "NCDInterpProg.h" - -#include <generated/blog_channel_ncd.h> - -#include "NCDInterpProg_hash.h" -#include <structure/CHash_impl.h> - -int NCDInterpProg_Init (NCDInterpProg *o, NCDProgram *prog, NCDStringIndex *string_index, NCDPlaceholderDb *pdb, NCDModuleIndex *module_index) -{ - ASSERT(prog) - ASSERT(!NCDProgram_ContainsElemType(prog, NCDPROGRAMELEM_INCLUDE)) - ASSERT(!NCDProgram_ContainsElemType(prog, NCDPROGRAMELEM_INCLUDE_GUARD)) - ASSERT(string_index) - ASSERT(pdb) - ASSERT(module_index) - - if (NCDProgram_NumElems(prog) > INT_MAX) { - BLog(BLOG_ERROR, "too many processes"); - goto fail0; - } - int num_procs = NCDProgram_NumElems(prog); - - if (!(o->procs = BAllocArray(num_procs, sizeof(o->procs[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - if (!NCDInterpProg__Hash_Init(&o->hash, num_procs)) { - BLog(BLOG_ERROR, "NCDInterpProg__Hash_Init failed"); - goto fail1; - } - - o->num_procs = 0; - - for (NCDProgramElem *elem = NCDProgram_FirstElem(prog); elem; elem = NCDProgram_NextElem(prog, elem)) { - ASSERT(NCDProgramElem_Type(elem) == NCDPROGRAMELEM_PROCESS) - NCDProcess *p = NCDProgramElem_Process(elem); - - struct NCDInterpProg__process *e = &o->procs[o->num_procs]; - - e->name = NCDStringIndex_Get(string_index, NCDProcess_Name(p)); - if (e->name < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto fail2; - } - - if (!NCDInterpProcess_Init(&e->iprocess, p, string_index, pdb, module_index)) { - BLog(BLOG_ERROR, "NCDInterpProcess_Init failed"); - goto fail2; - } - - NCDInterpProg__HashRef ref = {e, o->num_procs}; - if (!NCDInterpProg__Hash_Insert(&o->hash, o->procs, ref, NULL)) { - BLog(BLOG_ERROR, "duplicate process or template name: %s", NCDProcess_Name(p)); - NCDInterpProcess_Free(&e->iprocess); - goto fail2; - } - - o->num_procs++; - } - - ASSERT(o->num_procs == num_procs) - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - while (o->num_procs-- > 0) { - NCDInterpProcess_Free(&o->procs[o->num_procs].iprocess); - } - NCDInterpProg__Hash_Free(&o->hash); -fail1: - BFree(o->procs); -fail0: - return 0; -} - -void NCDInterpProg_Free (NCDInterpProg *o) -{ - DebugObject_Free(&o->d_obj); - - while (o->num_procs-- > 0) { - NCDInterpProcess_Free(&o->procs[o->num_procs].iprocess); - } - - NCDInterpProg__Hash_Free(&o->hash); - - BFree(o->procs); -} - -NCDInterpProcess * NCDInterpProg_FindProcess (NCDInterpProg *o, NCD_string_id_t name) -{ - DebugObject_Access(&o->d_obj); - ASSERT(name >= 0) - - NCDInterpProg__HashRef ref = NCDInterpProg__Hash_Lookup(&o->hash, o->procs, name); - if (ref.link == NCDInterpProg__HashNullLink()) { - return NULL; - } - - ASSERT(ref.ptr->name == name) - - return &ref.ptr->iprocess; -} diff --git a/external/badvpn_dns/ncd/NCDInterpProg.h b/external/badvpn_dns/ncd/NCDInterpProg.h deleted file mode 100644 index 2c8aaff..0000000 --- a/external/badvpn_dns/ncd/NCDInterpProg.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file NCDInterpProg.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDINTERPPROG_H -#define BADVPN_NCDINTERPPROG_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <ncd/NCDAst.h> -#include <ncd/NCDInterpProcess.h> -#include <ncd/NCDStringIndex.h> -#include <structure/CHash.h> - -struct NCDInterpProg__process { - NCD_string_id_t name; - NCDInterpProcess iprocess; - int hash_next; -}; - -typedef struct NCDInterpProg__process NCDInterpProg__hashentry; -typedef struct NCDInterpProg__process *NCDInterpProg__hasharg; - -#include "NCDInterpProg_hash.h" -#include <structure/CHash_decl.h> - -typedef struct { - struct NCDInterpProg__process *procs; - int num_procs; - NCDInterpProg__Hash hash; - DebugObject d_obj; -} NCDInterpProg; - -int NCDInterpProg_Init (NCDInterpProg *o, NCDProgram *prog, NCDStringIndex *string_index, NCDPlaceholderDb *pdb, NCDModuleIndex *module_index) WARN_UNUSED; -void NCDInterpProg_Free (NCDInterpProg *o); -NCDInterpProcess * NCDInterpProg_FindProcess (NCDInterpProg *o, NCD_string_id_t name); - -#endif diff --git a/external/badvpn_dns/ncd/NCDInterpProg_hash.h b/external/badvpn_dns/ncd/NCDInterpProg_hash.h deleted file mode 100644 index fa8898e..0000000 --- a/external/badvpn_dns/ncd/NCDInterpProg_hash.h +++ /dev/null @@ -1,12 +0,0 @@ -#define CHASH_PARAM_NAME NCDInterpProg__Hash -#define CHASH_PARAM_ENTRY NCDInterpProg__hashentry -#define CHASH_PARAM_LINK int -#define CHASH_PARAM_KEY NCD_string_id_t -#define CHASH_PARAM_ARG NCDInterpProg__hasharg -#define CHASH_PARAM_NULL ((int)-1) -#define CHASH_PARAM_DEREF(arg, link) (&(arg)[(link)]) -#define CHASH_PARAM_ENTRYHASH(arg, entry) ((size_t)(entry).ptr->name) -#define CHASH_PARAM_KEYHASH(arg, key) ((size_t)(key)) -#define CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) ((entry1).ptr->name == (entry2).ptr->name) -#define CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) ((key1) == (entry2).ptr->name) -#define CHASH_PARAM_ENTRY_NEXT hash_next diff --git a/external/badvpn_dns/ncd/NCDInterpreter.c b/external/badvpn_dns/ncd/NCDInterpreter.c deleted file mode 100644 index dc05cc5..0000000 --- a/external/badvpn_dns/ncd/NCDInterpreter.c +++ /dev/null @@ -1,1356 +0,0 @@ -/** - * @file NCDInterpreter.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <string.h> -#include <stdlib.h> -#include <limits.h> -#include <stdarg.h> - -#include <misc/offset.h> -#include <misc/balloc.h> -#include <misc/expstring.h> -#include <base/BLog.h> -#include <ncd/NCDSugar.h> -#include <ncd/modules/modules.h> - -#include "NCDInterpreter.h" - -#include <generated/blog_channel_ncd.h> - -#define SSTATE_CHILD 0 -#define SSTATE_ADULT 1 -#define SSTATE_DYING 2 -#define SSTATE_FORGOTTEN 3 - -#define PSTATE_WORKING 0 -#define PSTATE_UP 1 -#define PSTATE_WAITING 2 -#define PSTATE_TERMINATING 3 - -struct statement { - NCDModuleInst inst; - NCDValMem args_mem; - int mem_size; - int i; -}; - -struct process { - NCDInterpreter *interp; - BReactor *reactor; - NCDInterpProcess *iprocess; - NCDModuleProcess *module_process; - BSmallTimer wait_timer; - BSmallPending work_job; - LinkedList1Node list_node; // node in processes - int ap; - int fp; - int num_statements; - unsigned int error:1; - unsigned int have_alloc:1; -#ifndef NDEBUG - int state; -#endif - struct statement statements[]; -}; - -static void start_terminate (NCDInterpreter *interp, int exit_code); -static char * implode_id_strings (NCDInterpreter *interp, const NCD_string_id_t *names, size_t num_names, char del); -static void clear_process_cache (NCDInterpreter *interp); -static struct process * process_allocate (NCDInterpreter *interp, NCDInterpProcess *iprocess); -static void process_release (struct process *p, int no_push); -static void process_assert_statements_cleared (struct process *p); -static int process_new (NCDInterpreter *interp, NCDInterpProcess *iprocess, NCDModuleProcess *module_process); -static void process_free (struct process *p, NCDModuleProcess **out_mp); -static void process_set_state (struct process *p, int state); -static void process_start_terminating (struct process *p); -static int process_have_child (struct process *p); -static void process_assert_pointers (struct process *p); -static void process_logfunc (struct process *p); -static void process_log (struct process *p, int level, const char *fmt, ...); -static void process_work_job_handler_working (struct process *p); -static void process_work_job_handler_up (struct process *p); -static void process_work_job_handler_waiting (struct process *p); -static void process_work_job_handler_terminating (struct process *p); -static int replace_placeholders_callback (void *arg, int plid, NCDValMem *mem, NCDValRef *out); -static void process_advance (struct process *p); -static void process_wait_timer_handler (BSmallTimer *timer); -static int process_find_object (struct process *p, int pos, NCD_string_id_t name, NCDObject *out_object); -static int process_resolve_object_expr (struct process *p, int pos, const NCD_string_id_t *names, size_t num_names, NCDObject *out_object); -static int process_resolve_variable_expr (struct process *p, int pos, const NCD_string_id_t *names, size_t num_names, NCDValMem *mem, NCDValRef *out_value); -static void statement_logfunc (struct statement *ps); -static void statement_log (struct statement *ps, int level, const char *fmt, ...); -static struct process * statement_process (struct statement *ps); -static int statement_mem_is_allocated (struct statement *ps); -static int statement_mem_size (struct statement *ps); -static int statement_allocate_memory (struct statement *ps, int alloc_size); -static void statement_instance_func_event (NCDModuleInst *inst, int event); -static int statement_instance_func_getobj (NCDModuleInst *inst, NCD_string_id_t objname, NCDObject *out_object); -static int statement_instance_func_initprocess (void *vinterp, NCDModuleProcess *mp, NCD_string_id_t template_name); -static void statement_instance_logfunc (NCDModuleInst *inst); -static void statement_instance_func_interp_exit (void *vinterp, int exit_code); -static int statement_instance_func_interp_getargs (void *vinterp, NCDValMem *mem, NCDValRef *out_value); -static btime_t statement_instance_func_interp_getretrytime (void *vinterp); -static int statement_instance_func_interp_loadgroup (void *vinterp, const struct NCDModuleGroup *group); -static void process_moduleprocess_func_event (struct process *p, int event); -static int process_moduleprocess_func_getobj (struct process *p, NCD_string_id_t name, NCDObject *out_object); - -#define STATEMENT_LOG(ps, channel, ...) if (BLog_WouldLog(BLOG_CURRENT_CHANNEL, channel)) statement_log(ps, channel, __VA_ARGS__) - -int NCDInterpreter_Init (NCDInterpreter *o, NCDProgram program, struct NCDInterpreter_params params) -{ - ASSERT(!NCDProgram_ContainsElemType(&program, NCDPROGRAMELEM_INCLUDE)); - ASSERT(!NCDProgram_ContainsElemType(&program, NCDPROGRAMELEM_INCLUDE_GUARD)); - ASSERT(params.handler_finished); - ASSERT(params.num_extra_args >= 0); - ASSERT(params.reactor); -#ifndef BADVPN_NO_PROCESS - ASSERT(params.manager); -#endif -#ifndef BADVPN_NO_UDEV - ASSERT(params.umanager); -#endif -#ifndef BADVPN_NO_RANDOM - ASSERT(params.random2); -#endif - - // set params - o->params = params; - - // set not terminating - o->terminating = 0; - - // set program - o->program = program; - - // init string index - if (!NCDStringIndex_Init(&o->string_index)) { - BLog(BLOG_ERROR, "NCDStringIndex_Init failed"); - goto fail0; - } - - // init module index - if (!NCDModuleIndex_Init(&o->mindex, &o->string_index)) { - BLog(BLOG_ERROR, "NCDModuleIndex_Init failed"); - goto fail2; - } - - // init pointers to global resources in out struct NCDModuleInst_iparams. - // Don't initialize any callback at this point as these must not be called - // from globalinit functions of modules. - o->module_iparams.reactor = params.reactor; -#ifndef BADVPN_NO_PROCESS - o->module_iparams.manager = params.manager; -#endif -#ifndef BADVPN_NO_UDEV - o->module_iparams.umanager = params.umanager; -#endif -#ifndef BADVPN_NO_RANDOM - o->module_iparams.random2 = params.random2; -#endif - o->module_iparams.string_index = &o->string_index; - - // add module groups to index and allocate string id's for base_type's - for (const struct NCDModuleGroup **g = ncd_modules; *g; g++) { - if (!NCDModuleIndex_AddGroup(&o->mindex, *g, &o->module_iparams, &o->string_index)) { - BLog(BLOG_ERROR, "NCDModuleIndex_AddGroup failed"); - goto fail3; - } - } - - // desugar - if (!NCDSugar_Desugar(&o->program)) { - BLog(BLOG_ERROR, "NCDSugar_Desugar failed"); - goto fail3; - } - - // init placeholder database - if (!NCDPlaceholderDb_Init(&o->placeholder_db, &o->string_index)) { - BLog(BLOG_ERROR, "NCDPlaceholderDb_Init failed"); - goto fail3; - } - - // init interp program - if (!NCDInterpProg_Init(&o->iprogram, &o->program, &o->string_index, &o->placeholder_db, &o->mindex)) { - BLog(BLOG_ERROR, "NCDInterpProg_Init failed"); - goto fail5; - } - - // init the rest of the module parameters structures - o->module_params.func_event = statement_instance_func_event; - o->module_params.func_getobj = statement_instance_func_getobj; - o->module_params.logfunc = (BLog_logfunc)statement_instance_logfunc; - o->module_params.iparams = &o->module_iparams; - o->module_iparams.user = o; - o->module_iparams.func_initprocess = statement_instance_func_initprocess; - o->module_iparams.func_interp_exit = statement_instance_func_interp_exit; - o->module_iparams.func_interp_getargs = statement_instance_func_interp_getargs; - o->module_iparams.func_interp_getretrytime = statement_instance_func_interp_getretrytime; - o->module_iparams.func_loadgroup = statement_instance_func_interp_loadgroup; - - // init processes list - LinkedList1_Init(&o->processes); - - // init processes - for (NCDProgramElem *elem = NCDProgram_FirstElem(&o->program); elem; elem = NCDProgram_NextElem(&o->program, elem)) { - ASSERT(NCDProgramElem_Type(elem) == NCDPROGRAMELEM_PROCESS) - NCDProcess *p = NCDProgramElem_Process(elem); - - if (NCDProcess_IsTemplate(p)) { - continue; - } - - // get string id for process name - NCD_string_id_t name_id = NCDStringIndex_Lookup(&o->string_index, NCDProcess_Name(p)); - ASSERT(name_id >= 0) - - // find iprocess - NCDInterpProcess *iprocess = NCDInterpProg_FindProcess(&o->iprogram, name_id); - ASSERT(iprocess) - - if (!process_new(o, iprocess, NULL)) { - BLog(BLOG_ERROR, "failed to initialize process, exiting"); - goto fail7; - } - } - - DebugObject_Init(&o->d_obj); - return 1; - -fail7:; - // free processes - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->processes)) { - struct process *p = UPPER_OBJECT(ln, struct process, list_node); - BSmallPending_Unset(&p->work_job, BReactor_PendingGroup(o->params.reactor)); - NCDModuleProcess *mp; - process_free(p, &mp); - ASSERT(!mp) - } - // clear process cache (process_free() above may push to cache) - clear_process_cache(o); - // free interp program - NCDInterpProg_Free(&o->iprogram); -fail5: - // free placeholder database - NCDPlaceholderDb_Free(&o->placeholder_db); -fail3: - // free module index - NCDModuleIndex_Free(&o->mindex); -fail2: - // free string index - NCDStringIndex_Free(&o->string_index); -fail0: - // free program AST - NCDProgram_Free(&o->program); - return 0; -} - -void NCDInterpreter_Free (NCDInterpreter *o) -{ - DebugObject_Free(&o->d_obj); - // any process that exists must be completely uninitialized - - // free processes - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->processes)) { - struct process *p = UPPER_OBJECT(ln, struct process, list_node); - BSmallPending_Unset(&p->work_job, BReactor_PendingGroup(o->params.reactor)); - NCDModuleProcess *mp; - process_free(p, &mp); - ASSERT(!mp) - } - - // clear process cache - clear_process_cache(o); - - // free interp program - NCDInterpProg_Free(&o->iprogram); - - // free placeholder database - NCDPlaceholderDb_Free(&o->placeholder_db); - - // free module index - NCDModuleIndex_Free(&o->mindex); - - // free string index - NCDStringIndex_Free(&o->string_index); - - // free program AST - NCDProgram_Free(&o->program); -} - -void NCDInterpreter_RequestShutdown (NCDInterpreter *o, int exit_code) -{ - DebugObject_Access(&o->d_obj); - - start_terminate(o, exit_code); -} - -void start_terminate (NCDInterpreter *interp, int exit_code) -{ - // remember exit code - interp->main_exit_code = exit_code; - - // if we're already terminating, there's nothing to do - if (interp->terminating) { - return; - } - - // set the terminating flag - interp->terminating = 1; - - // if there are no processes, we're done - if (LinkedList1_IsEmpty(&interp->processes)) { - interp->params.handler_finished(interp->params.user, interp->main_exit_code); - return; - } - - // start terminating non-template processes - for (LinkedList1Node *ln = LinkedList1_GetFirst(&interp->processes); ln; ln = LinkedList1Node_Next(ln)) { - struct process *p = UPPER_OBJECT(ln, struct process, list_node); - if (p->module_process) { - continue; - } - process_start_terminating(p); - } -} - -char * implode_id_strings (NCDInterpreter *interp, const NCD_string_id_t *names, size_t num_names, char del) -{ - ExpString str; - if (!ExpString_Init(&str)) { - goto fail0; - } - - int is_first = 1; - - while (num_names > 0) { - if (!is_first && !ExpString_AppendChar(&str, del)) { - goto fail1; - } - const char *name_str = NCDStringIndex_Value(&interp->string_index, *names); - if (!ExpString_Append(&str, name_str)) { - goto fail1; - } - names++; - num_names--; - is_first = 0; - } - - return ExpString_Get(&str); - -fail1: - ExpString_Free(&str); -fail0: - return NULL; -} - -void clear_process_cache (NCDInterpreter *interp) -{ - for (NCDProgramElem *elem = NCDProgram_FirstElem(&interp->program); elem; elem = NCDProgram_NextElem(&interp->program, elem)) { - ASSERT(NCDProgramElem_Type(elem) == NCDPROGRAMELEM_PROCESS) - NCDProcess *ast_p = NCDProgramElem_Process(elem); - - NCD_string_id_t name_id = NCDStringIndex_Lookup(&interp->string_index, NCDProcess_Name(ast_p)); - NCDInterpProcess *iprocess = NCDInterpProg_FindProcess(&interp->iprogram, name_id); - - struct process *p; - while (p = NCDInterpProcess_CachePull(iprocess)) { - process_release(p, 1); - } - } -} - -struct process * process_allocate (NCDInterpreter *interp, NCDInterpProcess *iprocess) -{ - ASSERT(iprocess) - - // try to pull from cache - struct process *p = NCDInterpProcess_CachePull(iprocess); - if (p) { - goto allocated; - } - - // get number of statements - int num_statements = NCDInterpProcess_NumStatements(iprocess); - - // get size of preallocated memory - int mem_size = NCDInterpProcess_PreallocSize(iprocess); - if (mem_size < 0) { - goto fail0; - } - - // start with size of process structure - size_t alloc_size = sizeof(struct process); - - // add size of statements array - if (num_statements > SIZE_MAX / sizeof(struct statement)) { - goto fail0; - } - if (!BSizeAdd(&alloc_size, num_statements * sizeof(struct statement))) { - goto fail0; - } - - // align for preallocated memory - if (!BSizeAlign(&alloc_size, BMAX_ALIGN)) { - goto fail0; - } - size_t mem_off = alloc_size; - - // add size of preallocated memory - if (mem_size > SIZE_MAX || !BSizeAdd(&alloc_size, mem_size)) { - goto fail0; - } - - // allocate memory - p = BAlloc(alloc_size); - if (!p) { - goto fail0; - } - - // set variables - p->interp = interp; - p->reactor = interp->params.reactor; - p->iprocess = iprocess; - p->ap = 0; - p->fp = 0; - p->num_statements = num_statements; - p->error = 0; - p->have_alloc = 0; - - // init statements - char *mem = (char *)p + mem_off; - for (int i = 0; i < num_statements; i++) { - struct statement *ps = &p->statements[i]; - ps->i = i; - ps->inst.istate = SSTATE_FORGOTTEN; - ps->mem_size = NCDInterpProcess_StatementPreallocSize(iprocess, i); - ps->inst.mem = mem + NCDInterpProcess_StatementPreallocOffset(iprocess, i); - } - - // init timer - BSmallTimer_Init(&p->wait_timer, process_wait_timer_handler); - - // init work job - BSmallPending_Init(&p->work_job, BReactor_PendingGroup(p->reactor), NULL, NULL); - -allocated: - ASSERT(p->interp == interp) - ASSERT(p->reactor == interp->params.reactor) - ASSERT(p->iprocess == iprocess) - ASSERT(p->ap == 0) - ASSERT(p->fp == 0) - ASSERT(p->num_statements == NCDInterpProcess_NumStatements(iprocess)) - ASSERT(p->error == 0) - process_assert_statements_cleared(p); - ASSERT(!BSmallPending_IsSet(&p->work_job)) - ASSERT(!BSmallTimer_IsRunning(&p->wait_timer)) - - return p; - -fail0: - BLog(BLOG_ERROR, "failed to allocate memory for process %s", NCDInterpProcess_Name(iprocess)); - return NULL; -} - -void process_release (struct process *p, int no_push) -{ - ASSERT(p->ap == 0) - ASSERT(p->fp == 0) - ASSERT(p->error == 0) - process_assert_statements_cleared(p); - ASSERT(!BSmallPending_IsSet(&p->work_job)) - ASSERT(!BSmallTimer_IsRunning(&p->wait_timer)) - - // try to push to cache - if (!no_push && !p->have_alloc) { - if (NCDInterpProcess_CachePush(p->iprocess, p)) { - return; - } - } - - // free work job - BSmallPending_Free(&p->work_job, BReactor_PendingGroup(p->reactor)); - - // free statement memory - if (p->have_alloc) { - for (int i = 0; i < p->num_statements; i++) { - struct statement *ps = &p->statements[i]; - if (statement_mem_is_allocated(ps)) { - free(ps->inst.mem); - } - } - } - - // free strucure - BFree(p); -} - -void process_assert_statements_cleared (struct process *p) -{ -#ifndef NDEBUG - for (int i = 0; i < p->num_statements; i++) { - ASSERT(p->statements[i].i == i) - ASSERT(p->statements[i].inst.istate == SSTATE_FORGOTTEN) - } -#endif -} - -int process_new (NCDInterpreter *interp, NCDInterpProcess *iprocess, NCDModuleProcess *module_process) -{ - ASSERT(iprocess) - - // allocate prepared process struct - struct process *p = process_allocate(interp, iprocess); - if (!p) { - return 0; - } - - // set module process pointer - p->module_process = module_process; - - // set module process handlers - if (p->module_process) { - NCDModuleProcess_Interp_SetHandlers(p->module_process, p, - (NCDModuleProcess_interp_func_event)process_moduleprocess_func_event, - (NCDModuleProcess_interp_func_getobj)process_moduleprocess_func_getobj); - } - - // set state - process_set_state(p, PSTATE_WORKING); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_working, p); - - // insert to processes list - LinkedList1_Append(&interp->processes, &p->list_node); - - // schedule work - BSmallPending_Set(&p->work_job, BReactor_PendingGroup(p->reactor)); - - return 1; -} - -void process_set_state (struct process *p, int state) -{ -#ifndef NDEBUG - p->state = state; -#endif -} - -void process_free (struct process *p, NCDModuleProcess **out_mp) -{ - ASSERT(p->ap == 0) - ASSERT(p->fp == 0) - ASSERT(out_mp) - ASSERT(!BSmallPending_IsSet(&p->work_job)) - - // give module process to caller so it can inform the process creator that the process has terminated - *out_mp = p->module_process; - - // remove from processes list - LinkedList1_Remove(&p->interp->processes, &p->list_node); - - // free timer - BReactor_RemoveSmallTimer(p->reactor, &p->wait_timer); - - // clear error - p->error = 0; - - process_release(p, 0); -} - -void process_start_terminating (struct process *p) -{ - // set state terminating - process_set_state(p, PSTATE_TERMINATING); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_terminating, p); - - // schedule work - BSmallPending_Set(&p->work_job, BReactor_PendingGroup(p->reactor)); -} - -int process_have_child (struct process *p) -{ - return (p->ap > 0 && p->statements[p->ap - 1].inst.istate == SSTATE_CHILD); -} - -void process_assert_pointers (struct process *p) -{ - ASSERT(p->ap <= p->num_statements) - ASSERT(p->fp >= p->ap) - ASSERT(p->fp <= p->num_statements) - -#ifndef NDEBUG - // check AP - for (int i = 0; i < p->ap; i++) { - if (i == p->ap - 1) { - ASSERT(p->statements[i].inst.istate == SSTATE_ADULT || p->statements[i].inst.istate == SSTATE_CHILD) - } else { - ASSERT(p->statements[i].inst.istate == SSTATE_ADULT) - } - } - - // check FP - int fp = p->num_statements; - while (fp > 0 && p->statements[fp - 1].inst.istate == SSTATE_FORGOTTEN) { - fp--; - } - ASSERT(p->fp == fp) -#endif -} - -void process_logfunc (struct process *p) -{ - BLog_Append("process %s: ", NCDInterpProcess_Name(p->iprocess)); -} - -void process_log (struct process *p, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)process_logfunc, p, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void process_work_job_handler_working (struct process *p) -{ - process_assert_pointers(p); - ASSERT(p->state == PSTATE_WORKING) - - // cleaning up? - if (p->ap < p->fp) { - // order the last living statement to die, if needed - struct statement *ps = &p->statements[p->fp - 1]; - if (ps->inst.istate == SSTATE_DYING) { - return; - } - - STATEMENT_LOG(ps, BLOG_INFO, "killing"); - - // set statement state DYING - ps->inst.istate = SSTATE_DYING; - - // order it to die - NCDModuleInst_Die(&ps->inst); - return; - } - - // clean? - if (process_have_child(p)) { - ASSERT(p->ap > 0) - ASSERT(p->ap <= p->num_statements) - - struct statement *ps = &p->statements[p->ap - 1]; - ASSERT(ps->inst.istate == SSTATE_CHILD) - - STATEMENT_LOG(ps, BLOG_INFO, "clean"); - - // report clean - NCDModuleInst_Clean(&ps->inst); - return; - } - - // finished? - if (p->ap == p->num_statements) { - process_log(p, BLOG_INFO, "victory"); - - // set state up - process_set_state(p, PSTATE_UP); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_up, p); - - // set module process up - if (p->module_process) { - NCDModuleProcess_Interp_Up(p->module_process); - } - return; - } - - // advancing? - struct statement *ps = &p->statements[p->ap]; - ASSERT(ps->inst.istate == SSTATE_FORGOTTEN) - - if (p->error) { - STATEMENT_LOG(ps, BLOG_INFO, "waiting after error"); - - // clear error - p->error = 0; - - // set wait timer - BReactor_SetSmallTimer(p->reactor, &p->wait_timer, BTIMER_SET_RELATIVE, p->interp->params.retry_time); - } else { - // advance - process_advance(p); - } -} - -void process_work_job_handler_up (struct process *p) -{ - process_assert_pointers(p); - ASSERT(p->state == PSTATE_UP) - ASSERT(p->ap < p->num_statements || process_have_child(p)) - - // if we have module process, wait for its permission to continue - if (p->module_process) { - // set state waiting - process_set_state(p, PSTATE_WAITING); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_waiting, p); - - // set module process down - NCDModuleProcess_Interp_Down(p->module_process); - return; - } - - // set state working - process_set_state(p, PSTATE_WORKING); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_working, p); - - // delegate the rest to the working handler - process_work_job_handler_working(p); -} - -void process_work_job_handler_waiting (struct process *p) -{ - process_assert_pointers(p); - ASSERT(p->state == PSTATE_WAITING) - - // do absolutely nothing. Having this no-op handler avoids a branch - // in statement_instance_func_event(). -} - -void process_work_job_handler_terminating (struct process *p) -{ - process_assert_pointers(p); - ASSERT(p->state == PSTATE_TERMINATING) - -again: - if (p->fp == 0) { - NCDInterpreter *interp = p->interp; - - // free process - NCDModuleProcess *mp; - process_free(p, &mp); - - // if program is terminating amd there are no more processes, exit program - if (interp->terminating && LinkedList1_IsEmpty(&interp->processes)) { - ASSERT(!mp) - interp->params.handler_finished(interp->params.user, interp->main_exit_code); - return; - } - - // inform the process creator that the process has terminated - if (mp) { - NCDModuleProcess_Interp_Terminated(mp); - return; - } - - return; - } - - // order the last living statement to die, if needed - struct statement *ps = &p->statements[p->fp - 1]; - ASSERT(ps->inst.istate != SSTATE_FORGOTTEN) - if (ps->inst.istate == SSTATE_DYING) { - return; - } - - STATEMENT_LOG(ps, BLOG_INFO, "killing"); - - // update AP - if (p->ap > ps->i) { - p->ap = ps->i; - } - - // optimize for statements which can be destroyed immediately - if (NCDModuleInst_TryFree(&ps->inst)) { - STATEMENT_LOG(ps, BLOG_INFO, "died"); - - // free arguments memory - NCDValMem_Free(&ps->args_mem); - - // set statement state FORGOTTEN - ps->inst.istate = SSTATE_FORGOTTEN; - - // update FP - while (p->fp > 0 && p->statements[p->fp - 1].inst.istate == SSTATE_FORGOTTEN) { - p->fp--; - } - - goto again; - } - - // set statement state DYING - ps->inst.istate = SSTATE_DYING; - - // order it to die - NCDModuleInst_Die(&ps->inst); - return; -} - -int replace_placeholders_callback (void *arg, int plid, NCDValMem *mem, NCDValRef *out) -{ - struct process *p = arg; - ASSERT(plid >= 0) - ASSERT(mem) - ASSERT(out) - - const NCD_string_id_t *varnames; - size_t num_names; - NCDPlaceholderDb_GetVariable(&p->interp->placeholder_db, plid, &varnames, &num_names); - - return process_resolve_variable_expr(p, p->ap, varnames, num_names, mem, out); -} - -void process_advance (struct process *p) -{ - process_assert_pointers(p); - ASSERT(p->ap == p->fp) - ASSERT(!process_have_child(p)) - ASSERT(p->ap < p->num_statements) - ASSERT(!p->error) - ASSERT(!BSmallPending_IsSet(&p->work_job)) - ASSERT(p->state == PSTATE_WORKING) - - struct statement *ps = &p->statements[p->ap]; - ASSERT(ps->inst.istate == SSTATE_FORGOTTEN) - - STATEMENT_LOG(ps, BLOG_INFO, "initializing"); - - // need to determine the module and object to use it on (if it's a method) - const struct NCDInterpModule *module; - void *method_context = NULL; - - // get object names, e.g. "my.cat" in "my.cat->meow();" - // (or NULL if this is not a method statement) - const NCD_string_id_t *objnames; - size_t num_objnames; - NCDInterpProcess_StatementObjNames(p->iprocess, p->ap, &objnames, &num_objnames); - - if (!objnames) { - // not a method; module is already known by NCDInterpProcess - module = NCDInterpProcess_StatementGetSimpleModule(p->iprocess, p->ap, &p->interp->string_index, &p->interp->mindex); - - if (!module) { - const char *cmdname_str = NCDInterpProcess_StatementCmdName(p->iprocess, p->ap, &p->interp->string_index); - STATEMENT_LOG(ps, BLOG_ERROR, "unknown simple statement: %s", cmdname_str); - goto fail0; - } - } else { - // get object - NCDObject object; - if (!process_resolve_object_expr(p, p->ap, objnames, num_objnames, &object)) { - goto fail0; - } - - // get object type - NCD_string_id_t object_type = NCDObject_Type(&object); - if (object_type < 0) { - STATEMENT_LOG(ps, BLOG_ERROR, "cannot call method on object with no type"); - goto fail0; - } - - // get method context - method_context = NCDObject_MethodUser(&object); - - // find module based on type of object - module = NCDInterpProcess_StatementGetMethodModule(p->iprocess, p->ap, object_type, &p->interp->mindex); - - if (!module) { - const char *type_str = NCDStringIndex_Value(&p->interp->string_index, object_type); - const char *cmdname_str = NCDInterpProcess_StatementCmdName(p->iprocess, p->ap, &p->interp->string_index); - STATEMENT_LOG(ps, BLOG_ERROR, "unknown method statement: %s::%s", type_str, cmdname_str); - goto fail0; - } - } - - // copy arguments - NCDValRef args; - NCDValReplaceProg prog; - if (!NCDInterpProcess_CopyStatementArgs(p->iprocess, ps->i, &ps->args_mem, &args, &prog)) { - STATEMENT_LOG(ps, BLOG_ERROR, "NCDInterpProcess_CopyStatementArgs failed"); - goto fail0; - } - - // replace placeholders with values of variables - if (!NCDValReplaceProg_Execute(prog, &ps->args_mem, replace_placeholders_callback, p)) { - STATEMENT_LOG(ps, BLOG_ERROR, "failed to replace variables in arguments with values"); - goto fail1; - } - - // convert non-continuous strings unless the module can handle them - if (!(module->module.flags & NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS)) { - if (!NCDValMem_ConvertNonContinuousStrings(&ps->args_mem, &args)) { - STATEMENT_LOG(ps, BLOG_ERROR, "NCDValMem_ConvertNonContinuousStrings failed"); - goto fail1; - } - } - - // allocate memory - if (!statement_allocate_memory(ps, module->module.alloc_size)) { - STATEMENT_LOG(ps, BLOG_ERROR, "failed to allocate memory"); - goto fail1; - } - - // set statement state CHILD - ps->inst.istate = SSTATE_CHILD; - - // increment AP - p->ap++; - - // increment FP - p->fp++; - - process_assert_pointers(p); - - // initialize module instance - NCDModuleInst_Init(&ps->inst, module, method_context, args, &p->interp->module_params); - return; - -fail1: - NCDValMem_Free(&ps->args_mem); -fail0: - // set error - p->error = 1; - - // schedule work to start the timer - BSmallPending_Set(&p->work_job, BReactor_PendingGroup(p->reactor)); -} - -void process_wait_timer_handler (BSmallTimer *timer) -{ - struct process *p = UPPER_OBJECT(timer, struct process, wait_timer); - process_assert_pointers(p); - ASSERT(!BSmallPending_IsSet(&p->work_job)) - - // check if something happened that means we no longer need to retry - if (p->ap != p->fp || process_have_child(p) || p->ap == p->num_statements) { - return; - } - - process_log(p, BLOG_INFO, "retrying"); - - // advance. Note: the asserts for this are indeed satisfied, though this - // it not trivial to prove. - process_advance(p); -} - -int process_find_object (struct process *p, int pos, NCD_string_id_t name, NCDObject *out_object) -{ - ASSERT(pos >= 0) - ASSERT(pos <= p->num_statements) - ASSERT(out_object) - - int i = NCDInterpProcess_FindStatement(p->iprocess, pos, name); - if (i >= 0) { - struct statement *ps = &p->statements[i]; - ASSERT(i < p->num_statements) - - if (ps->inst.istate == SSTATE_FORGOTTEN) { - process_log(p, BLOG_ERROR, "statement (%d) is uninitialized", i); - return 0; - } - - *out_object = NCDModuleInst_Object(&ps->inst); - return 1; - } - - if (p->module_process && NCDModuleProcess_Interp_GetSpecialObj(p->module_process, name, out_object)) { - return 1; - } - - return 0; -} - -int process_resolve_object_expr (struct process *p, int pos, const NCD_string_id_t *names, size_t num_names, NCDObject *out_object) -{ - ASSERT(pos >= 0) - ASSERT(pos <= p->num_statements) - ASSERT(names) - ASSERT(num_names > 0) - ASSERT(out_object) - - NCDObject object; - if (!process_find_object(p, pos, names[0], &object)) { - goto fail; - } - - if (!NCDObject_ResolveObjExprCompact(&object, names + 1, num_names - 1, out_object)) { - goto fail; - } - - return 1; - -fail:; - char *name = implode_id_strings(p->interp, names, num_names, '.'); - process_log(p, BLOG_ERROR, "failed to resolve object (%s) from position %zu", (name ? name : ""), pos); - free(name); - return 0; -} - -int process_resolve_variable_expr (struct process *p, int pos, const NCD_string_id_t *names, size_t num_names, NCDValMem *mem, NCDValRef *out_value) -{ - ASSERT(pos >= 0) - ASSERT(pos <= p->num_statements) - ASSERT(names) - ASSERT(num_names > 0) - ASSERT(mem) - ASSERT(out_value) - - NCDObject object; - if (!process_find_object(p, pos, names[0], &object)) { - goto fail; - } - - if (!NCDObject_ResolveVarExprCompact(&object, names + 1, num_names - 1, mem, out_value)) { - goto fail; - } - - return 1; - -fail:; - char *name = implode_id_strings(p->interp, names, num_names, '.'); - process_log(p, BLOG_ERROR, "failed to resolve variable (%s) from position %zu", (name ? name : ""), pos); - free(name); - return 0; -} - -void statement_logfunc (struct statement *ps) -{ - process_logfunc(statement_process(ps)); - BLog_Append("statement %zu: ", ps->i); -} - -void statement_log (struct statement *ps, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)statement_logfunc, ps, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -struct process * statement_process (struct statement *ps) -{ - return UPPER_OBJECT(ps - ps->i, struct process, statements); -} - -int statement_mem_is_allocated (struct statement *ps) -{ - return (ps->mem_size < 0); -} - -int statement_mem_size (struct statement *ps) -{ - return (ps->mem_size >= 0 ? ps->mem_size : -ps->mem_size); -} - -int statement_allocate_memory (struct statement *ps, int alloc_size) -{ - ASSERT(alloc_size >= 0) - - if (alloc_size > statement_mem_size(ps)) { - // allocate new memory - char *new_mem = malloc(alloc_size); - if (!new_mem) { - STATEMENT_LOG(ps, BLOG_ERROR, "malloc failed"); - return 0; - } - - // release old memory unless it was preallocated - if (statement_mem_is_allocated(ps)) { - free(ps->inst.mem); - } - - struct process *p = statement_process(ps); - - // register memory in statement - ps->inst.mem = new_mem; - ps->mem_size = -alloc_size; - - // set the alloc flag in the process to make sure process_free() - // releases the allocated memory - p->have_alloc = 1; - - // register alloc size for future preallocations - NCDInterpProcess_StatementBumpAllocSize(p->iprocess, ps->i, alloc_size); - } - - return 1; -} - -void statement_instance_func_event (NCDModuleInst *inst, int event) -{ - struct statement *ps = UPPER_OBJECT(inst, struct statement, inst); - ASSERT(ps->inst.istate == SSTATE_CHILD || ps->inst.istate == SSTATE_ADULT || ps->inst.istate == SSTATE_DYING) - - struct process *p = statement_process(ps); - process_assert_pointers(p); - - // schedule work - BSmallPending_Set(&p->work_job, BReactor_PendingGroup(p->reactor)); - - switch (event) { - case NCDMODULE_EVENT_UP: { - ASSERT(ps->inst.istate == SSTATE_CHILD) - - STATEMENT_LOG(ps, BLOG_INFO, "up"); - - // set state ADULT - ps->inst.istate = SSTATE_ADULT; - } break; - - case NCDMODULE_EVENT_DOWN: { - ASSERT(ps->inst.istate == SSTATE_ADULT) - - STATEMENT_LOG(ps, BLOG_INFO, "down"); - - // set state CHILD - ps->inst.istate = SSTATE_CHILD; - - // clear error - if (ps->i < p->ap) { - p->error = 0; - } - - // update AP - if (p->ap > ps->i + 1) { - p->ap = ps->i + 1; - } - } break; - - case NCDMODULE_EVENT_DOWNUP: { - ASSERT(ps->inst.istate == SSTATE_ADULT) - - STATEMENT_LOG(ps, BLOG_INFO, "down"); - STATEMENT_LOG(ps, BLOG_INFO, "up"); - - // clear error - if (ps->i < p->ap) { - p->error = 0; - } - - // update AP - if (p->ap > ps->i + 1) { - p->ap = ps->i + 1; - } - } break; - - case NCDMODULE_EVENT_DEAD: { - STATEMENT_LOG(ps, BLOG_INFO, "died"); - - // free instance - NCDModuleInst_Free(&ps->inst); - - // free arguments memory - NCDValMem_Free(&ps->args_mem); - - // set state FORGOTTEN - ps->inst.istate = SSTATE_FORGOTTEN; - - // update AP - if (p->ap > ps->i) { - p->ap = ps->i; - } - - // update FP - while (p->fp > 0 && p->statements[p->fp - 1].inst.istate == SSTATE_FORGOTTEN) { - p->fp--; - } - } break; - - case NCDMODULE_EVENT_DEADERROR: { - STATEMENT_LOG(ps, BLOG_ERROR, "died with error"); - - // free instance - NCDModuleInst_Free(&ps->inst); - - // free arguments memory - NCDValMem_Free(&ps->args_mem); - - // set state FORGOTTEN - ps->inst.istate = SSTATE_FORGOTTEN; - - // set error - if (ps->i < p->ap) { - p->error = 1; - } - - // update AP - if (p->ap > ps->i) { - p->ap = ps->i; - } - - // update FP - while (p->fp > 0 && p->statements[p->fp - 1].inst.istate == SSTATE_FORGOTTEN) { - p->fp--; - } - } break; - } -} - -int statement_instance_func_getobj (NCDModuleInst *inst, NCD_string_id_t objname, NCDObject *out_object) -{ - struct statement *ps = UPPER_OBJECT(inst, struct statement, inst); - ASSERT(ps->inst.istate != SSTATE_FORGOTTEN) - - return process_find_object(statement_process(ps), ps->i, objname, out_object); -} - -int statement_instance_func_initprocess (void *vinterp, NCDModuleProcess* mp, NCD_string_id_t template_name) -{ - NCDInterpreter *interp = vinterp; - - // find process - NCDInterpProcess *iprocess = NCDInterpProg_FindProcess(&interp->iprogram, template_name); - if (!iprocess) { - const char *str = NCDStringIndex_Value(&interp->string_index, template_name); - BLog(BLOG_ERROR, "no template named %s", str); - return 0; - } - - // make sure it's a template - if (!NCDInterpProcess_IsTemplate(iprocess)) { - const char *str = NCDStringIndex_Value(&interp->string_index, template_name); - BLog(BLOG_ERROR, "need template to create a process, but %s is a process", str); - return 0; - } - - // create process - if (!process_new(interp, iprocess, mp)) { - const char *str = NCDStringIndex_Value(&interp->string_index, template_name); - BLog(BLOG_ERROR, "failed to create process from template %s", str); - return 0; - } - - if (BLog_WouldLog(BLOG_INFO, BLOG_CURRENT_CHANNEL)) { - const char *str = NCDStringIndex_Value(&interp->string_index, template_name); - BLog(BLOG_INFO, "created process from template %s", str); - } - - return 1; -} - -void statement_instance_logfunc (NCDModuleInst *inst) -{ - struct statement *ps = UPPER_OBJECT(inst, struct statement, inst); - ASSERT(ps->inst.istate != SSTATE_FORGOTTEN) - - statement_logfunc(ps); - BLog_Append("module: "); -} - -void statement_instance_func_interp_exit (void *vinterp, int exit_code) -{ - NCDInterpreter *interp = vinterp; - - start_terminate(interp, exit_code); -} - -int statement_instance_func_interp_getargs (void *vinterp, NCDValMem *mem, NCDValRef *out_value) -{ - NCDInterpreter *interp = vinterp; - - *out_value = NCDVal_NewList(mem, interp->params.num_extra_args); - if (NCDVal_IsInvalid(*out_value)) { - BLog(BLOG_ERROR, "NCDVal_NewList failed"); - goto fail; - } - - for (int i = 0; i < interp->params.num_extra_args; i++) { - NCDValRef arg = NCDVal_NewString(mem, interp->params.extra_args[i]); - if (NCDVal_IsInvalid(arg)) { - BLog(BLOG_ERROR, "NCDVal_NewString failed"); - goto fail; - } - - if (!NCDVal_ListAppend(*out_value, arg)) { - BLog(BLOG_ERROR, "depth limit exceeded"); - goto fail; - } - } - - return 1; - -fail: - *out_value = NCDVal_NewInvalid(); - return 1; -} - -btime_t statement_instance_func_interp_getretrytime (void *vinterp) -{ - NCDInterpreter *interp = vinterp; - - return interp->params.retry_time; -} - -int statement_instance_func_interp_loadgroup (void *vinterp, const struct NCDModuleGroup *group) -{ - NCDInterpreter *interp = vinterp; - - if (!NCDModuleIndex_AddGroup(&interp->mindex, group, &interp->module_iparams, &interp->string_index)) { - BLog(BLOG_ERROR, "NCDModuleIndex_AddGroup failed"); - return 0; - } - - return 1; -} - -void process_moduleprocess_func_event (struct process *p, int event) -{ - ASSERT(p->module_process) - - switch (event) { - case NCDMODULEPROCESS_INTERP_EVENT_CONTINUE: { - ASSERT(p->state == PSTATE_WAITING) - - // set state working - process_set_state(p, PSTATE_WORKING); - BSmallPending_SetHandler(&p->work_job, (BSmallPending_handler)process_work_job_handler_working, p); - - // schedule work - BSmallPending_Set(&p->work_job, BReactor_PendingGroup(p->reactor)); - } break; - - case NCDMODULEPROCESS_INTERP_EVENT_TERMINATE: { - ASSERT(p->state != PSTATE_TERMINATING) - - process_log(p, BLOG_INFO, "process termination requested"); - - // start terminating - process_start_terminating(p); - } break; - - default: ASSERT(0); - } -} - -int process_moduleprocess_func_getobj (struct process *p, NCD_string_id_t name, NCDObject *out_object) -{ - ASSERT(p->module_process) - - return process_find_object(p, p->num_statements, name, out_object); -} diff --git a/external/badvpn_dns/ncd/NCDInterpreter.h b/external/badvpn_dns/ncd/NCDInterpreter.h deleted file mode 100644 index 8d11c33..0000000 --- a/external/badvpn_dns/ncd/NCDInterpreter.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file NCDInterpreter.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_INTERPRETER_H -#define BADVPN_NCD_INTERPRETER_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BTime.h> -#include <system/BReactor.h> -#include <ncd/NCDStringIndex.h> -#include <ncd/NCDModuleIndex.h> -#include <ncd/NCDAst.h> -#include <ncd/NCDPlaceholderDb.h> -#include <ncd/NCDInterpProg.h> -#include <ncd/NCDModule.h> -#include <structure/LinkedList1.h> - -#ifndef BADVPN_NO_PROCESS -#include <system/BProcess.h> -#endif -#ifndef BADVPN_NO_UDEV -#include <udevmonitor/NCDUdevManager.h> -#endif -#ifndef BADVPN_NO_RANDOM -#include <random/BRandom2.h> -#endif - -/** - * Handler called when the interpreter has terminated, and {@link NCDInterpreter_Free} - * can be called. - * - * @param user the user member of struct {@link NCDInterpreter_params} - * @param exit_code the exit code specified in the last interpreter termination request - */ -typedef void (*NCDInterpreter_handler_finished) (void *user, int exit_code); - -struct NCDInterpreter_params { - // callbacks - NCDInterpreter_handler_finished handler_finished; - void *user; - - // options - btime_t retry_time; - char **extra_args; - int num_extra_args; - - // possibly shared resources - BReactor *reactor; -#ifndef BADVPN_NO_PROCESS - BProcessManager *manager; -#endif -#ifndef BADVPN_NO_UDEV - NCDUdevManager *umanager; -#endif -#ifndef BADVPN_NO_RANDOM - BRandom2 *random2; -#endif -}; - -typedef struct { - // parameters - struct NCDInterpreter_params params; - - // are we terminating - int terminating; - int main_exit_code; - - // string index - NCDStringIndex string_index; - - // module index - NCDModuleIndex mindex; - - // program AST - NCDProgram program; - - // placeholder database - NCDPlaceholderDb placeholder_db; - - // structure for efficient interpretation - NCDInterpProg iprogram; - - // common module parameters - struct NCDModuleInst_params module_params; - struct NCDModuleInst_iparams module_iparams; - - // processes - LinkedList1 processes; - - DebugObject d_obj; -} NCDInterpreter; - -/** - * Initializes and starts the interpreter. - * - * @param o the interpreter - * @param program the program to execute in AST format. The program must - * not contain any 'include' or 'include_guard' directives. - * The interpreter takes ownership of the program, regardless - * of the success of this function. - * @param params other parameters - * @return 1 on success, 0 on failure - */ -int NCDInterpreter_Init (NCDInterpreter *o, NCDProgram program, struct NCDInterpreter_params params) WARN_UNUSED; - -/** - * Frees the interpreter. - * This may only be called after the interpreter has terminated, i.e. - * the {@link NCDInterpreter_handler_finished} handler has been called. - * Additionally, it can be called right after {@link NCDInterpreter_Init} - * before any of the interpreter's {@link BPendingGroup} jobs have executed. - */ -void NCDInterpreter_Free (NCDInterpreter *o); - -/** - * Requests termination of the interpreter. - * NOTE: the program can request its own termination, possibly overriding the exit - * code specified here. Expect the program to terminate even if this function was - * not called. - * - * @param o the interpreter - * @param exit_code the exit code to be passed to {@link NCDInterpreter_handler_finished}. - * This overrides any exit code set previously. - */ -void NCDInterpreter_RequestShutdown (NCDInterpreter *o, int exit_code); - -#endif diff --git a/external/badvpn_dns/ncd/NCDMethodIndex.c b/external/badvpn_dns/ncd/NCDMethodIndex.c deleted file mode 100644 index 5b3662a..0000000 --- a/external/badvpn_dns/ncd/NCDMethodIndex.c +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @file NCDMethodIndex.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/hashfun.h> -#include <misc/balloc.h> -#include <misc/strdup.h> - -#include "NCDMethodIndex.h" - -#include "NCDMethodIndex_hash.h" -#include <structure/CHash_impl.h> - -#define GROWARRAY_NAME NamesArray -#define GROWARRAY_OBJECT_TYPE NCDMethodIndex -#define GROWARRAY_ARRAY_MEMBER names -#define GROWARRAY_CAPACITY_MEMBER names_capacity -#define GROWARRAY_MAX_CAPACITY INT_MAX -#include <misc/grow_array.h> - -#define GROWARRAY_NAME EntriesArray -#define GROWARRAY_OBJECT_TYPE NCDMethodIndex -#define GROWARRAY_ARRAY_MEMBER entries -#define GROWARRAY_CAPACITY_MEMBER entries_capacity -#define GROWARRAY_MAX_CAPACITY INT_MAX -#include <misc/grow_array.h> - -#include <generated/blog_channel_ncd.h> - -static int find_method_name (NCDMethodIndex *o, const char *method_name, int *out_entry_idx) -{ - ASSERT(method_name) - - NCDMethodIndex__HashRef ref = NCDMethodIndex__Hash_Lookup(&o->hash, o->names, method_name); - if (ref.link == -1) { - return 0; - } - - ASSERT(ref.link >= 0) - ASSERT(ref.link < o->num_names) - - struct NCDMethodIndex__method_name *name_entry = ref.ptr; - ASSERT(!strcmp(name_entry->method_name, method_name)) - ASSERT(name_entry->first_entry >= 0) - ASSERT(name_entry->first_entry < o->num_entries) - - if (out_entry_idx) { - *out_entry_idx = name_entry->first_entry; - } - return 1; -} - -static int add_method_name (NCDMethodIndex *o, const char *method_name, int *out_entry_idx) -{ - ASSERT(method_name) - ASSERT(!find_method_name(o, method_name, NULL)) - - if (o->num_entries == o->entries_capacity && !EntriesArray_DoubleUp(o)) { - BLog(BLOG_ERROR, "EntriesArray_DoubleUp failed"); - goto fail0; - } - - if (o->num_names == o->names_capacity && !NamesArray_DoubleUp(o)) { - BLog(BLOG_ERROR, "NamesArray_DoubleUp failed"); - goto fail0; - } - - struct NCDMethodIndex__entry *entry = &o->entries[o->num_entries]; - entry->obj_type = -1; - entry->next = -1; - - struct NCDMethodIndex__method_name *name_entry = &o->names[o->num_names]; - - if (!(name_entry->method_name = b_strdup(method_name))) { - BLog(BLOG_ERROR, "b_strdup failed"); - goto fail0; - } - - name_entry->first_entry = o->num_entries; - - NCDMethodIndex__HashRef ref = {name_entry, o->num_names}; - int res = NCDMethodIndex__Hash_Insert(&o->hash, o->names, ref, NULL); - ASSERT_EXECUTE(res) - - o->num_entries++; - o->num_names++; - - if (out_entry_idx) { - *out_entry_idx = name_entry->first_entry; - } - return 1; - -fail0: - return 0; -} - -int NCDMethodIndex_Init (NCDMethodIndex *o, NCDStringIndex *string_index) -{ - ASSERT(string_index) - - o->string_index = string_index; - - if (!NamesArray_Init(o, NCDMETHODINDEX_NUM_EXPECTED_METHOD_NAMES)) { - BLog(BLOG_ERROR, "NamesArray_Init failed"); - goto fail0; - } - - if (!EntriesArray_Init(o, NCDMETHODINDEX_NUM_EXPECTED_ENTRIES)) { - BLog(BLOG_ERROR, "EntriesArray_Init failed"); - goto fail1; - } - - o->num_names = 0; - o->num_entries = 0; - - if (!NCDMethodIndex__Hash_Init(&o->hash, NCDMETHODINDEX_NUM_EXPECTED_METHOD_NAMES)) { - BLog(BLOG_ERROR, "NCDMethodIndex__Hash_Init failed"); - goto fail2; - } - - return 1; - -fail2: - EntriesArray_Free(o); -fail1: - NamesArray_Free(o); -fail0: - return 0; -} - -void NCDMethodIndex_Free (NCDMethodIndex *o) -{ - for (int i = 0; i < o->num_names; i++) { - free(o->names[i].method_name); - } - - NCDMethodIndex__Hash_Free(&o->hash); - EntriesArray_Free(o); - NamesArray_Free(o); -} - -int NCDMethodIndex_AddMethod (NCDMethodIndex *o, const char *obj_type, size_t obj_type_len, const char *method_name, const struct NCDInterpModule *module) -{ - ASSERT(obj_type) - ASSERT(method_name) - ASSERT(module) - - NCD_string_id_t obj_type_id = NCDStringIndex_GetBin(o->string_index, obj_type, obj_type_len); - if (obj_type_id < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto fail0; - } - - int entry_idx; - int first_entry_idx; - - if (!find_method_name(o, method_name, &first_entry_idx)) { - if (!add_method_name(o, method_name, &entry_idx)) { - goto fail0; - } - - ASSERT(entry_idx >= 0) - ASSERT(entry_idx < o->num_entries) - - struct NCDMethodIndex__entry *entry = &o->entries[entry_idx]; - - entry->obj_type = obj_type_id; - entry->module = module; - } else { - ASSERT(first_entry_idx >= 0) - ASSERT(first_entry_idx < o->num_entries) - - if (o->num_entries == o->entries_capacity && !EntriesArray_DoubleUp(o)) { - BLog(BLOG_ERROR, "EntriesArray_DoubleUp failed"); - goto fail0; - } - - entry_idx = o->num_entries; - struct NCDMethodIndex__entry *entry = &o->entries[o->num_entries]; - - entry->obj_type = obj_type_id; - entry->module = module; - - entry->next = o->entries[first_entry_idx].next; - o->entries[first_entry_idx].next = o->num_entries; - - o->num_entries++; - } - - return entry_idx; - -fail0: - return -1; -} - -void NCDMethodIndex_RemoveMethod (NCDMethodIndex *o, int method_name_id) -{ - ASSERT(method_name_id >= 0) - ASSERT(method_name_id < o->num_entries) - ASSERT(o->entries[method_name_id].obj_type >= 0) - - o->entries[method_name_id].obj_type = -1; -} - -int NCDMethodIndex_GetMethodNameId (NCDMethodIndex *o, const char *method_name) -{ - ASSERT(method_name) - - int first_entry_idx; - - if (!find_method_name(o, method_name, &first_entry_idx)) { - if (!add_method_name(o, method_name, &first_entry_idx)) { - return -1; - } - } - - ASSERT(first_entry_idx >= 0) - ASSERT(first_entry_idx < o->num_entries) - - return first_entry_idx; -} - -const struct NCDInterpModule * NCDMethodIndex_GetMethodModule (NCDMethodIndex *o, NCD_string_id_t obj_type, int method_name_id) -{ - ASSERT(obj_type >= 0) - ASSERT(method_name_id >= 0) - ASSERT(method_name_id < o->num_entries) - - do { - struct NCDMethodIndex__entry *entry = &o->entries[method_name_id]; - - if (entry->obj_type == obj_type) { - ASSERT(entry->module) - return entry->module; - } - - method_name_id = entry->next; - ASSERT(method_name_id >= -1) - ASSERT(method_name_id < o->num_entries) - } while (method_name_id >= 0); - - return NULL; -} diff --git a/external/badvpn_dns/ncd/NCDMethodIndex.h b/external/badvpn_dns/ncd/NCDMethodIndex.h deleted file mode 100644 index e4db0a5..0000000 --- a/external/badvpn_dns/ncd/NCDMethodIndex.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file NCDMethodIndex.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDMETHODINDEX_H -#define BADVPN_NCDMETHODINDEX_H - -#include <misc/debug.h> -#include <structure/CHash.h> -#include <ncd/NCDModule.h> -#include <ncd/NCDStringIndex.h> - -#define NCDMETHODINDEX_NUM_EXPECTED_METHOD_NAMES 64 -#define NCDMETHODINDEX_NUM_EXPECTED_ENTRIES 64 - -struct NCDMethodIndex__method_name { - char *method_name; - int first_entry; - int hash_next; -}; - -struct NCDMethodIndex__entry { - NCD_string_id_t obj_type; - const struct NCDInterpModule *module; - int next; -}; - -typedef struct NCDMethodIndex__method_name NCDMethodIndex__hashentry; -typedef const char *NCDMethodIndex__hashkey; -typedef struct NCDMethodIndex__method_name *NCDMethodIndex__hasharg; - -#include "NCDMethodIndex_hash.h" -#include <structure/CHash_decl.h> - -/** - * The method index associates (object_type, method_name) pairs to pointers - * to corresponding \link NCDInterpModule structures (whose type strings would - * be "object_type::method_name"). - * More precisely, the method names are represented as indices into an - * internal array, which allows very efficient lookup when the method names - * are known in advance, but not the object types. - */ -typedef struct { - struct NCDMethodIndex__method_name *names; - struct NCDMethodIndex__entry *entries; - int names_capacity; - int entries_capacity; - int num_names; - int num_entries; - NCDMethodIndex__Hash hash; - NCDStringIndex *string_index; -} NCDMethodIndex; - -/** - * Initializes the method index. - * - * @return 1 on success, 0 on failure - */ -int NCDMethodIndex_Init (NCDMethodIndex *o, NCDStringIndex *string_index) WARN_UNUSED; - -/** - * Frees the method index. - */ -void NCDMethodIndex_Free (NCDMethodIndex *o); - -/** - * Adds a method to the index. - * Duplicate methods will not be detected here. - * - * @param obj_type object type of method, e.g. "cat" in "cat::meow". - * Must not be NULL. Does not have to be null-terminated. - * @param obj_type_len number of characters in obj_type - * @param method_name name of method, e.g. "meow" in "cat::meow". - * Must not be NULL. - * @param module pointer to module structure. Must not be NULL. - * @return on success, a non-negative identifier; on failure, -1 - */ -int NCDMethodIndex_AddMethod (NCDMethodIndex *o, const char *obj_type, size_t obj_type_len, const char *method_name, const struct NCDInterpModule *module); - -/** - * Removes a method from the index. - * - * @param method_name_id method name identifier - */ -void NCDMethodIndex_RemoveMethod (NCDMethodIndex *o, int method_name_id); - -/** - * Obtains an internal integer identifier for a method name. The intention is that - * this is stored and later passed to \link NCDMethodIndex_GetMethodModule for - * efficient lookup of modules corresponding to methods. - * - * @param method_name name of method, e.g. "meow" in "cat::meow". - * Must not be NULL. - * @return non-negative integer on success, -1 on failure - */ -int NCDMethodIndex_GetMethodNameId (NCDMethodIndex *o, const char *method_name); - -/** - * Looks up the module corresponding to a method. The method name is passed as an - * identifier obtained from \link NCDMethodIndex_GetMethodNameId. - * - * @param obj_type object type of method, e.g. "cat" in "cat::meow", as a string - * identifier via {@link NCDStringIndex} - * @param method_name_id method name identifier. Must have been previously returned - * by a successfull call of \link NCDMethodIndex_GetMethodNameId. - * @return module pointer, or NULL if no such method exists - */ -const struct NCDInterpModule * NCDMethodIndex_GetMethodModule (NCDMethodIndex *o, NCD_string_id_t obj_type, int method_name_id); - -#endif diff --git a/external/badvpn_dns/ncd/NCDMethodIndex_hash.h b/external/badvpn_dns/ncd/NCDMethodIndex_hash.h deleted file mode 100644 index f1108cb..0000000 --- a/external/badvpn_dns/ncd/NCDMethodIndex_hash.h +++ /dev/null @@ -1,12 +0,0 @@ -#define CHASH_PARAM_NAME NCDMethodIndex__Hash -#define CHASH_PARAM_ENTRY NCDMethodIndex__hashentry -#define CHASH_PARAM_LINK int -#define CHASH_PARAM_KEY NCDMethodIndex__hashkey -#define CHASH_PARAM_ARG NCDMethodIndex__hasharg -#define CHASH_PARAM_NULL ((int)-1) -#define CHASH_PARAM_DEREF(arg, link) (&(arg)[(link)]) -#define CHASH_PARAM_ENTRYHASH(arg, entry) (badvpn_djb2_hash((const uint8_t *)(entry).ptr->method_name)) -#define CHASH_PARAM_KEYHASH(arg, key) (badvpn_djb2_hash((const uint8_t *)(key))) -#define CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) (!strcmp((entry1).ptr->method_name, (entry2).ptr->method_name)) -#define CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) (!strcmp((key1), (entry2).ptr->method_name)) -#define CHASH_PARAM_ENTRY_NEXT hash_next diff --git a/external/badvpn_dns/ncd/NCDModule.c b/external/badvpn_dns/ncd/NCDModule.c deleted file mode 100644 index da6894a..0000000 --- a/external/badvpn_dns/ncd/NCDModule.c +++ /dev/null @@ -1,625 +0,0 @@ -/** - * @file NCDModule.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdarg.h> -#include <string.h> -#include <stddef.h> -#include <inttypes.h> -#include <limits.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#define STATE_DEAD 0 -#define STATE_DOWN_CLEAN 1 -#define STATE_UP 2 -#define STATE_DOWN_UNCLEAN 3 -#define STATE_DYING 4 - -#define PROCESS_STATE_INIT 0 -#define PROCESS_STATE_DOWN 1 -#define PROCESS_STATE_UP 2 -#define PROCESS_STATE_DOWN_WAITING 3 -#define PROCESS_STATE_TERMINATING 4 -#define PROCESS_STATE_TERMINATED 5 - -static int object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); -static int object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static int process_args_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); -static int process_arg_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); - -static void frontend_event (NCDModuleInst *n, int event) -{ - n->params->func_event(n, event); -} - -static void inst_assert_backend (NCDModuleInst *n) -{ - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) -} - -static void set_process_state (NCDModuleProcess *p, int state) -{ -#ifndef NDEBUG - p->state = state; -#endif -} - -void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDInterpModule *m, void *method_context, NCDValRef args, const struct NCDModuleInst_params *params) -{ - ASSERT(m) - ASSERT(m->module.func_new2) - ASSERT(m->module.alloc_size >= 0) - ASSERT(m->base_type_id >= 0) - ASSERT(m->group) - ASSERT(n->mem) - ASSERT(NCDVal_IsList(args)) - ASSERT(params) - ASSERT(params->func_event) - ASSERT(params->func_getobj) - ASSERT(params->logfunc) - ASSERT(params->iparams) - ASSERT(params->iparams->func_initprocess) - ASSERT(params->iparams->func_interp_exit) - ASSERT(params->iparams->func_interp_getargs) - ASSERT(params->iparams->func_interp_getretrytime) - - // init arguments - n->m = m; - n->params = params; - - // set initial state - n->state = STATE_DOWN_CLEAN; - - // give NCDModuleInst to methods, not mem - n->pass_mem_to_methods = 0; - - DebugObject_Init(&n->d_obj); - - struct NCDModuleInst_new_params new_params; - new_params.method_user = method_context; - new_params.args = args; - - n->m->module.func_new2(n->mem, n, &new_params); -} - -void NCDModuleInst_Free (NCDModuleInst *n) -{ - DebugObject_Free(&n->d_obj); - ASSERT(n->state == STATE_DEAD) -} - -void NCDModuleInst_Die (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_UP || n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN) - - n->state = STATE_DYING; - - if (!n->m->module.func_die) { - NCDModuleInst_Backend_Dead(n); - return; - } - - n->m->module.func_die(n->mem); - return; -} - -int NCDModuleInst_TryFree (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_UP || n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN) - - if (n->m->module.func_die) { - return 0; - } - - DebugObject_Free(&n->d_obj); - - return 1; -} - -void NCDModuleInst_Clean (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN) - - if (n->state == STATE_DOWN_UNCLEAN) { - n->state = STATE_DOWN_CLEAN; - - if (n->m->module.func_clean) { - n->m->module.func_clean(n->mem); - return; - } - } -} - -NCDObject NCDModuleInst_Object (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->m->base_type_id >= 0) - - void *method_user = (n->pass_mem_to_methods ? n->mem : n); - - return NCDObject_BuildFull(n->m->base_type_id, n, 0, method_user, object_func_getvar, object_func_getobj); -} - -void NCDModuleInst_Backend_PassMemToMethods (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) - - n->pass_mem_to_methods = 1; -} - -static int can_resolve (NCDModuleInst *n) -{ - switch (n->state) { - case STATE_UP: - return 1; - case STATE_DOWN_CLEAN: - case STATE_DOWN_UNCLEAN: - return !!(n->m->module.flags & NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN); - default: - return 0; - } -} - -static int object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - NCDModuleInst *n = NCDObject_DataPtr(obj); - DebugObject_Access(&n->d_obj); - - if ((!n->m->module.func_getvar && !n->m->module.func_getvar2) || !can_resolve(n)) { - return 0; - } - - int res; - if (n->m->module.func_getvar2) { - res = n->m->module.func_getvar2(n->mem, name, mem, out_value); - } else { - if (NCDStringIndex_HasNulls(n->params->iparams->string_index, name)) { - return 0; - } - const char *name_str = NCDStringIndex_Value(n->params->iparams->string_index, name); - res = n->m->module.func_getvar(n->mem, name_str, mem, out_value); - } - ASSERT(res == 0 || res == 1) - ASSERT(res == 0 || (NCDVal_Assert(*out_value), 1)) - - return res; -} - -static int object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - NCDModuleInst *n = NCDObject_DataPtr(obj); - DebugObject_Access(&n->d_obj); - - if (!n->m->module.func_getobj || !can_resolve(n)) { - return 0; - } - - int res = n->m->module.func_getobj(n->mem, name, out_object); - ASSERT(res == 0 || res == 1) - - return res; -} - -void * NCDModuleInst_Backend_GetUser (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) - - return n->mem; -} - -void NCDModuleInst_Backend_Up (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN) - - n->state = STATE_UP; - frontend_event(n, NCDMODULE_EVENT_UP); -} - -void NCDModuleInst_Backend_Down (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_UP) - - n->state = STATE_DOWN_UNCLEAN; - frontend_event(n, NCDMODULE_EVENT_DOWN); -} - -void NCDModuleInst_Backend_DownUp (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_UP) - - frontend_event(n, NCDMODULE_EVENT_DOWNUP); -} - -void NCDModuleInst_Backend_Dead (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN || - n->state == STATE_UP || n->state == STATE_DYING) - - n->state = STATE_DEAD; - - frontend_event(n, NCDMODULE_EVENT_DEAD); - return; -} - -void NCDModuleInst_Backend_DeadError (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_CLEAN || n->state == STATE_DOWN_UNCLEAN || - n->state == STATE_UP || n->state == STATE_DYING) - - n->state = STATE_DEAD; - - frontend_event(n, NCDMODULE_EVENT_DEADERROR); - return; -} - -int NCDModuleInst_Backend_GetObj (NCDModuleInst *n, NCD_string_id_t name, NCDObject *out_object) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) - ASSERT(out_object) - - int res = n->params->func_getobj(n, name, out_object); - ASSERT(res == 0 || res == 1) - - return res; -} - -void NCDModuleInst_Backend_Log (NCDModuleInst *n, int channel, int level, const char *fmt, ...) -{ - DebugObject_Access(&n->d_obj); - - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg(n->params->logfunc, n, channel, level, fmt, vl); - va_end(vl); -} - -void NCDModuleInst_Backend_LogVarArg (NCDModuleInst *n, int channel, int level, const char *fmt, va_list vl) -{ - DebugObject_Access(&n->d_obj); - - BLog_LogViaFuncVarArg(n->params->logfunc, n, channel, level, fmt, vl); -} - -BLogContext NCDModuleInst_Backend_LogContext (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - - return BLog_MakeContext(n->params->logfunc, n); -} - -void NCDModuleInst_Backend_InterpExit (NCDModuleInst *n, int exit_code) -{ - DebugObject_Access(&n->d_obj); - inst_assert_backend(n); - - n->params->iparams->func_interp_exit(n->params->iparams->user, exit_code); -} - -int NCDModuleInst_Backend_InterpGetArgs (NCDModuleInst *n, NCDValMem *mem, NCDValRef *out_value) -{ - DebugObject_Access(&n->d_obj); - inst_assert_backend(n); - ASSERT(mem) - ASSERT(out_value) - - int res = n->params->iparams->func_interp_getargs(n->params->iparams->user, mem, out_value); - ASSERT(res == 0 || res == 1) - ASSERT(res == 0 || (NCDVal_Assert(*out_value), 1)) - - return res; -} - -btime_t NCDModuleInst_Backend_InterpGetRetryTime (NCDModuleInst *n) -{ - DebugObject_Access(&n->d_obj); - inst_assert_backend(n); - - return n->params->iparams->func_interp_getretrytime(n->params->iparams->user); -} - -int NCDModuleInst_Backend_InterpLoadGroup (NCDModuleInst *n, const struct NCDModuleGroup *group) -{ - DebugObject_Access(&n->d_obj); - inst_assert_backend(n); - ASSERT(group) - - return n->params->iparams->func_loadgroup(n->params->iparams->user, group); -} - -int NCDModuleProcess_InitId (NCDModuleProcess *o, NCDModuleInst *n, NCD_string_id_t template_name, NCDValRef args, NCDModuleProcess_handler_event handler_event) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) - ASSERT(template_name >= 0) - ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args)) - ASSERT(handler_event) - - // init arguments - o->args = args; - o->handler_event = handler_event; - - // set no special functions - o->func_getspecialobj = NULL; - - // set state - set_process_state(o, PROCESS_STATE_INIT); - -#ifndef NDEBUG - // clear interp functions so we can assert they were set - o->interp_func_event = NULL; - o->interp_func_getobj = NULL; -#endif - - // init interpreter part - if (!(n->params->iparams->func_initprocess(n->params->iparams->user, o, template_name))) { - goto fail1; - } - - ASSERT(o->interp_func_event) - ASSERT(o->interp_func_getobj) - - // set state - set_process_state(o, PROCESS_STATE_DOWN); - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - return 0; -} - -int NCDModuleProcess_InitValue (NCDModuleProcess *o, NCDModuleInst *n, NCDValRef template_name, NCDValRef args, NCDModuleProcess_handler_event handler_event) -{ - DebugObject_Access(&n->d_obj); - ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN || - n->state == STATE_UP || - n->state == STATE_DYING) - ASSERT(NCDVal_IsString(template_name)) - ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args)) - ASSERT(handler_event) - - NCD_string_id_t template_name_id; - - if (NCDVal_IsIdString(template_name)) { - template_name_id = NCDVal_IdStringId(template_name); - } else { - NCDValContString cts; - if (!NCDVal_StringContinuize(template_name, &cts)) { - BLog(BLOG_ERROR, "NCDVal_StringContinuize failed"); - return 0; - } - - template_name_id = NCDStringIndex_GetBin(n->params->iparams->string_index, cts.data, NCDVal_StringLength(template_name)); - NCDValContString_Free(&cts); - if (template_name_id < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_GetBin failed"); - return 0; - } - } - - return NCDModuleProcess_InitId(o, n, template_name_id, args, handler_event); -} - -void NCDModuleProcess_Free (NCDModuleProcess *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(o->state == PROCESS_STATE_TERMINATED) -} - -void NCDModuleProcess_AssertFree (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == PROCESS_STATE_TERMINATED) -} - -void NCDModuleProcess_SetSpecialFuncs (NCDModuleProcess *o, NCDModuleProcess_func_getspecialobj func_getspecialobj) -{ - DebugObject_Access(&o->d_obj); - - o->func_getspecialobj = func_getspecialobj; -} - -void NCDModuleProcess_Continue (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == PROCESS_STATE_DOWN_WAITING) - - set_process_state(o, PROCESS_STATE_DOWN); - - o->interp_func_event(o->interp_user, NCDMODULEPROCESS_INTERP_EVENT_CONTINUE); -} - -void NCDModuleProcess_Terminate (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP || - o->state == PROCESS_STATE_DOWN_WAITING) - - set_process_state(o, PROCESS_STATE_TERMINATING); - - o->interp_func_event(o->interp_user, NCDMODULEPROCESS_INTERP_EVENT_TERMINATE); -} - -int NCDModuleProcess_GetObj (NCDModuleProcess *o, NCD_string_id_t name, NCDObject *out_object) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state != PROCESS_STATE_INIT) - ASSERT(o->state != PROCESS_STATE_TERMINATED) - ASSERT(out_object) - - int res = o->interp_func_getobj(o->interp_user, name, out_object); - ASSERT(res == 0 || res == 1) - - return res; -} - -static void process_assert_interp (NCDModuleProcess *o) -{ - // assert that the interpreter knows about the object, and we're not in init - ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP || - o->state == PROCESS_STATE_DOWN_WAITING || o->state == PROCESS_STATE_TERMINATING) -} - -void NCDModuleProcess_Interp_SetHandlers (NCDModuleProcess *o, void *interp_user, - NCDModuleProcess_interp_func_event interp_func_event, - NCDModuleProcess_interp_func_getobj interp_func_getobj) -{ - ASSERT(o->state == PROCESS_STATE_INIT) - ASSERT(interp_func_event) - ASSERT(interp_func_getobj) - - o->interp_user = interp_user; - o->interp_func_event = interp_func_event; - o->interp_func_getobj = interp_func_getobj; -} - -void NCDModuleProcess_Interp_Up (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(o->state == PROCESS_STATE_DOWN) - - set_process_state(o, PROCESS_STATE_UP); - - o->handler_event(o, NCDMODULEPROCESS_EVENT_UP); - return; -} - -void NCDModuleProcess_Interp_Down (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(o->state == PROCESS_STATE_UP) - - set_process_state(o, PROCESS_STATE_DOWN_WAITING); - - o->handler_event(o, NCDMODULEPROCESS_EVENT_DOWN); - return; -} - -void NCDModuleProcess_Interp_Terminated (NCDModuleProcess *o) -{ - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(o->state == PROCESS_STATE_TERMINATING) - - set_process_state(o, PROCESS_STATE_TERMINATED); - - o->handler_event(o, NCDMODULEPROCESS_EVENT_TERMINATED); - return; -} - -int NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, NCD_string_id_t name, NCDObject *out_object) -{ - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(out_object) - - if (!NCDVal_IsInvalid(o->args)) { - if (name == NCD_STRING_ARGS) { - *out_object = NCDObject_Build(-1, o, process_args_object_func_getvar, NCDObject_no_getobj); - return 1; - } - - if (name >= NCD_STRING_ARG0 && name <= NCD_STRING_ARG19) { - int num = name - NCD_STRING_ARG0; - if (num < NCDVal_ListCount(o->args)) { - *out_object = NCDObject_BuildFull(-1, o, num, NULL, process_arg_object_func_getvar, NCDObject_no_getobj); - return 1; - } - } - } - - if (!o->func_getspecialobj) { - return 0; - } - - int res = o->func_getspecialobj(o, name, out_object); - ASSERT(res == 0 || res == 1) - - return res; -} - -static int process_args_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - NCDModuleProcess *o = NCDObject_DataPtr(obj); - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(!NCDVal_IsInvalid(o->args)) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out_value = NCDVal_NewCopy(mem, o->args); - if (NCDVal_IsInvalid(*out_value)) { - BLog_LogToChannel(BLOG_CHANNEL_NCDModuleProcess, BLOG_ERROR, "NCDVal_NewCopy failed"); - } - return 1; -} - -static int process_arg_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - NCDModuleProcess *o = NCDObject_DataPtr(obj); - DebugObject_Access(&o->d_obj); - process_assert_interp(o); - ASSERT(!NCDVal_IsInvalid(o->args)) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out_value = NCDVal_NewCopy(mem, NCDVal_ListGet(o->args, NCDObject_DataInt(obj))); - if (NCDVal_IsInvalid(*out_value)) { - BLog_LogToChannel(BLOG_CHANNEL_NCDModuleProcess, BLOG_ERROR, "NCDVal_NewCopy failed"); - } - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDModule.h b/external/badvpn_dns/ncd/NCDModule.h deleted file mode 100644 index c00fe90..0000000 --- a/external/badvpn_dns/ncd/NCDModule.h +++ /dev/null @@ -1,1011 +0,0 @@ -/** - * @file NCDModule.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_NCDMODULE_H -#define BADVPN_NCD_NCDMODULE_H - -#include <stdarg.h> - -#include <misc/debug.h> -#include <system/BReactor.h> -#include <base/BLog.h> -#include <ncd/NCDObject.h> -#include <ncd/NCDStringIndex.h> - -#ifndef BADVPN_NO_PROCESS -#include <system/BProcess.h> -#endif -#ifndef BADVPN_NO_UDEV -#include <udevmonitor/NCDUdevManager.h> -#endif -#ifndef BADVPN_NO_RANDOM -#include <random/BRandom2.h> -#endif - -#define NCDMODULE_EVENT_UP 1 -#define NCDMODULE_EVENT_DOWN 2 -#define NCDMODULE_EVENT_DOWNUP 3 -#define NCDMODULE_EVENT_DEAD 4 -#define NCDMODULE_EVENT_DEADERROR 5 - -struct NCDModuleInst_s; -struct NCDModuleProcess_s; -struct NCDModuleGroup; -struct NCDInterpModule; -struct NCDInterpModuleGroup; - -/** - * Function called to inform the interpeter of state changes of the - * module instance. - * Possible events are: - * - * - NCDMODULE_EVENT_UP: the instance came up. - * The instance was in down state. - * The instance enters up state. - * - * - NCDMODULE_EVENT_DOWN: the instance went down. - * The instance was in up state. - * The instance enters down state. - * - * After the instance goes down, the interpreter should eventually call - * {@link NCDModuleInst_Clean} or {@link NCDModuleInst_Die}, unless - * the module goes up again. - * - * - NCDMODULE_EVENT_DEAD: the module died. To determine if the module - * died with error, read the is_error member of {@link NCDModuleInst}. - * The instance enters dead state. - * - * This function is not being called in event context. The interpreter should - * only update its internal state, and visibly react only via jobs that it pushes - * from within this function. The only exception is that it may free the - * instance from within the NCDMODULE_EVENT_DEAD event. - * - * @param inst the module instance - * @param event event number - */ -typedef void (*NCDModuleInst_func_event) (struct NCDModuleInst_s *inst, int event); - -/** - * Function called when the module instance wants the interpreter to - * resolve an object from the point of view of its statement. - * The instance will not be in dead state. - * This function must not have any side effects. - * - * @param inst the module instance - * @param name name of the object as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModuleInst_func_getobj) (struct NCDModuleInst_s *inst, NCD_string_id_t name, NCDObject *out_object); - -/** - * Function called when the module instance wants the interpreter to - * create a new process backend from a process template. - * The instance will not be in dead state. - * - * On success, the interpreter must have called {@link NCDModuleProcess_Interp_SetHandlers} - * from within this function, to allow communication with the controller of the process. - * On success, the new process backend enters down state. - * - * This function is not being called in event context. The interpreter should - * only update its internal state, and visibly react only via jobs that it pushes - * from within this function. - * - * @param user value of 'user' member of {@link NCDModuleInst_iparams} - * @param p handle for the new process backend - * @param template_name name of the template to create the process from, - * as an {@link NCDStringIndex} identifier - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModuleInst_func_initprocess) (void *user, struct NCDModuleProcess_s *p, NCD_string_id_t template_name); - -/** - * Function called when the module instance wants the interpreter to - * initiate termination, as if it received an external terminatio request (signal). - * - * @param user value of 'user' member of {@link NCDModuleInst_iparams} - * @param exit_code exit code to return the the operating system. This overrides any previously - * set exit code, and will be overriden by a signal to the value 1. - * - */ -typedef void (*NCDModuleInst_func_interp_exit) (void *user, int exit_code); - -/** - * Function called when the module instance wants the interpreter to - * provide its extra command line arguments. - * - * @param user value of 'user' member of {@link NCDModuleInst_iparams} - * @param mem value memory to use - * @param out_value write value reference here on success - * @return 1 if available, 0 if not available. If available, but out of memory, return 1 - * and an invalid value. - */ -typedef int (*NCDModuleInst_func_interp_getargs) (void *user, NCDValMem *mem, NCDValRef *out_value); - -/** - * Function called when the module instance wants the interpreter to - * provide its retry time. - * - * @param user value of 'user' member of {@link NCDModuleInst_iparams} - * @return retry time in milliseconds - */ -typedef btime_t (*NCDModuleInst_func_interp_getretrytime) (void *user); - -/** - * Function called when the module instance wants the interpreter to - * load a new module group. - * - * @param user value of 'user' member of {@link NCDModuleInst_iparams} - * @param group module group to load - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModuleInst_func_interp_loadgroup) (void *user, const struct NCDModuleGroup *group); - -#define NCDMODULEPROCESS_EVENT_UP 1 -#define NCDMODULEPROCESS_EVENT_DOWN 2 -#define NCDMODULEPROCESS_EVENT_TERMINATED 3 - -/** - * Handler which reports process state changes from the interpreter. - * Possible events are: - * - * - NCDMODULEPROCESS_EVENT_UP: the process went up. - * The process was in down state. - * The process enters up state. - * - * - NCDMODULEPROCESS_EVENT_DOWN: the process went down. - * The process was in up state. - * The process enters waiting state. - * - * NOTE: the process enters waiting state, NOT down state, and is paused. - * To allow the process to continue, call {@link NCDModuleProcess_Continue}. - * - * - NCDMODULEPROCESS_EVENT_TERMINATED: the process terminated. - * The process was in terminating state. - * The process enters terminated state. - * - * @param user pointer to the process. Use {@link UPPER_OBJECT} to retrieve the pointer - * to the containing struct. - * @param event event number - */ -typedef void (*NCDModuleProcess_handler_event) (struct NCDModuleProcess_s *process, int event); - -/** - * Function called when the interpreter wants to resolve a special - * object in the process. - * This function must have no side effects. - * - * @param user pointer to the process. Use {@link UPPER_OBJECT} to retrieve the pointer - * to the containing struct. - * @param name name of the object as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModuleProcess_func_getspecialobj) (struct NCDModuleProcess_s *process, NCD_string_id_t name, NCDObject *out_object); - -#define NCDMODULEPROCESS_INTERP_EVENT_CONTINUE 1 -#define NCDMODULEPROCESS_INTERP_EVENT_TERMINATE 2 - -/** - * Function called to report process backend requests to the interpreter. - * Possible events are: - * - * - NCDMODULEPROCESS_INTERP_EVENT_CONTINUE: the process can continue. - * The process backend was in waiting state. - * The process backend enters down state. - * - * - NCDMODULEPROCESS_INTERP_EVENT_TERMINATE: the process should terminate. - * The process backend was in down, up or waiting state. - * The process backend enters terminating state. - * - * The interpreter should call {@link NCDModuleProcess_Interp_Terminated} - * when the process terminates. - * - * This function is not being called in event context. The interpreter should - * only update its internal state, and visibly react only via jobs that it pushes - * from within this function. - * - * @param user as in {@link NCDModuleProcess_Interp_SetHandlers} - * @param event event number - */ -typedef void (*NCDModuleProcess_interp_func_event) (void *user, int event); - -/** - * Function called to have the interpreter resolve an object within the process - * of a process backend. - * This function must not have any side effects. - * - * @param user as in {@link NCDModuleProcess_Interp_SetHandlers} - * @param name name of the object as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 in failure - */ -typedef int (*NCDModuleProcess_interp_func_getobj) (void *user, NCD_string_id_t name, NCDObject *out_object); - -struct NCDModule; - -/** - * Contains parameters to the module initialization function - * ({@link NCDModule_func_new2}) that are passed indirectly. - */ -struct NCDModuleInst_new_params { - /** - * A reference to the argument list for the module instance. - * The reference remains valid as long as the backend instance - * exists. Unless the module has the NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - * flag set, it is guaranteed that any strings within the arguments will be - * some kind of ContinuousString. - */ - NCDValRef args; - - /** - * If the module instance corresponds to a method-like statement, - * this pointer identifies the object it is being invoked with. - * If the object is a statement (i.e. a {@link NCDModuleInst}), then this - * will be the NCDModuleInst pointer, and {@link NCDModuleInst_Backend_GetUser} - * can be called on this to retrieve the pointer to preallocated memory for - * the backend instance; *unless* {@link NCDModuleInst_Backend_PassMemToMethods} - * was called for the object on which the method is being called, in which case - * this will directly point to the preallocated memory. - * On the other hand, if this is a method on an internal object built using - * only {@link NCDObject_Build} or {@link NCDObject_BuildFull}, - * this pointer will be whatever was passed as the "data_ptr" argument, for the - * first function, and as "method_user", for the latter function. - */ - void *method_user; -}; - -/** - * Contains parameters to {@link NCDModuleInst_Init} that are passed indirectly. - * This itself only contains parameters related to communication between the - * backend and the creator of the module instance; other parameters are passed - * via the iparams member; - */ -struct NCDModuleInst_params { - /** - * Callback to report state changes. - */ - NCDModuleInst_func_event func_event; - /** - * Callback to resolve objects from the viewpoint of the instance. - */ - NCDModuleInst_func_getobj func_getobj; - /** - * Log function which appends a log prefix with {@link BLog_Append}. - */ - BLog_logfunc logfunc; - /** - * Pointer to an {@link NCDModuleInst_iparams} structure, which exposes - * services provided by the interpreter. - */ - const struct NCDModuleInst_iparams *iparams; -}; - -/** - * Contains parameters to {@link NCDModuleInst_Init} that are passed indirectly. - * This only contains parameters related to services provided by the interpreter. - */ -struct NCDModuleInst_iparams { - /** - * Reactor we live in. - */ - BReactor *reactor; -#ifndef BADVPN_NO_PROCESS - /** - * Process manager. - */ - BProcessManager *manager; -#endif -#ifndef BADVPN_NO_UDEV - /** - * Udev manager. - */ - NCDUdevManager *umanager; -#endif -#ifndef BADVPN_NO_RANDOM - /** - * Random number generator. - */ - BRandom2 *random2; -#endif - /** - * String index which keeps a mapping between strings and string identifiers. - */ - NCDStringIndex *string_index; - /** - * Pointer passed to the interpreter callbacks below, for state keeping. - */ - void *user; - /** - * Callback to create a new template process. - */ - NCDModuleInst_func_initprocess func_initprocess; - /** - * Callback to request interpreter termination. - */ - NCDModuleInst_func_interp_exit func_interp_exit; - /** - * Callback to get extra command line arguments. - */ - NCDModuleInst_func_interp_getargs func_interp_getargs; - /** - * Callback to get retry time. - */ - NCDModuleInst_func_interp_getretrytime func_interp_getretrytime; - /** - * Callback to load a module group. - */ - NCDModuleInst_func_interp_loadgroup func_loadgroup; -}; - -/** - * Module instance. - * The module instance is initialized by the interpreter by calling - * {@link NCDModuleInst_Init}. It is implemented by a module backend - * specified in a {@link NCDModule}. - */ -typedef struct NCDModuleInst_s { - const struct NCDInterpModule *m; - const struct NCDModuleInst_params *params; - void *mem; // not modified by NCDModuleInst (but passed to module) - unsigned int state:3; - unsigned int pass_mem_to_methods:1; - unsigned int istate:3; // untouched by NCDModuleInst - DebugObject d_obj; -} NCDModuleInst; - -/** - * Process created from a process template on behalf of a module backend - * instance, implemented by the interpreter. - */ -typedef struct NCDModuleProcess_s { - NCDValRef args; - NCDModuleProcess_handler_event handler_event; - NCDModuleProcess_func_getspecialobj func_getspecialobj; - void *interp_user; - NCDModuleProcess_interp_func_event interp_func_event; - NCDModuleProcess_interp_func_getobj interp_func_getobj; -#ifndef NDEBUG - int state; -#endif - DebugObject d_obj; -} NCDModuleProcess; - -/** - * Initializes an instance of an NCD module. - * The instance is initialized in down state. - * WARNING: this directly calls the module backend; expect to be called back - * - * This and other non-Backend methods are the interpreter interface. - * The Backend methods are the module backend interface and are documented - * independently with their own logical states. - * - * NOTE: the instance structure \a n should have the member 'mem' initialized - * to point to preallocated memory for the statement. This memory must be - * at least m->prealloc_size big and must be properly aligned for any object. - * The 'mem' pointer is never modified by NCDModuleInst, so that the interpreter - * can use it as outside the lifetime of NCDModuleInst. - * - * @param n the instance - * @param m pointer to the {@link NCDInterpModule} structure representing the module - * to be instantiated - * @param method_context a context pointer passed to the module backend, applicable to method-like - * statements only. This should be set to the 'user' member of the - * {@link NCDObject} which represents the base object for the method. - * The caller must ensure that the NCDObject that was used is of the type - * expected by the module being instanciated. - * @param args arguments to the module. Must be a list value. Must be available and unchanged - * as long as the instance exists. Unless the module has the - * NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS flag set, any strings within the - * arguments must be some kind of ContinuousString. This can be ensured by calling - * {@link NCDValMem_ConvertNonContinuousStrings}. - * @param user argument to callback functions - * @param params more parameters, see {@link NCDModuleInst_params} - */ -void NCDModuleInst_Init (NCDModuleInst *n, const struct NCDInterpModule *m, void *method_context, NCDValRef args, const struct NCDModuleInst_params *params); - -/** - * Frees the instance. - * The instance must be in dead state. - * - * @param n the instance - */ -void NCDModuleInst_Free (NCDModuleInst *n); - -/** - * Requests the instance to die. - * The instance must be in down or up state. - * The instance enters dying state. - * WARNING: this directly calls the module backend; expect to be called back - * - * @param n the instance - */ -void NCDModuleInst_Die (NCDModuleInst *n); - -/** - * Attempts to destroy the instance immediately. - * This function can be used to optimize destroying instances of modules which - * don't specify any {@link NCDModule_func_die} handler. If immediate destruction - * is not possible, this does nothing and returns 0; {@link NCDModuleInst_Die} - * should be used to destroy the instance instead. If however immediate destruction - * is possible, this destroys the module instance and returns 1; {@link NCDModuleInst_Free} - * must not be called after that. - * The instance must be in down or up state, as for {@link NCDModuleInst_Die}. - * - * @param n the instance - * @return 1 if destruction was performed, 0 if not - */ -int NCDModuleInst_TryFree (NCDModuleInst *n); - -/** - * Informs the module that it is in a clean state to proceed. - * The instance must be in down state. - * WARNING: this directly calls the module backend; expect to be called back - * - * @param n the instance - */ -void NCDModuleInst_Clean (NCDModuleInst *n); - -/** - * Returns an {@link NCDObject} which can be used to resolve variables and objects - * within this instance, as well as call its methods. The resulting object may only - * be used immediately, and becomes invalid when the instance is freed. - * - * @param n the instance - * @return an NCDObject for this instance - */ -NCDObject NCDModuleInst_Object (NCDModuleInst *n); - -/** - * If this is called, any methods called on this object will receive the preallocated - * memory pointer as the object state pointer. This means that in the - * {@link NCDModule_func_getvar2} function which is called when a method is created, - * the preallocated memory should be accessed as params->method_user. - * By default, however, params->method_user points to the NCDModuleInst of the base - * object, and {@link NCDModuleInst_Backend_GetUser} is needed to retrieve the - * preallocated memory pointer. - */ -void NCDModuleInst_Backend_PassMemToMethods (NCDModuleInst *n); - -/** - * Retuns the state pointer passed to handlers of a module backend instance; - * see {@link NCDModule_func_new2}. - * - * @param n backend instance handle - * @return argument passed to handlers - */ -void * NCDModuleInst_Backend_GetUser (NCDModuleInst *n); - -/** - * Puts the backend instance into up state. - * The instance must be in down state. - * The instance enters up state. - * - * @param n backend instance handle - */ -void NCDModuleInst_Backend_Up (NCDModuleInst *n); - -/** - * Puts the backend instance into down state. - * The instance must be in up state. - * The instance enters down state. - * - * @param n backend instance handle - */ -void NCDModuleInst_Backend_Down (NCDModuleInst *n); - -/** - * Puts the backend instance into down state, then immediatly back into the up state. - * This effectively causes the interpreter to start backtracking to this statement. - * The instance must be in up state, and remains in up state. - * - * @param n backend instance handle - */ -void NCDModuleInst_Backend_DownUp (NCDModuleInst *n); - -/** - * Destroys the backend instance. - * The backend instance handle becomes invalid and must not be used from - * the backend any longer. - * - * @param n backend instance handle - */ -void NCDModuleInst_Backend_Dead (NCDModuleInst *n); - -/** - * Like {@link NCDModuleInst_Backend_Dead}, but also reports an error condition - * to the interpreter. - */ -void NCDModuleInst_Backend_DeadError (NCDModuleInst *n); - -/** - * Resolves an object for a backend instance, from the point of the instance's - * statement in the containing process. - * - * @param n backend instance handle - * @param name name of the object to resolve as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -int NCDModuleInst_Backend_GetObj (NCDModuleInst *n, NCD_string_id_t name, NCDObject *out_object) WARN_UNUSED; - -/** - * Logs a backend instance message. - * - * @param n backend instance handle - * @param channel log channel - * @param level loglevel - * @param fmt format string as in printf, arguments follow - */ -void NCDModuleInst_Backend_Log (NCDModuleInst *n, int channel, int level, const char *fmt, ...); - -/** - * Like {@link NCDModuleInst_Backend_Log}, but the extra arguments are passed - * as a va_list. This allows creation of logging wrappers. - */ -void NCDModuleInst_Backend_LogVarArg (NCDModuleInst *n, int channel, int level, const char *fmt, va_list vl); - -/** - * Returns a logging context. The context is valid until the backend dies. - */ -BLogContext NCDModuleInst_Backend_LogContext (NCDModuleInst *n); - -/** - * Initiates interpreter termination. - * - * @param n backend instance handle - * @param exit_code exit code to return to the operating system. This overrides - * any previously set exit code, and will be overriden by a - * termination signal to the value 1. - */ -void NCDModuleInst_Backend_InterpExit (NCDModuleInst *n, int exit_code); - -/** - * Retrieves extra command line arguments passed to the interpreter. - * - * @param n backend instance handle - * @param mem value memory to use - * @param out_value the arguments will be written here on success as a list value - * @return 1 if available, 0 if not available. If available, but out of memory, returns 1 - * and an invalid value. - */ -int NCDModuleInst_Backend_InterpGetArgs (NCDModuleInst *n, NCDValMem *mem, NCDValRef *out_value); - -/** - * Returns the retry time of the intepreter. - * - * @param n backend instance handle - * @return retry time in milliseconds - */ -btime_t NCDModuleInst_Backend_InterpGetRetryTime (NCDModuleInst *n); - -/** - * Loads a module group into the interpreter. - * - * @param n backend instance handle - * @param group module group to load - * @return 1 on success, 0 on failure - */ -int NCDModuleInst_Backend_InterpLoadGroup (NCDModuleInst *n, const struct NCDModuleGroup *group); - -/** - * Initializes a process in the interpreter from a process template. - * This must be called on behalf of a module backend instance. - * The process is initializes in down state. - * - * @param o the process - * @param n backend instance whose interpreter will be providing the process - * @param template_name name of the process template as an {@link NCDStringIndex} identifier - * @param args arguments to the process. Must be an invalid value or a list value. - * The value must be available and unchanged while the process exists. - * @param handler_event handler which reports events about the process from the - * interpreter - * @return 1 on success, 0 on failure - */ -int NCDModuleProcess_InitId (NCDModuleProcess *o, NCDModuleInst *n, NCD_string_id_t template_name, NCDValRef args, NCDModuleProcess_handler_event handler_event) WARN_UNUSED; - -/** - * Wrapper around {@link NCDModuleProcess_InitId} which takes the template name as an - * {@link NCDValRef}, which must point to a string value. - */ -int NCDModuleProcess_InitValue (NCDModuleProcess *o, NCDModuleInst *n, NCDValRef template_name, NCDValRef args, NCDModuleProcess_handler_event handler_event) WARN_UNUSED; - -/** - * Frees the process. - * The process must be in terminated state. - * - * @param o the process - */ -void NCDModuleProcess_Free (NCDModuleProcess *o); - -/** - * Does nothing. - * The process must be in terminated state. - * - * @param o the process - */ -void NCDModuleProcess_AssertFree (NCDModuleProcess *o); - -/** - * Sets callback functions for providing special objects within the process. - * - * @param o the process - * @param func_getspecialobj function for resolving special objects, or NULL - */ -void NCDModuleProcess_SetSpecialFuncs (NCDModuleProcess *o, NCDModuleProcess_func_getspecialobj func_getspecialobj); - -/** - * Continues the process after the process went down. - * The process must be in waiting state. - * The process enters down state. - * - * @param o the process - */ -void NCDModuleProcess_Continue (NCDModuleProcess *o); - -/** - * Requests the process to terminate. - * The process must be in down, up or waiting state. - * The process enters terminating state. - * - * @param o the process - */ -void NCDModuleProcess_Terminate (NCDModuleProcess *o); - -/** - * Resolves an object within the process from the point - * at the end of the process. - * This function has no side effects. - * - * @param o the process - * @param name name of the object to resolve as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -int NCDModuleProcess_GetObj (NCDModuleProcess *o, NCD_string_id_t name, NCDObject *out_object) WARN_UNUSED; - -/** - * Sets callback functions for the interpreter to implement the - * process backend. - * Must be called from within {@link NCDModuleInst_func_initprocess} - * if success is to be reported there. - * - * @param o process backend handle, as in {@link NCDModuleInst_func_initprocess} - * @param interp_user argument to callback functions - * @param interp_func_event function for reporting continue/terminate requests - * @param interp_func_getobj function for resolving objects within the process - */ -void NCDModuleProcess_Interp_SetHandlers (NCDModuleProcess *o, void *interp_user, - NCDModuleProcess_interp_func_event interp_func_event, - NCDModuleProcess_interp_func_getobj interp_func_getobj); - -/** - * Reports the process backend as up. - * The process backend must be in down state. - * The process backend enters up state. - * WARNING: this directly calls the process creator; expect to be called back - * - * @param o process backend handle - */ -void NCDModuleProcess_Interp_Up (NCDModuleProcess *o); - -/** - * Reports the process backend as down. - * The process backend must be in up state. - * The process backend enters waiting state. - * WARNING: this directly calls the process creator; expect to be called back - * - * NOTE: the backend enters waiting state, NOT down state. The interpreter should - * pause the process until {@link NCDModuleProcess_interp_func_event} reports - * NCDMODULEPROCESS_INTERP_EVENT_CONTINUE, unless termination is requested via - * NCDMODULEPROCESS_INTERP_EVENT_TERMINATE. - * - * @param o process backend handle - */ -void NCDModuleProcess_Interp_Down (NCDModuleProcess *o); - -/** - * Reports termination of the process backend. - * The process backend must be in terminating state. - * The process backend handle becomes invalid and must not be used - * by the interpreter any longer. - * WARNING: this directly calls the process creator; expect to be called back - * - * @param o process backend handle - */ -void NCDModuleProcess_Interp_Terminated (NCDModuleProcess *o); - -/** - * Resolves a special process object for the process backend. - * - * @param o process backend handle - * @param name name of the object as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -int NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, NCD_string_id_t name, NCDObject *out_object) WARN_UNUSED; - -/** - * Function called before any instance of any backend in a module - * group is created; - * - * @param params structure containing global resources, such as - * {@link BReactor}, {@link BProcessManager} and {@link NCDUdevManager}. - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModule_func_globalinit) (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params); - -/** - * Function called to clean up after {@link NCDModule_func_globalinit} and modules - * in a module group. - * There are no backend instances alive from this module group. - */ -typedef void (*NCDModule_func_globalfree) (struct NCDInterpModuleGroup *group); - -/** - * Handler called to create an new module backend instance. - * The backend is initialized in down state. - * - * If the backend fails initialization, this function should report the backend - * instance to have died with error by calling {@link NCDModuleInst_Backend_DeadError}. - * - * @param o if the module specifies a positive alloc_size value in the {@link NCDModule} - * structure, this will point to the allocated memory that can be used by the - * module instance while it exists. If the alloc_size is 0 (default), this may or - * may not be NULL. - * @param i module backend instance handler. The backend may only use this handle via - * the Backend functions of {@link NCDModuleInst}. - */ -typedef void (*NCDModule_func_new2) (void *o, NCDModuleInst *i, const struct NCDModuleInst_new_params *params); - -/** - * Handler called to request termination of a backend instance. - * The backend instance was in down or up state. - * The backend instance enters dying state. - * - * @param o state pointer, as in {@link NCDModule_func_new2} - */ -typedef void (*NCDModule_func_die) (void *o); - -/** - * Function called to resolve a variable within a backend instance. - * The backend instance is in up state, or in up or down state if can_resolve_when_down=1. - * This function must not have any side effects. - * - * @param o state pointer, as in {@link NCDModule_func_new2} - * @param name name of the variable to resolve - * @param mem value memory to use - * @param out on success, the backend should initialize the value here - * @return 1 if exists, 0 if not exists. If exists, but out of memory, return 1 - * and an invalid value. - */ -typedef int (*NCDModule_func_getvar) (void *o, const char *name, NCDValMem *mem, NCDValRef *out); - -/** - * Function called to resolve a variable within a backend instance. - * The backend instance is in up state, or in up or down state if can_resolve_when_down=1. - * This function must not have any side effects. - * - * @param o state pointer, as in {@link NCDModule_func_new2} - * @param name name of the variable to resolve as an {@link NCDStringIndex} identifier - * @param mem value memory to use - * @param out on success, the backend should initialize the value here - * @return 1 if exists, 0 if not exists. If exists, but out of memory, return 1 - * and an invalid value. - */ -typedef int (*NCDModule_func_getvar2) (void *o, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); - -/** - * Function called to resolve an object within a backend instance. - * The backend instance is in up state, or in up or down state if can_resolve_when_down=1. - * This function must not have any side effects. - * - * @param o state pointer, as in {@link NCDModule_func_new2} - * @param name name of the object to resolve as an {@link NCDStringIndex} identifier - * @param out_object the object will be returned here - * @return 1 on success, 0 on failure - */ -typedef int (*NCDModule_func_getobj) (void *o, NCD_string_id_t name, NCDObject *out_object); - -/** - * Handler called when the module instance is in a clean state. - * This means that all statements preceding it in the process are - * up, this statement is down, and all following statements are - * uninitialized. When a backend instance goes down, it is guaranteed, - * as long as it stays down, that either this will be called or - * termination will be requested with {@link NCDModule_func_die}. - * The backend instance was in down state. - * - * @param o state pointer, as in {@link NCDModule_func_new2} - */ -typedef void (*NCDModule_func_clean) (void *o); - -#define NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN (1 << 0) -#define NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS (1 << 1) - -/** - * Structure encapsulating the implementation of a module backend. - */ -struct NCDModule { - /** - * If this implements a plain statement, the name of the statement. - * If this implements a method, then "base_type::method_name". - */ - const char *type; - - /** - * The base type for methods operating on instances of this backend. - * Any module with type of form "base_type::method_name" is considered - * a method of instances of this backend. - * If this is NULL, the base type will default to type. - */ - const char *base_type; - - /** - * Function called to create an new backend instance. - */ - NCDModule_func_new2 func_new2; - - /** - * Function called to request termination of a backend instance. - * May be NULL, in which case the default is to call NCDModuleInst_Backend_Dead(). - */ - NCDModule_func_die func_die; - - /** - * Function called to resolve a variable within the backend instance. - * May be NULL. - */ - NCDModule_func_getvar func_getvar; - - /** - * Function called to resolve a variable within the backend instance. - * May be NULL. - */ - NCDModule_func_getvar2 func_getvar2; - - /** - * Function called to resolve an object within the backend instance. - * May be NULL. - */ - NCDModule_func_getobj func_getobj; - - /** - * Function called when the backend instance is in a clean state. - * May be NULL. - */ - NCDModule_func_clean func_clean; - - /** - * Various flags. - * - * - NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN - * Whether the interpreter is allowed to call func_getvar and func_getobj - * even when the backend instance is in down state (as opposed to just - * in up state. - * - * - NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - * If not set, strings within arguments which are not some kind of ContinuousString - * will be converted to some kind of ContinuousString before the module's init - * function is called. If set, they will not be, and the module must work with any - * kind of strings (i.e. {@link NCDVal_StringData} may not be allowed). - */ - int flags; - - /** - * The amount of memory to preallocate for each module instance. - * Preallocation can be used to avoid having to allocate memory from - * module initialization. The memory can be accessed via the first - * argument to {@link NCDModule_func_new2} and other calls. - */ - int alloc_size; -}; - -/** - * Structure encapsulating a group of module backend implementations, - * with global init and free functions. - */ -struct NCDModuleGroup { - /** - * Function called before any instance of any module backend in this - * group is crated. May be NULL. - */ - NCDModule_func_globalinit func_globalinit; - - /** - * Function called to clean up after {@link NCDModule_func_globalinit}. - * May be NULL. - */ - NCDModule_func_globalfree func_globalfree; - - /** - * Array of module backends. The array must be terminated with a - * structure that has a NULL type member. - */ - const struct NCDModule *modules; - - /** - * A pointer to an array of strings which will be mapped to - * {@link NCDStringIndex} string identifiers for the module to use. - * The array must be terminated by NULL. The resulting string - * identifiers will be available in the 'strings' member in - * {@link NCDInterpModuleGroup}. - */ - const char *const*strings; -}; - -/** - * Represents an {@link NCDModule} within an interpreter. - * This structure is initialized by the interpreter when it loads a module group. - */ -struct NCDInterpModule { - /** - * A copy of the original NCDModule structure, - */ - struct NCDModule module; - - /** - * The string identifier of this module's base_type (or type if base_type is - * not specified) according to {@link NCDStringIndex}. - */ - NCD_string_id_t base_type_id; - - /** - * A pointer to the {@link NCDInterpModuleGroup} representing the group - * this module belongs to. - */ - struct NCDInterpModuleGroup *group; -}; - -/** - * Represents an {@link NCDModuleGroup} within an interpreter. - * This structure is initialized by the interpreter when it loads a module group. - */ -struct NCDInterpModuleGroup { - /** - * A copy of the original NCDModuleGroup structure. - */ - struct NCDModuleGroup group; - - /** - * An array of string identifiers corresponding to the strings - * in the 'strings' member of NCDModuleGroup. May be NULL if there - * are no strings in the NCDModuleGroup. - */ - NCD_string_id_t *strings; - - /** - * Pointer which allows the module to keep private interpreter-wide state. - * This can be freely modified by the module; the interpeter will not - * read or write it. - */ - void *group_state; -}; - -#endif diff --git a/external/badvpn_dns/ncd/NCDModuleIndex.c b/external/badvpn_dns/ncd/NCDModuleIndex.c deleted file mode 100644 index 12ef48a..0000000 --- a/external/badvpn_dns/ncd/NCDModuleIndex.c +++ /dev/null @@ -1,372 +0,0 @@ -/** - * @file NCDModuleIndex.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdlib.h> - -#include <misc/offset.h> -#include <misc/balloc.h> -#include <misc/bsize.h> -#include <misc/hashfun.h> -#include <misc/compare.h> -#include <misc/substring.h> -#include <base/BLog.h> - -#include "NCDModuleIndex.h" - -#include <generated/blog_channel_NCDModuleIndex.h> - -#include "NCDModuleIndex_mhash.h" -#include <structure/CHash_impl.h> - -static int string_pointer_comparator (void *user, void *v1, void *v2) -{ - const char **s1 = v1; - const char **s2 = v2; - int cmp = strcmp(*s1, *s2); - return B_COMPARE(cmp, 0); -} - -static struct NCDModuleIndex_module * find_module (NCDModuleIndex *o, const char *type) -{ - NCDModuleIndex__MHashRef ref = NCDModuleIndex__MHash_Lookup(&o->modules_hash, 0, type); - ASSERT(!ref.link || !strcmp(ref.link->imodule.module.type, type)) - return ref.link; -} - -#ifndef NDEBUG -static struct NCDModuleIndex_base_type * find_base_type (NCDModuleIndex *o, const char *base_type) -{ - BAVLNode *node = BAVL_LookupExact(&o->base_types_tree, &base_type); - if (!node) { - return NULL; - } - - struct NCDModuleIndex_base_type *bt = UPPER_OBJECT(node, struct NCDModuleIndex_base_type, base_types_tree_node); - ASSERT(!strcmp(bt->base_type, base_type)) - - return bt; -} -#endif - -static int add_method (const char *type, const struct NCDInterpModule *module, NCDMethodIndex *method_index, int *out_method_id) -{ - ASSERT(type) - ASSERT(module) - ASSERT(method_index) - ASSERT(out_method_id) - - const char search[] = "::"; - size_t search_len = sizeof(search) - 1; - - size_t table[sizeof(search) - 1]; - build_substring_backtrack_table_reverse(search, search_len, table); - - size_t pos; - if (!find_substring_reverse(type, strlen(type), search, search_len, table, &pos)) { - *out_method_id = -1; - return 1; - } - - ASSERT(pos >= 0) - ASSERT(pos <= strlen(type) - search_len) - ASSERT(!memcmp(type + pos, search, search_len)) - - int method_id = NCDMethodIndex_AddMethod(method_index, type, pos, type + pos + search_len, module); - if (method_id < 0) { - BLog(BLOG_ERROR, "NCDMethodIndex_AddMethod failed"); - return 0; - } - - *out_method_id = method_id; - return 1; -} - -int NCDModuleIndex_Init (NCDModuleIndex *o, NCDStringIndex *string_index) -{ - ASSERT(string_index) - - // init modules hash - if (!NCDModuleIndex__MHash_Init(&o->modules_hash, NCDMODULEINDEX_MODULES_HASH_SIZE)) { - BLog(BLOG_ERROR, "NCDModuleIndex__MHash_Init failed"); - goto fail0; - } - -#ifndef NDEBUG - // init base types tree - BAVL_Init(&o->base_types_tree, OFFSET_DIFF(struct NCDModuleIndex_base_type, base_type, base_types_tree_node), string_pointer_comparator, NULL); -#endif - - // init groups list - LinkedList0_Init(&o->groups_list); - - // init method index - if (!NCDMethodIndex_Init(&o->method_index, string_index)) { - BLog(BLOG_ERROR, "NCDMethodIndex_Init failed"); - goto fail1; - } - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - NCDModuleIndex__MHash_Free(&o->modules_hash); -fail0: - return 0; -} - -void NCDModuleIndex_Free (NCDModuleIndex *o) -{ - DebugObject_Free(&o->d_obj); - - // free groups - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&o->groups_list)) { - struct NCDModuleIndex_group *ig = UPPER_OBJECT(ln, struct NCDModuleIndex_group, groups_list_node); - if (ig->igroup.group.func_globalfree) { - ig->igroup.group.func_globalfree(&ig->igroup); - } - BFree(ig->igroup.strings); - LinkedList0_Remove(&o->groups_list, &ig->groups_list_node); - BFree(ig); - } - -#ifndef NDEBUG - // free base types - BAVLNode *tn; - while (tn = BAVL_GetFirst(&o->base_types_tree)) { - struct NCDModuleIndex_base_type *bt = UPPER_OBJECT(tn, struct NCDModuleIndex_base_type, base_types_tree_node); - BAVL_Remove(&o->base_types_tree, &bt->base_types_tree_node); - BFree(bt); - } -#endif - - // free method index - NCDMethodIndex_Free(&o->method_index); - - // free modules hash - NCDModuleIndex__MHash_Free(&o->modules_hash); -} - -int NCDModuleIndex_AddGroup (NCDModuleIndex *o, const struct NCDModuleGroup *group, const struct NCDModuleInst_iparams *iparams, NCDStringIndex *string_index) -{ - DebugObject_Access(&o->d_obj); - ASSERT(group) - ASSERT(iparams) - ASSERT(string_index) - - // count modules in the group - size_t num_modules = 0; - while (group->modules[num_modules].type) { - num_modules++; - } - - // compute allocation size - bsize_t size = bsize_add(bsize_fromsize(sizeof(struct NCDModuleIndex_group)), bsize_mul(bsize_fromsize(num_modules), bsize_fromsize(sizeof(struct NCDModuleIndex_module)))); - - // allocate group - struct NCDModuleIndex_group *ig = BAllocSize(size); - if (!ig) { - BLog(BLOG_ERROR, "BAllocSize failed"); - goto fail0; - } - - // insert to groups list - LinkedList0_Prepend(&o->groups_list, &ig->groups_list_node); - - // copy NCDModuleGroup - ig->igroup.group = *group; - - if (!group->strings) { - // not resolving strings - ig->igroup.strings = NULL; - } else { - // compute number of strings - size_t num_strings = 0; - while (group->strings[num_strings]) { - num_strings++; - } - - // allocate array for string IDs - ig->igroup.strings = BAllocArray(num_strings, sizeof(ig->igroup.strings[0])); - if (!ig->igroup.strings) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail1; - } - - // map strings to IDs - for (size_t i = 0; i < num_strings; i++) { - ig->igroup.strings[i] = NCDStringIndex_Get(string_index, group->strings[i]); - if (ig->igroup.strings[i] < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto fail2; - } - } - } - - // call group init function - if (group->func_globalinit) { - if (!group->func_globalinit(&ig->igroup, iparams)) { - BLog(BLOG_ERROR, "func_globalinit failed"); - goto fail2; - } - } - - size_t num_inited_modules = 0; - - // initialize modules - for (size_t i = 0; i < num_modules; i++) { - const struct NCDModule *nm = &group->modules[i]; - struct NCDModuleIndex_module *m = &ig->modules[i]; - - // make sure a module with this name doesn't exist already - if (find_module(o, nm->type)) { - BLog(BLOG_ERROR, "module type '%s' already exists", nm->type); - goto loop_fail0; - } - - // copy NCDModule structure - m->imodule.module = *nm; - - // determine base type - const char *base_type = (nm->base_type ? nm->base_type : nm->type); - ASSERT(base_type) - - // map base type to ID - m->imodule.base_type_id = NCDStringIndex_Get(string_index, base_type); - if (m->imodule.base_type_id < 0) { - BLog(BLOG_ERROR, "NCDStringIndex_Get failed"); - goto loop_fail0; - } - - // set group pointer - m->imodule.group = &ig->igroup; - - // register method - if (!add_method(nm->type, &m->imodule, &o->method_index, &m->method_id)) { - goto loop_fail0; - } - -#ifndef NDEBUG - // ensure that this base_type does not appear in any other groups - struct NCDModuleIndex_base_type *bt = find_base_type(o, base_type); - if (bt) { - if (bt->group != ig) { - BLog(BLOG_ERROR, "module base type '%s' already exists in another module group", base_type); - goto loop_fail1; - } - } else { - if (!(bt = BAlloc(sizeof(*bt)))) { - BLog(BLOG_ERROR, "BAlloc failed"); - goto loop_fail1; - } - bt->base_type = base_type; - bt->group = ig; - ASSERT_EXECUTE(BAVL_Insert(&o->base_types_tree, &bt->base_types_tree_node, NULL)) - } -#endif - - // insert to modules hash - NCDModuleIndex__MHashRef ref = {m, m}; - int res = NCDModuleIndex__MHash_Insert(&o->modules_hash, 0, ref, NULL); - ASSERT_EXECUTE(res) - - num_inited_modules++; - continue; - -#ifndef NDEBUG - loop_fail1: - if (m->method_id >= 0) { - NCDMethodIndex_RemoveMethod(&o->method_index, m->method_id); - } -#endif - loop_fail0: - goto fail3; - } - - return 1; - -fail3: - while (num_inited_modules-- > 0) { - struct NCDModuleIndex_module *m = &ig->modules[num_inited_modules]; - NCDModuleIndex__MHashRef ref = {m, m}; - NCDModuleIndex__MHash_Remove(&o->modules_hash, 0, ref); -#ifndef NDEBUG - const struct NCDModule *nm = &group->modules[num_inited_modules]; - const char *base_type = (nm->base_type ? nm->base_type : nm->type); - struct NCDModuleIndex_base_type *bt = find_base_type(o, base_type); - if (bt) { - ASSERT(bt->group == ig) - BAVL_Remove(&o->base_types_tree, &bt->base_types_tree_node); - BFree(bt); - } -#endif - if (m->method_id >= 0) { - NCDMethodIndex_RemoveMethod(&o->method_index, m->method_id); - } - } - if (group->func_globalfree) { - group->func_globalfree(&ig->igroup); - } -fail2: - BFree(ig->igroup.strings); -fail1: - LinkedList0_Remove(&o->groups_list, &ig->groups_list_node); - BFree(ig); -fail0: - return 0; -} - -const struct NCDInterpModule * NCDModuleIndex_FindModule (NCDModuleIndex *o, const char *type) -{ - DebugObject_Access(&o->d_obj); - ASSERT(type) - - struct NCDModuleIndex_module *m = find_module(o, type); - if (!m) { - return NULL; - } - - return &m->imodule; -} - -int NCDModuleIndex_GetMethodNameId (NCDModuleIndex *o, const char *method_name) -{ - DebugObject_Access(&o->d_obj); - ASSERT(method_name) - - return NCDMethodIndex_GetMethodNameId(&o->method_index, method_name); -} - -const struct NCDInterpModule * NCDModuleIndex_GetMethodModule (NCDModuleIndex *o, NCD_string_id_t obj_type, int method_name_id) -{ - DebugObject_Access(&o->d_obj); - - return NCDMethodIndex_GetMethodModule(&o->method_index, obj_type, method_name_id); -} diff --git a/external/badvpn_dns/ncd/NCDModuleIndex.h b/external/badvpn_dns/ncd/NCDModuleIndex.h deleted file mode 100644 index f7cc255..0000000 --- a/external/badvpn_dns/ncd/NCDModuleIndex.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file NCDModuleIndex.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDMODULEINDEX_H -#define BADVPN_NCDMODULEINDEX_H - -#include <misc/debug.h> -#include <structure/BAVL.h> -#include <structure/CHash.h> -#include <structure/LinkedList0.h> -#include <base/DebugObject.h> -#include <ncd/NCDModule.h> -#include <ncd/NCDMethodIndex.h> - -#define NCDMODULEINDEX_MODULES_HASH_SIZE 512 - -struct NCDModuleIndex_module { - struct NCDInterpModule imodule; - struct NCDModuleIndex_module *hash_next; - int method_id; -}; - -#ifndef NDEBUG -struct NCDModuleIndex_base_type { - const char *base_type; - struct NCDModuleIndex_group *group; - BAVLNode base_types_tree_node; -}; -#endif - -struct NCDModuleIndex_group { - LinkedList0Node groups_list_node; - struct NCDInterpModuleGroup igroup; - struct NCDModuleIndex_module modules[]; -}; - -typedef struct NCDModuleIndex_module *NCDModuleIndex__mhash_link; -typedef const char *NCDModuleIndex__mhash_key; - -#include "NCDModuleIndex_mhash.h" -#include <structure/CHash_decl.h> - -typedef struct { - NCDModuleIndex__MHash modules_hash; -#ifndef NDEBUG - BAVL base_types_tree; -#endif - LinkedList0 groups_list; - NCDMethodIndex method_index; - DebugObject d_obj; -} NCDModuleIndex; - -int NCDModuleIndex_Init (NCDModuleIndex *o, NCDStringIndex *string_index) WARN_UNUSED; -void NCDModuleIndex_Free (NCDModuleIndex *o); -int NCDModuleIndex_AddGroup (NCDModuleIndex *o, const struct NCDModuleGroup *group, const struct NCDModuleInst_iparams *iparams, NCDStringIndex *string_index) WARN_UNUSED; -const struct NCDInterpModule * NCDModuleIndex_FindModule (NCDModuleIndex *o, const char *type); -int NCDModuleIndex_GetMethodNameId (NCDModuleIndex *o, const char *method_name); -const struct NCDInterpModule * NCDModuleIndex_GetMethodModule (NCDModuleIndex *o, NCD_string_id_t obj_type, int method_name_id); - -#endif diff --git a/external/badvpn_dns/ncd/NCDModuleIndex_mhash.h b/external/badvpn_dns/ncd/NCDModuleIndex_mhash.h deleted file mode 100644 index 8057b39..0000000 --- a/external/badvpn_dns/ncd/NCDModuleIndex_mhash.h +++ /dev/null @@ -1,12 +0,0 @@ -#define CHASH_PARAM_NAME NCDModuleIndex__MHash -#define CHASH_PARAM_ENTRY struct NCDModuleIndex_module -#define CHASH_PARAM_LINK NCDModuleIndex__mhash_link -#define CHASH_PARAM_KEY NCDModuleIndex__mhash_key -#define CHASH_PARAM_ARG int -#define CHASH_PARAM_NULL ((NCDModuleIndex__mhash_link)NULL) -#define CHASH_PARAM_DEREF(arg, link) (link) -#define CHASH_PARAM_ENTRYHASH(arg, entry) (badvpn_djb2_hash((const uint8_t *)(entry).ptr->imodule.module.type)) -#define CHASH_PARAM_KEYHASH(arg, key) (badvpn_djb2_hash((const uint8_t *)(key))) -#define CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) (!strcmp((entry1).ptr->imodule.module.type, (entry2).ptr->imodule.module.type)) -#define CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) (!strcmp((key1), (entry2).ptr->imodule.module.type)) -#define CHASH_PARAM_ENTRY_NEXT hash_next diff --git a/external/badvpn_dns/ncd/NCDObject.c b/external/badvpn_dns/ncd/NCDObject.c deleted file mode 100644 index c2f4cad..0000000 --- a/external/badvpn_dns/ncd/NCDObject.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file NCDObject.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "NCDObject.h" - -int NCDObject_no_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - return 0; -} - -int NCDObject_no_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - return 0; -} diff --git a/external/badvpn_dns/ncd/NCDObject.h b/external/badvpn_dns/ncd/NCDObject.h deleted file mode 100644 index 237ec72..0000000 --- a/external/badvpn_dns/ncd/NCDObject.h +++ /dev/null @@ -1,356 +0,0 @@ -/** - * @file NCDObject.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDOBJECT_H -#define BADVPN_NCDOBJECT_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <ncd/NCDVal.h> -#include <ncd/NCDStringIndex.h> -#include <ncd/static_strings.h> - -/** - * Represents an NCD object. - * Objects expose the following functionalities: - * - resolving variables by name, - * - resolving objects by name, - * - provide information for calling method-like statements. - * - * The NCDObject structure must not be stored persistently; it is only - * valid at the time it was obtained, and any change of state in the - * execution of the NCD program may render the object invalid. - * However, the structure does not contain any resources, and can freely - * be passed around by value. - */ -typedef struct NCDObject_s NCDObject; - -/** - * Callback function for variable resolution requests. - * - * @param obj const pointer to the NCDObject this is being called for. - * {@link NCDObject_DataPtr} and {@link NCDObject_DataInt} can be - * used to retrieve state information which was passed to - * {@link NCDObject_Build} or {@link NCDObject_BuildFull}. - * @param name name of the variable being resolved, in form of an {@link NCDStringIndex} - * string identifier - * @param mem pointer to the memory object where the resulting value should be - * constructed - * @param out_value If the variable exists, *out_value should be set to the value - * reference to the result value. If the variable exists but there - * was an error constructing the value, should be set to an - * invalid value reference. Can be modified even if the variable - * does not exist. - * @return 1 if the variable exists, 0 if not - */ -typedef int (*NCDObject_func_getvar) (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); - -/** - * Callback function for object resolution requests. - * - * @param obj const pointer to the NCDObject this is being called for. - * {@link NCDObject_DataPtr} and {@link NCDObject_DataInt} can be - * used to retrieve state information which was passed to - * {@link NCDObject_Build} or {@link NCDObject_BuildFull}. - * @param name name of the object being resolved, in form of an {@link NCDStringIndex} - * string identifier - * @param out_object If the object exists, *out_object should be set to the result - * object. Can be modified even if the object does not exist. - * @return 1 if the object exists, 0 if not - */ -typedef int (*NCDObject_func_getobj) (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); - -struct NCDObject_s { - NCD_string_id_t type; - int data_int; - void *data_ptr; - void *method_user; - NCDObject_func_getvar func_getvar; - NCDObject_func_getobj func_getobj; -}; - -/** - * Basic object construction function. - * This is equivalent to calling {@link NCDObject_BuildFull} with data_int=0 - * and method_user=data_ptr. See that function for detailed documentation. - */ -static NCDObject NCDObject_Build (NCD_string_id_t type, void *data_ptr, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj); - -/** - * Constructs an {@link NCDObject} structure. - * This is the full version where all supported parameters have to be provided. - * In most cases, {@link NCDObject_Build} will suffice. - * - * @param type type of the object for the purpose of calling method-like statements - * on the object, in form of an {@link NCDStringIndex} string identifier. - * May be set to -1 if the object has no methods. - * @param data_ptr state-keeping pointer which can be restored from callbacks using - * {@link NCDObject_DataPtr} - * @param data_int state-keeping integer which can be restored from callbacks using - * {@link NCDObject_DataInt} - * @param method_user state-keeping pointer to be passed to new method-like statements - * created using this object. The value of this argument will be - * available as params->method_user within the {@link NCDModule_func_new2} - * module backend callback. - * @param func_getvar callback for resolving variables within the object. This must not - * be NULL; if the object exposes no variables, pass {@link NCDObject_no_getvar}. - * @param func_getobj callback for resolving objects within the object. This must not - * be NULL; if the object exposes no objects, pass {@link NCDObject_no_getobj}. - * @return an NCDObject structure encapsulating the information given - */ -static NCDObject NCDObject_BuildFull (NCD_string_id_t type, void *data_ptr, int data_int, void *method_user, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj); - -/** - * Returns the 'type' attribute; see {@link NCDObject_BuildFull}. - */ -static NCD_string_id_t NCDObject_Type (const NCDObject *o); - -/** - * Returns the 'data_ptr' attribute; see {@link NCDObject_BuildFull}. - */ -static void * NCDObject_DataPtr (const NCDObject *o); - -/** - * Returns the 'data_int' attribute; see {@link NCDObject_BuildFull}. - */ -static int NCDObject_DataInt (const NCDObject *o); - -/** - * Returns the 'method_user' attribute; see {@link NCDObject_BuildFull}. - */ -static void * NCDObject_MethodUser (const NCDObject *o); - -/** - * Attempts to resolve a variable within the object. - * This just calls {@link NCDObject_func_getvar}, but also has some assertions to detect - * incorrect behavior of the callback. - */ -static int NCDObject_GetVar (const NCDObject *o, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) WARN_UNUSED; - -/** - * Attempts to resolve an object within the object. - * This just calls {@link NCDObject_func_getobj}, but also has some assertions to detect - * incorrect behavior of the callback. - */ -static int NCDObject_GetObj (const NCDObject *o, NCD_string_id_t name, NCDObject *out_object) WARN_UNUSED; - -/** - * Resolves a variable expression starting with this object. - * A variable expression is usually represented in dotted form, - * e.g. object1.object2.variable (for a named variable) or object1.object2.object3 - * (for an empty string variable). This function however receives the expression - * as an array of string identifiers. - * - * Consult the implementation for exact semantics of variable expression resolution. - * - * @param o object to start the resolution with - * @param names pointer to an array of names for the resolution. May be NULL if num_names is 0. - * @param num_names number in names in the array - * @param mem pointer to the memory object where the resulting value - * should be constructed - * @param out_value If the variable exists, *out_value will be set to the value - * reference to the result value. If the variable exists but there - * was an error constructing the value, will be set to an - * invalid value reference. May be modified even if the variable - * does not exist. - * @return 1 if the variable exists, 0 if not - */ -static int NCDObject_ResolveVarExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDValMem *mem, NCDValRef *out_value) WARN_UNUSED; - -/** - * Resolves an object expression starting with this object. - * An object expression is usually represented in dotted form, - * e.g. object1.object2.object3. This function however receives the expression - * as an array of string identifiers. - * - * Consult the implementation for exact semantics of object expression resolution. - * - * @param o object to start the resolution with - * @param names pointer to an array of names for the resolution. May be NULL if num_names is 0. - * @param num_names number in names in the array - * @param out_object If the object exists, *out_object will be set to the result - * object. May be modified even if the object does not exist. - * @return 1 if the object exists, 0 if not - */ -static int NCDObject_ResolveObjExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDObject *out_object) WARN_UNUSED; - -/** - * Returns 0. This can be used as a dummy variable resolution callback. - */ -int NCDObject_no_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); - -/** - * Returns 0. This can be used as a dummy object resolution callback. - */ -int NCDObject_no_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); - -// - -NCDObject NCDObject_Build (NCD_string_id_t type, void *data_ptr, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj) -{ - ASSERT(type >= -1) - ASSERT(func_getvar) - ASSERT(func_getobj) - - NCDObject obj; - obj.type = type; - obj.data_int = 0; - obj.data_ptr = data_ptr; - obj.method_user = data_ptr; - obj.func_getvar = func_getvar; - obj.func_getobj = func_getobj; - - return obj; -} - -NCDObject NCDObject_BuildFull (NCD_string_id_t type, void *data_ptr, int data_int, void *method_user, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj) -{ - ASSERT(type >= -1) - ASSERT(func_getvar) - ASSERT(func_getobj) - - NCDObject obj; - obj.type = type; - obj.data_int = data_int; - obj.data_ptr = data_ptr; - obj.method_user = method_user; - obj.func_getvar = func_getvar; - obj.func_getobj = func_getobj; - - return obj; -} - -NCD_string_id_t NCDObject_Type (const NCDObject *o) -{ - return o->type; -} - -void * NCDObject_DataPtr (const NCDObject *o) -{ - return o->data_ptr; -} - -int NCDObject_DataInt (const NCDObject *o) -{ - return o->data_int; -} - -void * NCDObject_MethodUser (const NCDObject *o) -{ - return o->method_user; -} - -int NCDObject_GetVar (const NCDObject *o, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - ASSERT(name >= 0) - ASSERT(mem) - ASSERT(out_value) - - int res = o->func_getvar(o, name, mem, out_value); - - ASSERT(res == 0 || res == 1) - ASSERT(res == 0 || (NCDVal_Assert(*out_value), 1)) - - return res; -} - -int NCDObject_GetObj (const NCDObject *o, NCD_string_id_t name, NCDObject *out_object) -{ - ASSERT(name >= 0) - ASSERT(out_object) - - int res = o->func_getobj(o, name, out_object); - - ASSERT(res == 0 || res == 1) - - return res; -} - -static NCDObject NCDObject__dig_into_object (NCDObject object) -{ - NCDObject obj2; - while (NCDObject_GetObj(&object, NCD_STRING_EMPTY, &obj2)) { - object = obj2; - } - - return object; -} - -int NCDObject_ResolveVarExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDValMem *mem, NCDValRef *out_value) -{ - ASSERT(num_names == 0 || names) - ASSERT(mem) - ASSERT(out_value) - - NCDObject object = NCDObject__dig_into_object(*o); - - while (num_names > 0) { - NCDObject obj2; - if (!NCDObject_GetObj(&object, *names, &obj2)) { - if (num_names == 1 && NCDObject_GetVar(&object, *names, mem, out_value)) { - return 1; - } - - return 0; - } - - object = NCDObject__dig_into_object(obj2); - - names++; - num_names--; - } - - return NCDObject_GetVar(&object, NCD_STRING_EMPTY, mem, out_value); -} - -int NCDObject_ResolveObjExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDObject *out_object) -{ - ASSERT(num_names == 0 || names) - ASSERT(out_object) - - NCDObject object = NCDObject__dig_into_object(*o); - - while (num_names > 0) { - NCDObject obj2; - if (!NCDObject_GetObj(&object, *names, &obj2)) { - return 0; - } - - object = NCDObject__dig_into_object(obj2); - - names++; - num_names--; - } - - *out_object = object; - return 1; -} - -#endif diff --git a/external/badvpn_dns/ncd/NCDPlaceholderDb.c b/external/badvpn_dns/ncd/NCDPlaceholderDb.c deleted file mode 100644 index 906509d..0000000 --- a/external/badvpn_dns/ncd/NCDPlaceholderDb.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file NCDPlaceholderDb.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <limits.h> -#include <stdlib.h> - -#include <misc/balloc.h> -#include <misc/strdup.h> -#include <base/BLog.h> -#include <ncd/make_name_indices.h> - -#include "NCDPlaceholderDb.h" - -#include <generated/blog_channel_NCDPlaceholderDb.h> - -int NCDPlaceholderDb_Init (NCDPlaceholderDb *o, NCDStringIndex *string_index) -{ - ASSERT(string_index) - - o->count = 0; - o->capacity = 1; - o->string_index = string_index; - - if (!(o->arr = BAllocArray(o->capacity, sizeof(o->arr[0])))) { - BLog(BLOG_ERROR, "NCDPlaceholderDb_Init failed"); - return 0; - } - - return 1; -} - -void NCDPlaceholderDb_Free (NCDPlaceholderDb *o) -{ - for (size_t i = 0; i < o->count; i++) { - BFree(o->arr[i].varnames); - } - - BFree(o->arr); -} - -int NCDPlaceholderDb_AddVariable (NCDPlaceholderDb *o, const char *varname, int *out_plid) -{ - ASSERT(varname) - ASSERT(out_plid) - ASSERT(o->count <= o->capacity) - ASSERT(o->capacity > 0) - - if (o->count == o->capacity) { - if (o->capacity > SIZE_MAX / 2) { - BLog(BLOG_ERROR, "too many placeholder entries (cannot resize)"); - return 0; - } - size_t newcap = 2 * o->capacity; - - struct NCDPlaceholderDb__entry *newarr = BAllocArray(newcap, sizeof(newarr[0])); - if (!newarr) { - BLog(BLOG_ERROR, "BAllocArray failed"); - return 0; - } - - memcpy(newarr, o->arr, o->count * sizeof(newarr[0])); - BFree(o->arr); - - o->arr = newarr; - o->capacity = newcap; - } - - ASSERT(o->count < o->capacity) - - if (o->count > INT_MAX) { - BLog(BLOG_ERROR, "too many placeholder entries (cannot fit integer)"); - return 0; - } - - NCD_string_id_t *varnames; - size_t num_names; - if (!ncd_make_name_indices(o->string_index, varname, &varnames, &num_names)) { - BLog(BLOG_ERROR, "ncd_make_name_indices failed"); - return 0; - } - - *out_plid = o->count; - - o->arr[o->count].varnames = varnames; - o->arr[o->count].num_names = num_names; - o->count++; - - return 1; -} - -void NCDPlaceholderDb_GetVariable (NCDPlaceholderDb *o, int plid, const NCD_string_id_t **out_varnames, size_t *out_num_names) -{ - ASSERT(plid >= 0) - ASSERT(plid < o->count) - ASSERT(out_varnames) - ASSERT(out_num_names) - - *out_varnames = o->arr[plid].varnames; - *out_num_names = o->arr[plid].num_names; -} diff --git a/external/badvpn_dns/ncd/NCDPlaceholderDb.h b/external/badvpn_dns/ncd/NCDPlaceholderDb.h deleted file mode 100644 index d6a1f40..0000000 --- a/external/badvpn_dns/ncd/NCDPlaceholderDb.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file NCDPlaceholderDb.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDPLACEHOLDERDB_H -#define BADVPN_NCDPLACEHOLDERDB_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <ncd/NCDStringIndex.h> - -struct NCDPlaceholderDb__entry { - NCD_string_id_t *varnames; - size_t num_names; -}; - -/** - * Associates variable placeholder numbers to variable names. - * This is populated by {@link NCDInterpProcess_Init} when converting the {@link NCDValue} - * objects in the AST to compact representations in {@link NCDValMem}. Variables are - * replaced with placeholder identifiers (integers), which this object associates - * with their names. - * During interpretation, when a statement is being initialized, the compact form held - * by {@link NCDInterpProcess} is byte-copied, and placeholders are replaced with the - * values of corresponding variables using {@link NCDVal_ReplacePlaceholders}. - */ -typedef struct { - struct NCDPlaceholderDb__entry *arr; - size_t count; - size_t capacity; - NCDStringIndex *string_index; -} NCDPlaceholderDb; - -/** - * Initializes the placeholder database. - * Returns 1 on success, and 0 on failure. - */ -int NCDPlaceholderDb_Init (NCDPlaceholderDb *o, NCDStringIndex *string_index) WARN_UNUSED; - -/** - * Frees the placeholder database. - */ -void NCDPlaceholderDb_Free (NCDPlaceholderDb *o); - -/** - * Adds a variable to the database. - * - * @param varname name of the variable (text, including dots). Must not be NULL. - * @param out_plid on success, the placeholder identifier will be returned here. Must - * not be NULL. - * @return 1 on success, 0 on failure - */ -int NCDPlaceholderDb_AddVariable (NCDPlaceholderDb *o, const char *varname, int *out_plid) WARN_UNUSED; - -/** - * Retrieves the name of the variable associated with a placeholder identifier. - * - * @param plid placeholder identifier; must have been previously provided by - * {@link NCDPlaceholderDb_AddVariable}. - * @return name of the variable, split by dots. The returned value points to - * an array of pointers to strings, which is terminated by a NULL - * pointer. These all point to internal data in the placeholder - * database; they must not be modified, and remain valid until the - * database is freed. - * Note that there will always be at least one string in the result. - */ -void NCDPlaceholderDb_GetVariable (NCDPlaceholderDb *o, int plid, const NCD_string_id_t **out_varnames, size_t *out_num_names); - -#endif diff --git a/external/badvpn_dns/ncd/NCDStringIndex.c b/external/badvpn_dns/ncd/NCDStringIndex.c deleted file mode 100644 index 87a231d..0000000 --- a/external/badvpn_dns/ncd/NCDStringIndex.c +++ /dev/null @@ -1,262 +0,0 @@ -/** - * @file NCDStringIndex.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdlib.h> - -#include <misc/hashfun.h> -#include <misc/strdup.h> -#include <misc/array_length.h> -#include <base/BLog.h> - -#include "NCDStringIndex.h" - -#include "NCDStringIndex_hash.h" -#include <structure/CHash_impl.h> - -#define GROWARRAY_NAME Array -#define GROWARRAY_OBJECT_TYPE NCDStringIndex -#define GROWARRAY_ARRAY_MEMBER entries -#define GROWARRAY_CAPACITY_MEMBER entries_capacity -#define GROWARRAY_MAX_CAPACITY NCD_STRING_ID_MAX -#include <misc/grow_array.h> - -#include <generated/blog_channel_ncd.h> - -// NOTE: keep synchronized with static_strings.h -static const char *static_strings[] = { - "", - "_args", - "_arg0", - "_arg1", - "_arg2", - "_arg3", - "_arg4", - "_arg5", - "_arg6", - "_arg7", - "_arg8", - "_arg9", - "_arg10", - "_arg11", - "_arg12", - "_arg13", - "_arg14", - "_arg15", - "_arg16", - "_arg17", - "_arg18", - "_arg19", - "true", - "false", - "<none>", - "_caller", - "succeeded", - "is_error", - "not_eof", - "length", - "type", - "exit_status", - "size" -}; - -static NCD_string_id_t do_get (NCDStringIndex *o, const char *str, size_t str_len) -{ - ASSERT(str) - - NCDStringIndex_hash_key key = {str, str_len}; - NCDStringIndex__HashRef ref = NCDStringIndex__Hash_Lookup(&o->hash, o->entries, key); - ASSERT(ref.link == -1 || ref.link >= 0) - ASSERT(ref.link == -1 || ref.link < o->entries_size) - ASSERT(ref.link == -1 || (ref.ptr->str_len == str_len && !memcmp(ref.ptr->str, str, str_len))) - - if (ref.link != -1) { - return ref.link; - } - - if (o->entries_size == o->entries_capacity) { - if (!Array_DoubleUp(o)) { - BLog(BLOG_ERROR, "Array_DoubleUp failed"); - return -1; - } - - if (!NCDStringIndex__Hash_MultiplyBuckets(&o->hash, o->entries, 1)) { - BLog(BLOG_ERROR, "NCDStringIndex__Hash_MultiplyBuckets failed"); - return -1; - } - } - - ASSERT(o->entries_size < o->entries_capacity) - - struct NCDStringIndex__entry *entry = &o->entries[o->entries_size]; - - if (!(entry->str = b_strdup_bin(str, str_len))) { - BLog(BLOG_ERROR, "b_strdup_bin failed"); - return -1; - } - entry->str_len = str_len; - entry->has_nulls = !!memchr(str, '\0', str_len); - - NCDStringIndex__HashRef newref = {entry, o->entries_size}; - int res = NCDStringIndex__Hash_Insert(&o->hash, o->entries, newref, NULL); - ASSERT_EXECUTE(res) - - return o->entries_size++; -} - -int NCDStringIndex_Init (NCDStringIndex *o) -{ - o->entries_size = 0; - - if (!Array_Init(o, NCDSTRINGINDEX_INITIAL_CAPACITY)) { - BLog(BLOG_ERROR, "Array_Init failed"); - goto fail0; - } - - if (!NCDStringIndex__Hash_Init(&o->hash, NCDSTRINGINDEX_INITIAL_HASH_BUCKETS)) { - BLog(BLOG_ERROR, "NCDStringIndex__Hash_Init failed"); - goto fail1; - } - - for (size_t i = 0; i < B_ARRAY_LENGTH(static_strings); i++) { - if (do_get(o, static_strings[i], strlen(static_strings[i])) < 0) { - goto fail2; - } - } - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - for (NCD_string_id_t i = 0; i < o->entries_size; i++) { - free(o->entries[i].str); - } - NCDStringIndex__Hash_Free(&o->hash); -fail1: - Array_Free(o); -fail0: - return 0; -} - -void NCDStringIndex_Free (NCDStringIndex *o) -{ - DebugObject_Free(&o->d_obj); - - for (NCD_string_id_t i = 0; i < o->entries_size; i++) { - free(o->entries[i].str); - } - - NCDStringIndex__Hash_Free(&o->hash); - Array_Free(o); -} - -NCD_string_id_t NCDStringIndex_Lookup (NCDStringIndex *o, const char *str) -{ - DebugObject_Access(&o->d_obj); - ASSERT(str) - - return NCDStringIndex_LookupBin(o, str, strlen(str)); -} - -NCD_string_id_t NCDStringIndex_LookupBin (NCDStringIndex *o, const char *str, size_t str_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(str) - - NCDStringIndex_hash_key key = {str, str_len}; - NCDStringIndex__HashRef ref = NCDStringIndex__Hash_Lookup(&o->hash, o->entries, key); - ASSERT(ref.link == -1 || ref.link >= 0) - ASSERT(ref.link == -1 || ref.link < o->entries_size) - ASSERT(ref.link == -1 || (ref.ptr->str_len == str_len && !memcmp(ref.ptr->str, str, str_len))) - - return ref.link; -} - -NCD_string_id_t NCDStringIndex_Get (NCDStringIndex *o, const char *str) -{ - DebugObject_Access(&o->d_obj); - ASSERT(str) - - return NCDStringIndex_GetBin(o, str, strlen(str)); -} - -NCD_string_id_t NCDStringIndex_GetBin (NCDStringIndex *o, const char *str, size_t str_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(str) - - return do_get(o, str, str_len); -} - -const char * NCDStringIndex_Value (NCDStringIndex *o, NCD_string_id_t id) -{ - DebugObject_Access(&o->d_obj); - ASSERT(id >= 0) - ASSERT(id < o->entries_size) - ASSERT(o->entries[id].str) - - return o->entries[id].str; -} - -size_t NCDStringIndex_Length (NCDStringIndex *o, NCD_string_id_t id) -{ - DebugObject_Access(&o->d_obj); - ASSERT(id >= 0) - ASSERT(id < o->entries_size) - ASSERT(o->entries[id].str) - - return o->entries[id].str_len; -} - -int NCDStringIndex_HasNulls (NCDStringIndex *o, NCD_string_id_t id) -{ - DebugObject_Access(&o->d_obj); - ASSERT(id >= 0) - ASSERT(id < o->entries_size) - ASSERT(o->entries[id].str) - - return o->entries[id].has_nulls; -} - -int NCDStringIndex_GetRequests (NCDStringIndex *o, struct NCD_string_request *requests) -{ - DebugObject_Access(&o->d_obj); - ASSERT(requests) - - while (requests->str) { - NCD_string_id_t id = NCDStringIndex_Get(o, requests->str); - if (id < 0) { - return 0; - } - requests->id = id; - requests++; - } - - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDStringIndex.h b/external/badvpn_dns/ncd/NCDStringIndex.h deleted file mode 100644 index 78e20ec..0000000 --- a/external/badvpn_dns/ncd/NCDStringIndex.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file NCDStringIndex.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_STRING_INDEX_H -#define BADVPN_NCD_STRING_INDEX_H - -#include <limits.h> - -#include <misc/debug.h> -#include <structure/CHash.h> -#include <base/DebugObject.h> - -#define NCDSTRINGINDEX_INITIAL_CAPACITY 256 -#define NCDSTRINGINDEX_INITIAL_HASH_BUCKETS 256 - -typedef int NCD_string_id_t; - -#define NCD_STRING_ID_MAX INT_MAX - -struct NCDStringIndex__entry { - char *str; - size_t str_len; - int has_nulls; - NCD_string_id_t hash_next; -}; - -typedef struct { const char *str; size_t len; } NCDStringIndex_hash_key; -typedef struct NCDStringIndex__entry *NCDStringIndex_hash_arg; - -#include "NCDStringIndex_hash.h" -#include <structure/CHash_decl.h> - -typedef struct { - struct NCDStringIndex__entry *entries; - NCD_string_id_t entries_capacity; - NCD_string_id_t entries_size; - NCDStringIndex__Hash hash; - DebugObject d_obj; -} NCDStringIndex; - -struct NCD_string_request { - const char *str; - NCD_string_id_t id; -}; - -int NCDStringIndex_Init (NCDStringIndex *o) WARN_UNUSED; -void NCDStringIndex_Free (NCDStringIndex *o); -NCD_string_id_t NCDStringIndex_Lookup (NCDStringIndex *o, const char *str); -NCD_string_id_t NCDStringIndex_LookupBin (NCDStringIndex *o, const char *str, size_t str_len); -NCD_string_id_t NCDStringIndex_Get (NCDStringIndex *o, const char *str); -NCD_string_id_t NCDStringIndex_GetBin (NCDStringIndex *o, const char *str, size_t str_len); -const char * NCDStringIndex_Value (NCDStringIndex *o, NCD_string_id_t id); -size_t NCDStringIndex_Length (NCDStringIndex *o, NCD_string_id_t id); -int NCDStringIndex_HasNulls (NCDStringIndex *o, NCD_string_id_t id); -int NCDStringIndex_GetRequests (NCDStringIndex *o, struct NCD_string_request *requests) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDStringIndex_hash.h b/external/badvpn_dns/ncd/NCDStringIndex_hash.h deleted file mode 100644 index 9a751fb..0000000 --- a/external/badvpn_dns/ncd/NCDStringIndex_hash.h +++ /dev/null @@ -1,13 +0,0 @@ -#define CHASH_PARAM_NAME NCDStringIndex__Hash -#define CHASH_PARAM_ENTRY struct NCDStringIndex__entry -#define CHASH_PARAM_LINK NCD_string_id_t -#define CHASH_PARAM_KEY NCDStringIndex_hash_key -#define CHASH_PARAM_ARG NCDStringIndex_hash_arg -#define CHASH_PARAM_NULL ((NCD_string_id_t)-1) -#define CHASH_PARAM_DEREF(arg, link) (&(arg)[(link)]) -#define CHASH_PARAM_ENTRYHASH(arg, entry) badvpn_djb2_hash_bin((const uint8_t *)(entry).ptr->str, (entry).ptr->str_len) -#define CHASH_PARAM_KEYHASH(arg, key) badvpn_djb2_hash_bin((const uint8_t *)(key).str, (key).len) -#define CHASH_PARAM_ENTRYHASH_IS_CHEAP 0 -#define CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) ((entry1).ptr->str_len == (entry2).ptr->str_len && !memcmp((entry1).ptr->str, (entry2).ptr->str, (entry1).ptr->str_len)) -#define CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) ((key1).len == (entry2).ptr->str_len && !memcmp((key1).str, (entry2).ptr->str, (key1).len)) -#define CHASH_PARAM_ENTRY_NEXT hash_next diff --git a/external/badvpn_dns/ncd/NCDSugar.c b/external/badvpn_dns/ncd/NCDSugar.c deleted file mode 100644 index 669bec8..0000000 --- a/external/badvpn_dns/ncd/NCDSugar.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * @file NCDSugar.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> - -#include "NCDSugar.h" - -struct desugar_state { - NCDProgram *prog; - size_t template_name_ctr; -}; - -static int add_template (struct desugar_state *state, NCDBlock block, NCDValue *out_name_val); -static int desugar_block (struct desugar_state *state, NCDBlock *block); -static int desugar_if (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next); -static int desugar_foreach (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next); - -static int add_template (struct desugar_state *state, NCDBlock block, NCDValue *out_name_val) -{ - char name[40]; - snprintf(name, sizeof(name), "__tmpl%zu", state->template_name_ctr); - state->template_name_ctr++; - - if (!desugar_block(state, &block)) { - NCDBlock_Free(&block); - return 0; - } - - NCDProcess proc_tmp; - if (!NCDProcess_Init(&proc_tmp, 1, name, block)) { - NCDBlock_Free(&block); - return 0; - } - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc_tmp); - - if (!NCDProgram_PrependElem(state->prog, elem)) { - NCDProgramElem_Free(&elem); - return 0; - } - - if (!NCDValue_InitString(out_name_val, name)) { - return 0; - } - - return 1; -} - -static int desugar_block (struct desugar_state *state, NCDBlock *block) -{ - NCDStatement *stmt = NCDBlock_FirstStatement(block); - - while (stmt) { - switch (NCDStatement_Type(stmt)) { - case NCDSTATEMENT_REG: { - stmt = NCDBlock_NextStatement(block, stmt); - } break; - - case NCDSTATEMENT_IF: { - if (!desugar_if(state, block, stmt, &stmt)) { - return 0; - } - } break; - - case NCDSTATEMENT_FOREACH: { - if (!desugar_foreach(state, block, stmt, &stmt)) { - return 0; - } - } break; - - default: ASSERT(0); - } - } - - return 1; -} - -static int desugar_if (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next) -{ - ASSERT(NCDStatement_Type(stmt) == NCDSTATEMENT_IF) - - NCDValue args; - NCDValue_InitList(&args); - - NCDIfBlock *ifblock = NCDStatement_IfBlock(stmt); - - while (NCDIfBlock_FirstIf(ifblock)) { - NCDIf ifc = NCDIfBlock_GrabIf(ifblock, NCDIfBlock_FirstIf(ifblock)); - - NCDValue if_cond; - NCDBlock if_block; - NCDIf_FreeGrab(&ifc, &if_cond, &if_block); - - if (!NCDValue_ListAppend(&args, if_cond)) { - NCDValue_Free(&if_cond); - NCDBlock_Free(&if_block); - goto fail; - } - - NCDValue action_arg; - if (!add_template(state, if_block, &action_arg)) { - goto fail; - } - - if (!NCDValue_ListAppend(&args, action_arg)) { - NCDValue_Free(&action_arg); - goto fail; - } - } - - if (NCDStatement_IfElse(stmt)) { - NCDBlock else_block = NCDStatement_IfGrabElse(stmt); - - NCDValue action_arg; - if (!add_template(state, else_block, &action_arg)) { - goto fail; - } - - if (!NCDValue_ListAppend(&args, action_arg)) { - NCDValue_Free(&action_arg); - goto fail; - } - } - - NCDStatement new_stmt; - if (!NCDStatement_InitReg(&new_stmt, NCDStatement_Name(stmt), NULL, "embcall2_multif", args)) { - goto fail; - } - - stmt = NCDBlock_ReplaceStatement(block, stmt, new_stmt); - - *out_next = NCDBlock_NextStatement(block, stmt); - return 1; - -fail: - NCDValue_Free(&args); - return 0; -} - -static int desugar_foreach (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next) -{ - ASSERT(NCDStatement_Type(stmt) == NCDSTATEMENT_FOREACH) - - NCDValue args; - NCDValue_InitList(&args); - - NCDValue collection; - NCDBlock foreach_block; - NCDStatement_ForeachGrab(stmt, &collection, &foreach_block); - - NCDValue template_arg; - if (!add_template(state, foreach_block, &template_arg)) { - NCDValue_Free(&collection); - goto fail; - } - - if (!NCDValue_ListAppend(&args, collection)) { - NCDValue_Free(&template_arg); - NCDValue_Free(&collection); - goto fail; - } - - if (!NCDValue_ListAppend(&args, template_arg)) { - NCDValue_Free(&template_arg); - goto fail; - } - - NCDValue name1_arg; - if (!NCDValue_InitString(&name1_arg, NCDStatement_ForeachName1(stmt))) { - goto fail; - } - - if (!NCDValue_ListAppend(&args, name1_arg)) { - NCDValue_Free(&name1_arg); - goto fail; - } - - if (NCDStatement_ForeachName2(stmt)) { - NCDValue name2_arg; - if (!NCDValue_InitString(&name2_arg, NCDStatement_ForeachName2(stmt))) { - goto fail; - } - - if (!NCDValue_ListAppend(&args, name2_arg)) { - NCDValue_Free(&name2_arg); - goto fail; - } - } - - NCDStatement new_stmt; - if (!NCDStatement_InitReg(&new_stmt, NCDStatement_Name(stmt), NULL, "foreach_emb", args)) { - goto fail; - } - - stmt = NCDBlock_ReplaceStatement(block, stmt, new_stmt); - - *out_next = NCDBlock_NextStatement(block, stmt); - return 1; - -fail: - NCDValue_Free(&args); - return 0; -} - -int NCDSugar_Desugar (NCDProgram *prog) -{ - ASSERT(!NCDProgram_ContainsElemType(prog, NCDPROGRAMELEM_INCLUDE)) - ASSERT(!NCDProgram_ContainsElemType(prog, NCDPROGRAMELEM_INCLUDE_GUARD)) - - struct desugar_state state; - state.prog = prog; - state.template_name_ctr = 0; - - for (NCDProgramElem *elem = NCDProgram_FirstElem(prog); elem; elem = NCDProgram_NextElem(prog, elem)) { - ASSERT(NCDProgramElem_Type(elem) == NCDPROGRAMELEM_PROCESS) - NCDProcess *proc = NCDProgramElem_Process(elem); - - if (!desugar_block(&state, NCDProcess_Block(proc))) { - return 0; - } - } - - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDSugar.h b/external/badvpn_dns/ncd/NCDSugar.h deleted file mode 100644 index 0aa0ad2..0000000 --- a/external/badvpn_dns/ncd/NCDSugar.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file NCDSugar.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDSUGAR_H -#define BADVPN_NCDSUGAR_H - -#include <misc/debug.h> -#include <ncd/NCDAst.h> - -int NCDSugar_Desugar (NCDProgram *prog) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDVal.c b/external/badvpn_dns/ncd/NCDVal.c deleted file mode 100644 index aecb82b..0000000 --- a/external/badvpn_dns/ncd/NCDVal.c +++ /dev/null @@ -1,2065 +0,0 @@ -/** - * @file NCDVal.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <limits.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdarg.h> - -#include <misc/balloc.h> -#include <misc/strdup.h> -#include <misc/offset.h> -#include <base/BLog.h> - -#include "NCDVal.h" - -#include <generated/blog_channel_NCDVal.h> - -#define TYPE_MASK_EXTERNAL_TYPE ((1 << 3) - 1) -#define TYPE_MASK_INTERNAL_TYPE ((1 << 5) - 1) -#define TYPE_SHIFT_DEPTH 5 - -#define STOREDSTRING_TYPE (NCDVAL_STRING | (0 << 3)) -#define IDSTRING_TYPE (NCDVAL_STRING | (1 << 3)) -#define EXTERNALSTRING_TYPE (NCDVAL_STRING | (2 << 3)) -#define COMPOSEDSTRING_TYPE (NCDVAL_STRING | (3 << 3)) - -static int make_type (int internal_type, int depth) -{ - ASSERT(internal_type == NCDVAL_LIST || - internal_type == NCDVAL_MAP || - internal_type == STOREDSTRING_TYPE || - internal_type == IDSTRING_TYPE || - internal_type == EXTERNALSTRING_TYPE || - internal_type == COMPOSEDSTRING_TYPE) - ASSERT(depth >= 0) - ASSERT(depth <= NCDVAL_MAX_DEPTH) - - return (internal_type | (depth << TYPE_SHIFT_DEPTH)); -} - -static int get_external_type (int type) -{ - return (type & TYPE_MASK_EXTERNAL_TYPE); -} - -static int get_internal_type (int type) -{ - return (type & TYPE_MASK_INTERNAL_TYPE); -} - -static int get_depth (int type) -{ - return (type >> TYPE_SHIFT_DEPTH); -} - -static int bump_depth (int *type_ptr, int elem_depth) -{ - if (get_depth(*type_ptr) < elem_depth + 1) { - if (elem_depth + 1 > NCDVAL_MAX_DEPTH) { - return 0; - } - *type_ptr = make_type(get_internal_type(*type_ptr), elem_depth + 1); - } - - return 1; -} - -static void * NCDValMem__BufAt (NCDValMem *o, NCDVal__idx idx) -{ - ASSERT(idx >= 0) - ASSERT(idx < o->used) - - return (o->buf ? o->buf : o->fastbuf) + idx; -} - -static NCDVal__idx NCDValMem__Alloc (NCDValMem *o, NCDVal__idx alloc_size, NCDVal__idx align) -{ - NCDVal__idx mod = o->used % align; - NCDVal__idx align_extra = mod ? (align - mod) : 0; - - if (alloc_size > NCDVAL_MAXIDX - align_extra) { - return -1; - } - NCDVal__idx aligned_alloc_size = align_extra + alloc_size; - - if (aligned_alloc_size > o->size - o->used) { - NCDVal__idx newsize = (o->buf ? o->size : NCDVAL_FIRST_SIZE); - while (aligned_alloc_size > newsize - o->used) { - if (newsize > NCDVAL_MAXIDX / 2) { - return -1; - } - newsize *= 2; - } - - char *newbuf; - - if (!o->buf) { - newbuf = malloc(newsize); - if (!newbuf) { - return -1; - } - memcpy(newbuf, o->fastbuf, o->used); - } else { - newbuf = realloc(o->buf, newsize); - if (!newbuf) { - return -1; - } - } - - o->buf = newbuf; - o->size = newsize; - } - - NCDVal__idx idx = o->used + align_extra; - o->used += aligned_alloc_size; - - return idx; -} - -static NCDValRef NCDVal__Ref (NCDValMem *mem, NCDVal__idx idx) -{ - ASSERT(idx == -1 || mem) - - NCDValRef ref = {mem, idx}; - return ref; -} - -static void NCDVal__AssertMem (NCDValMem *mem) -{ - ASSERT(mem) - ASSERT(mem->size >= 0) - ASSERT(mem->used >= 0) - ASSERT(mem->used <= mem->size) - ASSERT(mem->buf || mem->size == NCDVAL_FASTBUF_SIZE) - ASSERT(!mem->buf || mem->size >= NCDVAL_FIRST_SIZE) -} - -static void NCDVal_AssertExternal (NCDValMem *mem, const void *e_buf, size_t e_len) -{ -#ifndef NDEBUG - const char *e_cbuf = e_buf; - char *buf = (mem->buf ? mem->buf : mem->fastbuf); - ASSERT(e_cbuf >= buf + mem->size || e_cbuf + e_len <= buf) -#endif -} - -static void NCDVal__AssertValOnly (NCDValMem *mem, NCDVal__idx idx) -{ - // placeholders - if (idx < -1) { - return; - } - - ASSERT(idx >= 0) - ASSERT(idx + sizeof(int) <= mem->used) - -#ifndef NDEBUG - int *type_ptr = NCDValMem__BufAt(mem, idx); - - ASSERT(get_depth(*type_ptr) >= 0) - ASSERT(get_depth(*type_ptr) <= NCDVAL_MAX_DEPTH) - - switch (get_internal_type(*type_ptr)) { - case STOREDSTRING_TYPE: { - ASSERT(idx + sizeof(struct NCDVal__string) <= mem->used) - struct NCDVal__string *str_e = NCDValMem__BufAt(mem, idx); - ASSERT(str_e->length >= 0) - ASSERT(idx + sizeof(struct NCDVal__string) + str_e->length + 1 <= mem->used) - } break; - case NCDVAL_LIST: { - ASSERT(idx + sizeof(struct NCDVal__list) <= mem->used) - struct NCDVal__list *list_e = NCDValMem__BufAt(mem, idx); - ASSERT(list_e->maxcount >= 0) - ASSERT(list_e->count >= 0) - ASSERT(list_e->count <= list_e->maxcount) - ASSERT(idx + sizeof(struct NCDVal__list) + list_e->maxcount * sizeof(NCDVal__idx) <= mem->used) - } break; - case NCDVAL_MAP: { - ASSERT(idx + sizeof(struct NCDVal__map) <= mem->used) - struct NCDVal__map *map_e = NCDValMem__BufAt(mem, idx); - ASSERT(map_e->maxcount >= 0) - ASSERT(map_e->count >= 0) - ASSERT(map_e->count <= map_e->maxcount) - ASSERT(idx + sizeof(struct NCDVal__map) + map_e->maxcount * sizeof(struct NCDVal__mapelem) <= mem->used) - } break; - case IDSTRING_TYPE: { - ASSERT(idx + sizeof(struct NCDVal__idstring) <= mem->used) - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(mem, idx); - ASSERT(ids_e->string_id >= 0) - ASSERT(ids_e->string_index) - } break; - case EXTERNALSTRING_TYPE: { - ASSERT(idx + sizeof(struct NCDVal__externalstring) <= mem->used) - struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(mem, idx); - ASSERT(exs_e->data) - ASSERT(!exs_e->ref.target || exs_e->ref.next >= -1) - ASSERT(!exs_e->ref.target || exs_e->ref.next < mem->used) - } break; - case COMPOSEDSTRING_TYPE: { - ASSERT(idx + sizeof(struct NCDVal__composedstring) <= mem->used) - struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(mem, idx); - ASSERT(cms_e->func_getptr) - ASSERT(!cms_e->ref.target || cms_e->ref.next >= -1) - ASSERT(!cms_e->ref.target || cms_e->ref.next < mem->used) - } break; - default: ASSERT(0); - } -#endif -} - -static void NCDVal__AssertVal (NCDValRef val) -{ - NCDVal__AssertMem(val.mem); - NCDVal__AssertValOnly(val.mem, val.idx); -} - -static NCDValMapElem NCDVal__MapElem (NCDVal__idx elemidx) -{ - ASSERT(elemidx >= 0 || elemidx == -1) - - NCDValMapElem me = {elemidx}; - return me; -} - -static void NCDVal__MapAssertElemOnly (NCDValRef map, NCDVal__idx elemidx) -{ -#ifndef NDEBUG - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - ASSERT(elemidx >= map.idx + offsetof(struct NCDVal__map, elems)) - ASSERT(elemidx < map.idx + offsetof(struct NCDVal__map, elems) + map_e->count * sizeof(struct NCDVal__mapelem)) - - struct NCDVal__mapelem *me_e = NCDValMem__BufAt(map.mem, elemidx); - NCDVal__AssertValOnly(map.mem, me_e->key_idx); - NCDVal__AssertValOnly(map.mem, me_e->val_idx); -#endif -} - -static void NCDVal__MapAssertElem (NCDValRef map, NCDValMapElem me) -{ - ASSERT(NCDVal_IsMap(map)) - NCDVal__MapAssertElemOnly(map, me.elemidx); -} - -static NCDVal__idx NCDVal__MapElemIdx (NCDVal__idx mapidx, NCDVal__idx pos) -{ - return mapidx + offsetof(struct NCDVal__map, elems) + pos * sizeof(struct NCDVal__mapelem); -} - -static int NCDVal__Depth (NCDValRef val) -{ - ASSERT(val.idx != -1) - - // handle placeholders - if (val.idx < 0) { - return 0; - } - - int *elem_type_ptr = NCDValMem__BufAt(val.mem, val.idx); - int depth = get_depth(*elem_type_ptr); - ASSERT(depth >= 0) - ASSERT(depth <= NCDVAL_MAX_DEPTH) - - return depth; -} - -static int NCDValMem__NeedRegisterLink (NCDValMem *mem, NCDVal__idx val_idx) -{ - NCDVal__AssertValOnly(mem, val_idx); - - return !(val_idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(mem, val_idx)) == COMPOSEDSTRING_TYPE; -} - -static int NCDValMem__RegisterLink (NCDValMem *mem, NCDVal__idx val_idx, NCDVal__idx link_idx) -{ - NCDVal__AssertValOnly(mem, val_idx); - ASSERT(NCDValMem__NeedRegisterLink(mem, val_idx)) - - NCDVal__idx cms_link_idx = NCDValMem__Alloc(mem, sizeof(struct NCDVal__cms_link), __alignof(struct NCDVal__cms_link)); - if (cms_link_idx < 0) { - return 0; - } - - struct NCDVal__cms_link *cms_link = NCDValMem__BufAt(mem, cms_link_idx); - cms_link->link_idx = link_idx; - cms_link->next_cms_link = mem->first_cms_link; - mem->first_cms_link = cms_link_idx; - - return 1; -} - -static void NCDValMem__PopLastRegisteredLink (NCDValMem *mem) -{ - ASSERT(mem->first_cms_link != -1) - - struct NCDVal__cms_link *cms_link = NCDValMem__BufAt(mem, mem->first_cms_link); - mem->first_cms_link = cms_link->next_cms_link; -} - -static NCDValRef NCDVal__CopyComposedStringToStored (NCDValRef val) -{ - ASSERT(NCDVal_IsComposedString(val)) - - struct NCDVal__composedstring cms_e = *(struct NCDVal__composedstring *)NCDValMem__BufAt(val.mem, val.idx); - - NCDValRef copy = NCDVal_NewStringUninitialized(val.mem, cms_e.length); - if (NCDVal_IsInvalid(copy)) { - return NCDVal_NewInvalid(); - } - - char *copy_data = (char *)NCDVal_StringData(copy); - - size_t pos = 0; - while (pos < cms_e.length) { - const char *chunk_data; - size_t chunk_len; - cms_e.func_getptr(cms_e.user, cms_e.offset + pos, &chunk_data, &chunk_len); - ASSERT(chunk_data) - ASSERT(chunk_len > 0) - if (chunk_len > cms_e.length - pos) { - chunk_len = cms_e.length - pos; - } - memcpy(copy_data + pos, chunk_data, chunk_len); - pos += chunk_len; - } - - return copy; -} - -static const char * NCDVal__composedstring_cstring_func (const b_cstring *cstr, size_t offset, size_t *out_length) -{ - ASSERT(offset < cstr->length) - ASSERT(out_length) - ASSERT(cstr->func == NCDVal__composedstring_cstring_func) - - size_t str_offset = cstr->user1.size; - NCDVal_ComposedString_func_getptr func_getptr = (NCDVal_ComposedString_func_getptr)cstr->user2.fptr; - void *user = cstr->user3.ptr; - - const char *data; - func_getptr(user, str_offset + offset, &data, out_length); - - ASSERT(data) - ASSERT(*out_length > 0) - - return data; -} - -#include "NCDVal_maptree.h" -#include <structure/CAvl_impl.h> - -void NCDValMem_Init (NCDValMem *o) -{ - o->buf = NULL; - o->size = NCDVAL_FASTBUF_SIZE; - o->used = 0; - o->first_ref = -1; - o->first_cms_link = -1; -} - -void NCDValMem_Free (NCDValMem *o) -{ - NCDVal__AssertMem(o); - - NCDVal__idx refidx = o->first_ref; - while (refidx != -1) { - struct NCDVal__ref *ref = NCDValMem__BufAt(o, refidx); - ASSERT(ref->target) - BRefTarget_Deref(ref->target); - refidx = ref->next; - } - - if (o->buf) { - BFree(o->buf); - } -} - -int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other) -{ - NCDVal__AssertMem(other); - - o->size = other->size; - o->used = other->used; - o->first_ref = other->first_ref; - o->first_cms_link = other->first_cms_link; - - if (!other->buf) { - o->buf = NULL; - memcpy(o->fastbuf, other->fastbuf, other->used); - } else { - o->buf = BAlloc(other->size); - if (!o->buf) { - goto fail0; - } - memcpy(o->buf, other->buf, other->used); - } - - NCDVal__idx refidx = o->first_ref; - while (refidx != -1) { - struct NCDVal__ref *ref = NCDValMem__BufAt(o, refidx); - ASSERT(ref->target) - if (!BRefTarget_Ref(ref->target)) { - goto fail1; - } - refidx = ref->next; - } - - return 1; - -fail1:; - NCDVal__idx undo_refidx = o->first_ref; - while (undo_refidx != refidx) { - struct NCDVal__ref *ref = NCDValMem__BufAt(o, undo_refidx); - BRefTarget_Deref(ref->target); - undo_refidx = ref->next; - } - if (o->buf) { - BFree(o->buf); - } -fail0: - return 0; -} - -int NCDValMem_ConvertNonContinuousStrings (NCDValMem *o, NCDValRef *root_val) -{ - NCDVal__AssertMem(o); - ASSERT(root_val) - ASSERT(root_val->mem == o) - NCDVal__AssertValOnly(o, root_val->idx); - - while (o->first_cms_link != -1) { - struct NCDVal__cms_link cms_link = *(struct NCDVal__cms_link *)NCDValMem__BufAt(o, o->first_cms_link); - - NCDVal__idx val_idx = *(NCDVal__idx *)NCDValMem__BufAt(o, cms_link.link_idx); - NCDValRef val = NCDVal__Ref(o, val_idx); - ASSERT(NCDVal_IsComposedString(val)) - - NCDValRef copy = NCDVal__CopyComposedStringToStored(val); - if (NCDVal_IsInvalid(copy)) { - return 0; - } - - *(int *)NCDValMem__BufAt(o, cms_link.link_idx) = copy.idx; - - o->first_cms_link = cms_link.next_cms_link; - } - - if (NCDVal_IsComposedString(*root_val)) { - NCDValRef copy = NCDVal__CopyComposedStringToStored(*root_val); - if (NCDVal_IsInvalid(copy)) { - return 0; - } - *root_val = copy; - } - - return 1; -} - -void NCDVal_Assert (NCDValRef val) -{ - ASSERT(val.idx == -1 || (NCDVal__AssertVal(val), 1)) -} - -int NCDVal_IsInvalid (NCDValRef val) -{ - NCDVal_Assert(val); - - return (val.idx == -1); -} - -int NCDVal_IsPlaceholder (NCDValRef val) -{ - NCDVal_Assert(val); - - return (val.idx < -1); -} - -int NCDVal_Type (NCDValRef val) -{ - NCDVal__AssertVal(val); - - if (val.idx < -1) { - return NCDVAL_PLACEHOLDER; - } - - int *type_ptr = NCDValMem__BufAt(val.mem, val.idx); - - return get_external_type(*type_ptr); -} - -NCDValRef NCDVal_NewInvalid (void) -{ - NCDValRef ref = {NULL, -1}; - return ref; -} - -NCDValRef NCDVal_NewPlaceholder (NCDValMem *mem, int plid) -{ - NCDVal__AssertMem(mem); - ASSERT(plid >= 0) - ASSERT(NCDVAL_MINIDX + plid < -1) - - NCDValRef ref = {mem, NCDVAL_MINIDX + plid}; - return ref; -} - -int NCDVal_PlaceholderId (NCDValRef val) -{ - ASSERT(NCDVal_IsPlaceholder(val)) - - return (val.idx - NCDVAL_MINIDX); -} - -NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val) -{ - NCDVal__AssertMem(mem); - NCDVal__AssertVal(val); - - if (val.idx < -1) { - return NCDVal_NewPlaceholder(mem, NCDVal_PlaceholderId(val)); - } - - void *ptr = NCDValMem__BufAt(val.mem, val.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - - NCDVal__idx size = sizeof(struct NCDVal__string) + str_e->length + 1; - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__string)); - if (idx < 0) { - goto fail; - } - - str_e = NCDValMem__BufAt(val.mem, val.idx); - struct NCDVal__string *new_str_e = NCDValMem__BufAt(mem, idx); - - memcpy(new_str_e, str_e, size); - - return NCDVal__Ref(mem, idx); - } break; - - case NCDVAL_LIST: { - struct NCDVal__list *list_e = ptr; - - NCDVal__idx size = sizeof(struct NCDVal__list) + list_e->maxcount * sizeof(NCDVal__idx); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__list)); - if (idx < 0) { - goto fail; - } - - list_e = NCDValMem__BufAt(val.mem, val.idx); - struct NCDVal__list *new_list_e = NCDValMem__BufAt(mem, idx); - - *new_list_e = *list_e; - - NCDVal__idx count = list_e->count; - - for (NCDVal__idx i = 0; i < count; i++) { - NCDValRef elem_copy = NCDVal_NewCopy(mem, NCDVal__Ref(val.mem, list_e->elem_indices[i])); - if (NCDVal_IsInvalid(elem_copy)) { - goto fail; - } - - if (NCDValMem__NeedRegisterLink(mem, elem_copy.idx)) { - if (!NCDValMem__RegisterLink(mem, elem_copy.idx, idx + offsetof(struct NCDVal__list, elem_indices) + i * sizeof(NCDVal__idx))) { - goto fail; - } - } - - list_e = NCDValMem__BufAt(val.mem, val.idx); - new_list_e = NCDValMem__BufAt(mem, idx); - - new_list_e->elem_indices[i] = elem_copy.idx; - } - - return NCDVal__Ref(mem, idx); - } break; - - case NCDVAL_MAP: { - size_t count = NCDVal_MapCount(val); - - NCDValRef copy = NCDVal_NewMap(mem, count); - if (NCDVal_IsInvalid(copy)) { - goto fail; - } - - for (NCDValMapElem e = NCDVal_MapFirst(val); !NCDVal_MapElemInvalid(e); e = NCDVal_MapNext(val, e)) { - NCDValRef key_copy = NCDVal_NewCopy(mem, NCDVal_MapElemKey(val, e)); - NCDValRef val_copy = NCDVal_NewCopy(mem, NCDVal_MapElemVal(val, e)); - if (NCDVal_IsInvalid(key_copy) || NCDVal_IsInvalid(val_copy)) { - goto fail; - } - - int inserted; - if (!NCDVal_MapInsert(copy, key_copy, val_copy, &inserted)) { - goto fail; - } - ASSERT_EXECUTE(inserted) - } - - return copy; - } break; - - case IDSTRING_TYPE: { - NCDVal__idx size = sizeof(struct NCDVal__idstring); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__idstring)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(val.mem, val.idx); - struct NCDVal__idstring *new_ids_e = NCDValMem__BufAt(mem, idx); - - *new_ids_e = *ids_e; - - return NCDVal__Ref(mem, idx); - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - - return NCDVal_NewExternalString(mem, exs_e->data, exs_e->length, exs_e->ref.target); - } break; - - case COMPOSEDSTRING_TYPE: { - struct NCDVal__composedstring *cms_e = ptr; - - NCDValComposedStringResource resource; - resource.func_getptr = cms_e->func_getptr; - resource.user = cms_e->user; - resource.ref_target = cms_e->ref.target; - - return NCDVal_NewComposedString(mem, resource, cms_e->offset, cms_e->length); - } break; - - default: ASSERT(0); - } - - ASSERT(0); - -fail: - return NCDVal_NewInvalid(); -} - -int NCDVal_Compare (NCDValRef val1, NCDValRef val2) -{ - NCDVal__AssertVal(val1); - NCDVal__AssertVal(val2); - - int type1 = NCDVal_Type(val1); - int type2 = NCDVal_Type(val2); - - if (type1 != type2) { - return (type1 > type2) - (type1 < type2); - } - - switch (type1) { - case NCDVAL_STRING: { - size_t len1 = NCDVal_StringLength(val1); - size_t len2 = NCDVal_StringLength(val2); - size_t min_len = len1 < len2 ? len1 : len2; - - int cmp = NCDVal_StringMemCmp(val1, val2, 0, 0, min_len); - if (cmp) { - return (cmp > 0) - (cmp < 0); - } - - return (len1 > len2) - (len1 < len2); - } break; - - case NCDVAL_LIST: { - size_t count1 = NCDVal_ListCount(val1); - size_t count2 = NCDVal_ListCount(val2); - size_t min_count = count1 < count2 ? count1 : count2; - - for (size_t i = 0; i < min_count; i++) { - NCDValRef ev1 = NCDVal_ListGet(val1, i); - NCDValRef ev2 = NCDVal_ListGet(val2, i); - - int cmp = NCDVal_Compare(ev1, ev2); - if (cmp) { - return cmp; - } - } - - return (count1 > count2) - (count1 < count2); - } break; - - case NCDVAL_MAP: { - NCDValMapElem e1 = NCDVal_MapOrderedFirst(val1); - NCDValMapElem e2 = NCDVal_MapOrderedFirst(val2); - - while (1) { - int inv1 = NCDVal_MapElemInvalid(e1); - int inv2 = NCDVal_MapElemInvalid(e2); - if (inv1 || inv2) { - return inv2 - inv1; - } - - NCDValRef key1 = NCDVal_MapElemKey(val1, e1); - NCDValRef key2 = NCDVal_MapElemKey(val2, e2); - - int cmp = NCDVal_Compare(key1, key2); - if (cmp) { - return cmp; - } - - NCDValRef value1 = NCDVal_MapElemVal(val1, e1); - NCDValRef value2 = NCDVal_MapElemVal(val2, e2); - - cmp = NCDVal_Compare(value1, value2); - if (cmp) { - return cmp; - } - - e1 = NCDVal_MapOrderedNext(val1, e1); - e2 = NCDVal_MapOrderedNext(val2, e2); - } - } break; - - case NCDVAL_PLACEHOLDER: { - int plid1 = NCDVal_PlaceholderId(val1); - int plid2 = NCDVal_PlaceholderId(val2); - - return (plid1 > plid2) - (plid1 < plid2); - } break; - - default: - ASSERT(0); - return 0; - } -} - -NCDValSafeRef NCDVal_ToSafe (NCDValRef val) -{ - NCDVal_Assert(val); - - NCDValSafeRef sval = {val.idx}; - return sval; -} - -NCDValRef NCDVal_FromSafe (NCDValMem *mem, NCDValSafeRef sval) -{ - NCDVal__AssertMem(mem); - ASSERT(sval.idx == -1 || (NCDVal__AssertValOnly(mem, sval.idx), 1)) - - NCDValRef val = {mem, sval.idx}; - return val; -} - -NCDValRef NCDVal_Moved (NCDValMem *mem, NCDValRef val) -{ - NCDVal__AssertMem(mem); - ASSERT(val.idx == -1 || (NCDVal__AssertValOnly(mem, val.idx), 1)) - - NCDValRef val2 = {mem, val.idx}; - return val2; -} - -int NCDVal_HasOnlyContinuousStrings (NCDValRef val) -{ - NCDVal__AssertVal(val); - - switch (NCDVal_Type(val)) { - case NCDVAL_STRING: { - if (!NCDVal_IsContinuousString(val)) { - return 0; - } - } break; - - case NCDVAL_LIST: { - size_t count = NCDVal_ListCount(val); - for (size_t i = 0; i < count; i++) { - NCDValRef elem = NCDVal_ListGet(val, i); - if (!NCDVal_HasOnlyContinuousStrings(elem)) { - return 0; - } - } - } break; - - case NCDVAL_MAP: { - for (NCDValMapElem me = NCDVal_MapFirst(val); !NCDVal_MapElemInvalid(me); me = NCDVal_MapNext(val, me)) { - NCDValRef e_key = NCDVal_MapElemKey(val, me); - NCDValRef e_val = NCDVal_MapElemVal(val, me); - if (!NCDVal_HasOnlyContinuousStrings(e_key) || !NCDVal_HasOnlyContinuousStrings(e_val)) { - return 0; - } - } - } break; - - case NCDVAL_PLACEHOLDER: { - } break; - - default: - ASSERT(0); - } - - return 1; -} - -int NCDVal_IsString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return NCDVal_Type(val) == NCDVAL_STRING; -} - -int NCDVal_IsContinuousString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - if (val.idx < -1) { - return 0; - } - - switch (get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx))) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - return 1; - default: - return 0; - } -} - -int NCDVal_IsStoredString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == STOREDSTRING_TYPE; -} - -int NCDVal_IsIdString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == IDSTRING_TYPE; -} - -int NCDVal_IsExternalString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == EXTERNALSTRING_TYPE; -} - -int NCDVal_IsComposedString (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return !(val.idx < -1) && get_internal_type(*(int *)NCDValMem__BufAt(val.mem, val.idx)) == COMPOSEDSTRING_TYPE; -} - -int NCDVal_IsStringNoNulls (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return NCDVal_Type(val) == NCDVAL_STRING && !NCDVal_StringHasNulls(val); -} - -NCDValRef NCDVal_NewString (NCDValMem *mem, const char *data) -{ - NCDVal__AssertMem(mem); - ASSERT(data) - NCDVal_AssertExternal(mem, data, strlen(data)); - - return NCDVal_NewStringBin(mem, (const uint8_t *)data, strlen(data)); -} - -NCDValRef NCDVal_NewStringBin (NCDValMem *mem, const uint8_t *data, size_t len) -{ - NCDVal__AssertMem(mem); - ASSERT(len == 0 || data) - NCDVal_AssertExternal(mem, data, len); - - if (len > NCDVAL_MAXIDX - sizeof(struct NCDVal__string) - 1) { - goto fail; - } - - NCDVal__idx size = sizeof(struct NCDVal__string) + len + 1; - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__string)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__string *str_e = NCDValMem__BufAt(mem, idx); - str_e->type = make_type(STOREDSTRING_TYPE, 0); - str_e->length = len; - if (len > 0) { - memcpy(str_e->data, data, len); - } - str_e->data[len] = '\0'; - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -NCDValRef NCDVal_NewStringUninitialized (NCDValMem *mem, size_t len) -{ - NCDVal__AssertMem(mem); - - if (len > NCDVAL_MAXIDX - sizeof(struct NCDVal__string) - 1) { - goto fail; - } - - NCDVal__idx size = sizeof(struct NCDVal__string) + len + 1; - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__string)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__string *str_e = NCDValMem__BufAt(mem, idx); - str_e->type = make_type(STOREDSTRING_TYPE, 0); - str_e->length = len; - str_e->data[len] = '\0'; - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id, NCDStringIndex *string_index) -{ - NCDVal__AssertMem(mem); - ASSERT(string_id >= 0) - ASSERT(string_index) - - NCDVal__idx size = sizeof(struct NCDVal__idstring); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__idstring)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(mem, idx); - ids_e->type = make_type(IDSTRING_TYPE, 0); - ids_e->string_id = string_id; - ids_e->string_index = string_index; - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -NCDValRef NCDVal_NewExternalString (NCDValMem *mem, const char *data, size_t len, - BRefTarget *ref_target) -{ - NCDVal__AssertMem(mem); - ASSERT(data) - NCDVal_AssertExternal(mem, data, len); - - NCDVal__idx size = sizeof(struct NCDVal__externalstring); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__externalstring)); - if (idx < 0) { - goto fail; - } - - if (ref_target) { - if (!BRefTarget_Ref(ref_target)) { - goto fail; - } - } - - struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(mem, idx); - exs_e->type = make_type(EXTERNALSTRING_TYPE, 0); - exs_e->data = data; - exs_e->length = len; - exs_e->ref.target = ref_target; - - if (ref_target) { - exs_e->ref.next = mem->first_ref; - mem->first_ref = idx + offsetof(struct NCDVal__externalstring, ref); - } - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -NCDValRef NCDVal_NewComposedString (NCDValMem *mem, NCDValComposedStringResource resource, size_t offset, size_t length) -{ - NCDVal__AssertMem(mem); - ASSERT(resource.func_getptr) - - NCDVal__idx size = sizeof(struct NCDVal__composedstring); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__composedstring)); - if (idx < 0) { - goto fail; - } - - if (resource.ref_target) { - if (!BRefTarget_Ref(resource.ref_target)) { - goto fail; - } - } - - struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(mem, idx); - cms_e->type = make_type(COMPOSEDSTRING_TYPE, 0); - cms_e->offset = offset; - cms_e->length = length; - cms_e->func_getptr = resource.func_getptr; - cms_e->user = resource.user; - cms_e->ref.target = resource.ref_target; - - if (resource.ref_target) { - cms_e->ref.next = mem->first_ref; - mem->first_ref = idx + offsetof(struct NCDVal__composedstring, ref); - } - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -const char * NCDVal_StringData (NCDValRef contstring) -{ - ASSERT(NCDVal_IsContinuousString(contstring)) - - void *ptr = NCDValMem__BufAt(contstring.mem, contstring.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - return str_e->data; - } break; - - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - const char *value = NCDStringIndex_Value(ids_e->string_index, ids_e->string_id); - return value; - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - return exs_e->data; - } break; - - default: - ASSERT(0); - return NULL; - } -} - -size_t NCDVal_StringLength (NCDValRef string) -{ - ASSERT(NCDVal_IsString(string)) - - void *ptr = NCDValMem__BufAt(string.mem, string.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - return str_e->length; - } break; - - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - return NCDStringIndex_Length(ids_e->string_index, ids_e->string_id); - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - return exs_e->length; - } break; - - case COMPOSEDSTRING_TYPE: { - struct NCDVal__composedstring *cms_e = ptr; - return cms_e->length; - } break; - - default: - ASSERT(0); - return 0; - } -} - -b_cstring NCDValComposedStringResource_Cstring (NCDValComposedStringResource resource, size_t offset, size_t length) -{ - b_cstring cstr; - cstr.length = length; - cstr.func = NCDVal__composedstring_cstring_func; - cstr.user1.size = offset; - cstr.user2.fptr = (void (*) (void))resource.func_getptr; - cstr.user3.ptr = resource.user; - return cstr; -} - -b_cstring NCDVal_StringCstring (NCDValRef string) -{ - ASSERT(NCDVal_IsString(string)) - - void *ptr = NCDValMem__BufAt(string.mem, string.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - return b_cstring_make_buf(str_e->data, str_e->length); - } break; - - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - return b_cstring_make_buf(NCDStringIndex_Value(ids_e->string_index, ids_e->string_id), NCDStringIndex_Length(ids_e->string_index, ids_e->string_id)); - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - return b_cstring_make_buf(exs_e->data, exs_e->length); - } break; - - case COMPOSEDSTRING_TYPE: { - struct NCDVal__composedstring *cms_e = ptr; - b_cstring cstr; - cstr.length = cms_e->length; - cstr.func = NCDVal__composedstring_cstring_func; - cstr.user1.size = cms_e->offset; - cstr.user2.fptr = (void (*) (void))cms_e->func_getptr; - cstr.user3.ptr = cms_e->user; - return cstr; - } break; - - default: { - ASSERT(0); - return b_cstring_make_empty(); - } break; - } -} - -int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(out) - - void *ptr = NCDValMem__BufAt(string.mem, string.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - out->data = str_e->data; - out->is_allocated = 0; - return 1; - } break; - - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - out->data = (char *)NCDStringIndex_Value(ids_e->string_index, ids_e->string_id); - out->is_allocated = 0; - return 1; - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - - char *copy = b_strdup_bin(exs_e->data, exs_e->length); - if (!copy) { - return 0; - } - - out->data = copy; - out->is_allocated = 1; - return 1; - } break; - - case COMPOSEDSTRING_TYPE: { - struct NCDVal__composedstring *cms_e = ptr; - size_t length = cms_e->length; - - if (length == SIZE_MAX) { - return 0; - } - - char *copy = BAlloc(length + 1); - if (!copy) { - return 0; - } - - NCDVal_StringCopyOut(string, 0, length, copy); - copy[length] = '\0'; - - out->data = copy; - out->is_allocated = 1; - return 1; - } break; - - default: - ASSERT(0); - return 0; - } -} - -NCDValNullTermString NCDValNullTermString_NewDummy (void) -{ - NCDValNullTermString nts; - nts.data = NULL; - nts.is_allocated = 0; - return nts; -} - -void NCDValNullTermString_Free (NCDValNullTermString *o) -{ - if (o->is_allocated) { - BFree(o->data); - } -} - -int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(out) - - if (NCDVal_IsContinuousString(string)) { - out->data = (char *)NCDVal_StringData(string); - out->is_allocated = 0; - return 1; - } - - size_t length = NCDVal_StringLength(string); - - char *data = BAlloc(length); - if (!data) { - return 0; - } - - NCDVal_StringCopyOut(string, 0, length, data); - - out->data = data; - out->is_allocated = 1; - return 1; -} - -NCDValContString NCDValContString_NewDummy (void) -{ - NCDValContString cts; - cts.data = NULL; - cts.is_allocated = 0; - return cts; -} - -void NCDValContString_Free (NCDValContString *o) -{ - if (o->is_allocated) { - BFree(o->data); - } -} - -void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id, - NCDStringIndex **out_string_index) -{ - ASSERT(NCDVal_IsIdString(idstring)) - ASSERT(out_string_id) - ASSERT(out_string_index) - - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(idstring.mem, idstring.idx); - *out_string_id = ids_e->string_id; - *out_string_index = ids_e->string_index; -} - -NCD_string_id_t NCDVal_IdStringId (NCDValRef idstring) -{ - ASSERT(NCDVal_IsIdString(idstring)) - - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(idstring.mem, idstring.idx); - return ids_e->string_id; -} - -NCDStringIndex * NCDVal_IdStringStringIndex (NCDValRef idstring) -{ - ASSERT(NCDVal_IsIdString(idstring)) - - struct NCDVal__idstring *ids_e = NCDValMem__BufAt(idstring.mem, idstring.idx); - return ids_e->string_index; -} - -BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring) -{ - ASSERT(NCDVal_IsExternalString(externalstring)) - - struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(externalstring.mem, externalstring.idx); - return exs_e->ref.target; -} - -NCDValComposedStringResource NCDVal_ComposedStringResource (NCDValRef composedstring) -{ - ASSERT(NCDVal_IsComposedString(composedstring)) - - struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(composedstring.mem, composedstring.idx); - - NCDValComposedStringResource res; - res.func_getptr = cms_e->func_getptr; - res.user = cms_e->user; - res.ref_target = cms_e->ref.target; - - return res; -} - -size_t NCDVal_ComposedStringOffset (NCDValRef composedstring) -{ - ASSERT(NCDVal_IsComposedString(composedstring)) - - struct NCDVal__composedstring *cms_e = NCDValMem__BufAt(composedstring.mem, composedstring.idx); - - return cms_e->offset; -} - -int NCDVal_StringHasNulls (NCDValRef string) -{ - ASSERT(NCDVal_IsString(string)) - - void *ptr = NCDValMem__BufAt(string.mem, string.idx); - - switch (get_internal_type(*(int *)ptr)) { - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - return NCDStringIndex_HasNulls(ids_e->string_index, ids_e->string_id); - } break; - - case STOREDSTRING_TYPE: - case EXTERNALSTRING_TYPE: { - const char *data = NCDVal_StringData(string); - size_t length = NCDVal_StringLength(string); - return !!memchr(data, '\0', length); - } break; - - case COMPOSEDSTRING_TYPE: { - b_cstring cstr = NCDVal_StringCstring(string); - return b_cstring_memchr(cstr, 0, cstr.length, '\0', NULL); - } break; - - default: - ASSERT(0); - return 0; - } -} - -int NCDVal_StringEquals (NCDValRef string, const char *data) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(data) - - size_t data_len = strlen(data); - - return NCDVal_StringLength(string) == data_len && NCDVal_StringRegionEquals(string, 0, data_len, data); -} - -int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id, - NCDStringIndex *string_index) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(string_id >= 0) - ASSERT(string_index) - - void *ptr = NCDValMem__BufAt(string.mem, string.idx); - - switch (get_internal_type(*(int *)ptr)) { - case STOREDSTRING_TYPE: { - struct NCDVal__string *str_e = ptr; - const char *string_data = NCDStringIndex_Value(string_index, string_id); - size_t string_length = NCDStringIndex_Length(string_index, string_id); - return (string_length == str_e->length) && !memcmp(string_data, str_e->data, string_length); - } break; - - case IDSTRING_TYPE: { - struct NCDVal__idstring *ids_e = ptr; - ASSERT(ids_e->string_index == string_index) - return ids_e->string_id == string_id; - } break; - - case EXTERNALSTRING_TYPE: { - struct NCDVal__externalstring *exs_e = ptr; - const char *string_data = NCDStringIndex_Value(string_index, string_id); - size_t string_length = NCDStringIndex_Length(string_index, string_id); - return (string_length == exs_e->length) && !memcmp(string_data, exs_e->data, string_length); - } break; - - case COMPOSEDSTRING_TYPE: { - struct NCDVal__composedstring *cms_e = ptr; - const char *string_data = NCDStringIndex_Value(string_index, string_id); - size_t string_length = NCDStringIndex_Length(string_index, string_id); - return (string_length == cms_e->length) && NCDVal_StringRegionEquals(string, 0, string_length, string_data); - } break; - - default: - ASSERT(0); - return 0; - } -} - -int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, size_t start2, size_t length) -{ - ASSERT(NCDVal_IsString(string1)) - ASSERT(NCDVal_IsString(string2)) - ASSERT(start1 <= NCDVal_StringLength(string1)) - ASSERT(start2 <= NCDVal_StringLength(string2)) - ASSERT(length <= NCDVal_StringLength(string1) - start1) - ASSERT(length <= NCDVal_StringLength(string2) - start2) - - if (NCDVal_IsContinuousString(string1) && NCDVal_IsContinuousString(string2)) { - return memcmp(NCDVal_StringData(string1) + start1, NCDVal_StringData(string2) + start2, length); - } - - b_cstring cstr1 = NCDVal_StringCstring(string1); - b_cstring cstr2 = NCDVal_StringCstring(string2); - return b_cstring_memcmp(cstr1, cstr2, start1, start2, length); -} - -void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(start <= NCDVal_StringLength(string)) - ASSERT(length <= NCDVal_StringLength(string) - start) - - if (NCDVal_IsContinuousString(string)) { - memcpy(dst, NCDVal_StringData(string) + start, length); - return; - } - - b_cstring cstr = NCDVal_StringCstring(string); - b_cstring_copy_to_buf(cstr, start, length, dst); -} - -int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(start <= NCDVal_StringLength(string)) - ASSERT(length <= NCDVal_StringLength(string) - start) - - if (NCDVal_IsContinuousString(string)) { - return !memcmp(NCDVal_StringData(string) + start, data, length); - } - - b_cstring cstr = NCDVal_StringCstring(string); - return b_cstring_equals_buffer(cstr, start, length, data); -} - -int NCDVal_IsList (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return NCDVal_Type(val) == NCDVAL_LIST; -} - -NCDValRef NCDVal_NewList (NCDValMem *mem, size_t maxcount) -{ - NCDVal__AssertMem(mem); - - if (maxcount > (NCDVAL_MAXIDX - sizeof(struct NCDVal__list)) / sizeof(NCDVal__idx)) { - goto fail; - } - - NCDVal__idx size = sizeof(struct NCDVal__list) + maxcount * sizeof(NCDVal__idx); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__list)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__list *list_e = NCDValMem__BufAt(mem, idx); - list_e->type = make_type(NCDVAL_LIST, 0); - list_e->maxcount = maxcount; - list_e->count = 0; - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -int NCDVal_ListAppend (NCDValRef list, NCDValRef elem) -{ - ASSERT(NCDVal_IsList(list)) - ASSERT(NCDVal_ListCount(list) < NCDVal_ListMaxCount(list)) - ASSERT(elem.mem == list.mem) - NCDVal__AssertValOnly(list.mem, elem.idx); - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - int new_type = list_e->type; - if (!bump_depth(&new_type, NCDVal__Depth(elem))) { - return 0; - } - - if (NCDValMem__NeedRegisterLink(list.mem, elem.idx)) { - if (!NCDValMem__RegisterLink(list.mem, elem.idx, list.idx + offsetof(struct NCDVal__list, elem_indices) + list_e->count * sizeof(NCDVal__idx))) { - return 0; - } - list_e = NCDValMem__BufAt(list.mem, list.idx); - } - - list_e->type = new_type; - list_e->elem_indices[list_e->count++] = elem.idx; - - return 1; -} - -size_t NCDVal_ListCount (NCDValRef list) -{ - ASSERT(NCDVal_IsList(list)) - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - return list_e->count; -} - -size_t NCDVal_ListMaxCount (NCDValRef list) -{ - ASSERT(NCDVal_IsList(list)) - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - return list_e->maxcount; -} - -NCDValRef NCDVal_ListGet (NCDValRef list, size_t pos) -{ - ASSERT(NCDVal_IsList(list)) - ASSERT(pos < NCDVal_ListCount(list)) - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - ASSERT(pos < list_e->count) - NCDVal__AssertValOnly(list.mem, list_e->elem_indices[pos]); - - return NCDVal__Ref(list.mem, list_e->elem_indices[pos]); -} - -int NCDVal_ListRead (NCDValRef list, int num, ...) -{ - ASSERT(NCDVal_IsList(list)) - ASSERT(num >= 0) - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - if (num != list_e->count) { - return 0; - } - - va_list ap; - va_start(ap, num); - - for (int i = 0; i < num; i++) { - NCDValRef *dest = va_arg(ap, NCDValRef *); - *dest = NCDVal__Ref(list.mem, list_e->elem_indices[i]); - } - - va_end(ap); - - return 1; -} - -int NCDVal_ListReadHead (NCDValRef list, int num, ...) -{ - ASSERT(NCDVal_IsList(list)) - ASSERT(num >= 0) - - struct NCDVal__list *list_e = NCDValMem__BufAt(list.mem, list.idx); - - if (num > list_e->count) { - return 0; - } - - va_list ap; - va_start(ap, num); - - for (int i = 0; i < num; i++) { - NCDValRef *dest = va_arg(ap, NCDValRef *); - *dest = NCDVal__Ref(list.mem, list_e->elem_indices[i]); - } - - va_end(ap); - - return 1; -} - -int NCDVal_IsMap (NCDValRef val) -{ - NCDVal__AssertVal(val); - - return NCDVal_Type(val) == NCDVAL_MAP; -} - -NCDValRef NCDVal_NewMap (NCDValMem *mem, size_t maxcount) -{ - NCDVal__AssertMem(mem); - - if (maxcount > (NCDVAL_MAXIDX - sizeof(struct NCDVal__map)) / sizeof(struct NCDVal__mapelem)) { - goto fail; - } - - NCDVal__idx size = sizeof(struct NCDVal__map) + maxcount * sizeof(struct NCDVal__mapelem); - NCDVal__idx idx = NCDValMem__Alloc(mem, size, __alignof(struct NCDVal__map)); - if (idx < 0) { - goto fail; - } - - struct NCDVal__map *map_e = NCDValMem__BufAt(mem, idx); - map_e->type = make_type(NCDVAL_MAP, 0); - map_e->maxcount = maxcount; - map_e->count = 0; - NCDVal__MapTree_Init(&map_e->tree); - - return NCDVal__Ref(mem, idx); - -fail: - return NCDVal_NewInvalid(); -} - -int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inserted) -{ - ASSERT(NCDVal_IsMap(map)) - ASSERT(NCDVal_MapCount(map) < NCDVal_MapMaxCount(map)) - ASSERT(key.mem == map.mem) - ASSERT(val.mem == map.mem) - NCDVal__AssertValOnly(map.mem, key.idx); - NCDVal__AssertValOnly(map.mem, val.idx); - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - int new_type = map_e->type; - if (!bump_depth(&new_type, NCDVal__Depth(key)) || !bump_depth(&new_type, NCDVal__Depth(val))) { - goto fail0; - } - - NCDVal__idx elemidx = NCDVal__MapElemIdx(map.idx, map_e->count); - - if (NCDValMem__NeedRegisterLink(map.mem, key.idx)) { - if (!NCDValMem__RegisterLink(map.mem, key.idx, elemidx + offsetof(struct NCDVal__mapelem, key_idx))) { - goto fail0; - } - map_e = NCDValMem__BufAt(map.mem, map.idx); - } - - if (NCDValMem__NeedRegisterLink(map.mem, val.idx)) { - if (!NCDValMem__RegisterLink(map.mem, val.idx, elemidx + offsetof(struct NCDVal__mapelem, val_idx))) { - goto fail1; - } - map_e = NCDValMem__BufAt(map.mem, map.idx); - } - - struct NCDVal__mapelem *me_e = NCDValMem__BufAt(map.mem, elemidx); - ASSERT(me_e == &map_e->elems[map_e->count]) - me_e->key_idx = key.idx; - me_e->val_idx = val.idx; - - int res = NCDVal__MapTree_Insert(&map_e->tree, map.mem, NCDVal__MapTreeDeref(map.mem, elemidx), NULL); - if (!res) { - if (out_inserted) { - *out_inserted = 0; - } - return 1; - } - - map_e->type = new_type; - map_e->count++; - - if (out_inserted) { - *out_inserted = 1; - } - return 1; - -fail1: - if (NCDValMem__NeedRegisterLink(map.mem, key.idx)) { - NCDValMem__PopLastRegisteredLink(map.mem); - } -fail0: - return 0; -} - -size_t NCDVal_MapCount (NCDValRef map) -{ - ASSERT(NCDVal_IsMap(map)) - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - return map_e->count; -} - -size_t NCDVal_MapMaxCount (NCDValRef map) -{ - ASSERT(NCDVal_IsMap(map)) - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - return map_e->maxcount; -} - -int NCDVal_MapElemInvalid (NCDValMapElem me) -{ - ASSERT(me.elemidx >= 0 || me.elemidx == -1) - - return me.elemidx < 0; -} - -NCDValMapElem NCDVal_MapFirst (NCDValRef map) -{ - ASSERT(NCDVal_IsMap(map)) - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - if (map_e->count == 0) { - return NCDVal__MapElem(-1); - } - - NCDVal__idx elemidx = NCDVal__MapElemIdx(map.idx, 0); - NCDVal__MapAssertElemOnly(map, elemidx); - - return NCDVal__MapElem(elemidx); -} - -NCDValMapElem NCDVal_MapNext (NCDValRef map, NCDValMapElem me) -{ - NCDVal__MapAssertElem(map, me); - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - ASSERT(map_e->count > 0) - - NCDVal__idx last_elemidx = NCDVal__MapElemIdx(map.idx, map_e->count - 1); - ASSERT(me.elemidx <= last_elemidx) - - if (me.elemidx == last_elemidx) { - return NCDVal__MapElem(-1); - } - - NCDVal__idx elemidx = me.elemidx + sizeof(struct NCDVal__mapelem); - NCDVal__MapAssertElemOnly(map, elemidx); - - return NCDVal__MapElem(elemidx); -} - -NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map) -{ - ASSERT(NCDVal_IsMap(map)) - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - NCDVal__MapTreeRef ref = NCDVal__MapTree_GetFirst(&map_e->tree, map.mem); - ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1)) - - return NCDVal__MapElem(ref.link); -} - -NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me) -{ - NCDVal__MapAssertElem(map, me); - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - NCDVal__MapTreeRef ref = NCDVal__MapTree_GetNext(&map_e->tree, map.mem, NCDVal__MapTreeDeref(map.mem, me.elemidx)); - ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1)) - - return NCDVal__MapElem(ref.link); -} - -NCDValRef NCDVal_MapElemKey (NCDValRef map, NCDValMapElem me) -{ - NCDVal__MapAssertElem(map, me); - - struct NCDVal__mapelem *me_e = NCDValMem__BufAt(map.mem, me.elemidx); - - return NCDVal__Ref(map.mem, me_e->key_idx); -} - -NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me) -{ - NCDVal__MapAssertElem(map, me); - - struct NCDVal__mapelem *me_e = NCDValMem__BufAt(map.mem, me.elemidx); - - return NCDVal__Ref(map.mem, me_e->val_idx); -} - -NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key) -{ - ASSERT(NCDVal_IsMap(map)) - NCDVal__AssertVal(key); - - struct NCDVal__map *map_e = NCDValMem__BufAt(map.mem, map.idx); - - NCDVal__MapTreeRef ref = NCDVal__MapTree_LookupExact(&map_e->tree, map.mem, key); - ASSERT(ref.link == -1 || (NCDVal__MapAssertElemOnly(map, ref.link), 1)) - - return NCDVal__MapElem(ref.link); -} - -NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str) -{ - ASSERT(NCDVal_IsMap(map)) - ASSERT(key_str) - - NCDValMem mem; - mem.buf = NULL; - mem.size = NCDVAL_FASTBUF_SIZE; - mem.used = sizeof(struct NCDVal__externalstring); - mem.first_ref = -1; - - struct NCDVal__externalstring *exs_e = (void *)mem.fastbuf; - exs_e->type = make_type(EXTERNALSTRING_TYPE, 0); - exs_e->data = key_str; - exs_e->length = strlen(key_str); - exs_e->ref.target = NULL; - - NCDValRef key = NCDVal__Ref(&mem, 0); - - NCDValMapElem elem = NCDVal_MapFindKey(map, key); - if (NCDVal_MapElemInvalid(elem)) { - return NCDVal_NewInvalid(); - } - - return NCDVal_MapElemVal(map, elem); -} - -static void replaceprog_build_recurser (NCDValMem *mem, NCDVal__idx idx, size_t *out_num_instr, NCDValReplaceProg *prog) -{ - ASSERT(idx >= 0) - NCDVal__AssertValOnly(mem, idx); - ASSERT(out_num_instr) - - *out_num_instr = 0; - - void *ptr = NCDValMem__BufAt(mem, idx); - - struct NCDVal__instr instr; - - switch (get_internal_type(*((int *)(ptr)))) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: { - } break; - - case NCDVAL_LIST: { - struct NCDVal__list *list_e = ptr; - - for (NCDVal__idx i = 0; i < list_e->count; i++) { - int elem_changed = 0; - - if (list_e->elem_indices[i] < -1) { - if (prog) { - instr.type = NCDVAL_INSTR_PLACEHOLDER; - instr.placeholder.plid = list_e->elem_indices[i] - NCDVAL_MINIDX; - instr.placeholder.plidx = idx + offsetof(struct NCDVal__list, elem_indices) + i * sizeof(NCDVal__idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - elem_changed = 1; - } else { - size_t elem_num_instr; - replaceprog_build_recurser(mem, list_e->elem_indices[i], &elem_num_instr, prog); - (*out_num_instr) += elem_num_instr; - if (elem_num_instr > 0) { - elem_changed = 1; - } - } - - if (elem_changed) { - if (prog) { - instr.type = NCDVAL_INSTR_BUMPDEPTH; - instr.bumpdepth.parent_idx = idx; - instr.bumpdepth.child_idx_idx = idx + offsetof(struct NCDVal__list, elem_indices) + i * sizeof(NCDVal__idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - } - } - } break; - - case NCDVAL_MAP: { - struct NCDVal__map *map_e = ptr; - - for (NCDVal__idx i = 0; i < map_e->count; i++) { - int key_changed = 0; - int val_changed = 0; - - if (map_e->elems[i].key_idx < -1) { - if (prog) { - instr.type = NCDVAL_INSTR_PLACEHOLDER; - instr.placeholder.plid = map_e->elems[i].key_idx - NCDVAL_MINIDX; - instr.placeholder.plidx = idx + offsetof(struct NCDVal__map, elems) + i * sizeof(struct NCDVal__mapelem) + offsetof(struct NCDVal__mapelem, key_idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - key_changed = 1; - } else { - size_t key_num_instr; - replaceprog_build_recurser(mem, map_e->elems[i].key_idx, &key_num_instr, prog); - (*out_num_instr) += key_num_instr; - if (key_num_instr > 0) { - key_changed = 1; - } - } - - if (map_e->elems[i].val_idx < -1) { - if (prog) { - instr.type = NCDVAL_INSTR_PLACEHOLDER; - instr.placeholder.plid = map_e->elems[i].val_idx - NCDVAL_MINIDX; - instr.placeholder.plidx = idx + offsetof(struct NCDVal__map, elems) + i * sizeof(struct NCDVal__mapelem) + offsetof(struct NCDVal__mapelem, val_idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - val_changed = 1; - } else { - size_t val_num_instr; - replaceprog_build_recurser(mem, map_e->elems[i].val_idx, &val_num_instr, prog); - (*out_num_instr) += val_num_instr; - if (val_num_instr > 0) { - val_changed = 1; - } - } - - if (key_changed) { - if (prog) { - instr.type = NCDVAL_INSTR_REINSERT; - instr.reinsert.mapidx = idx; - instr.reinsert.elempos = i; - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - - if (prog) { - instr.type = NCDVAL_INSTR_BUMPDEPTH; - instr.bumpdepth.parent_idx = idx; - instr.bumpdepth.child_idx_idx = idx + offsetof(struct NCDVal__map, elems) + i * sizeof(struct NCDVal__mapelem) + offsetof(struct NCDVal__mapelem, key_idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - } - - if (val_changed) { - if (prog) { - instr.type = NCDVAL_INSTR_BUMPDEPTH; - instr.bumpdepth.parent_idx = idx; - instr.bumpdepth.child_idx_idx = idx + offsetof(struct NCDVal__map, elems) + i * sizeof(struct NCDVal__mapelem) + offsetof(struct NCDVal__mapelem, val_idx); - prog->instrs[prog->num_instrs++] = instr; - } - (*out_num_instr)++; - } - } - } break; - - default: ASSERT(0); - } -} - -int NCDValReplaceProg_Init (NCDValReplaceProg *o, NCDValRef val) -{ - NCDVal__AssertVal(val); - ASSERT(!NCDVal_IsPlaceholder(val)) - - size_t num_instrs; - replaceprog_build_recurser(val.mem, val.idx, &num_instrs, NULL); - - if (!(o->instrs = BAllocArray(num_instrs, sizeof(o->instrs[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - return 0; - } - - o->num_instrs = 0; - - size_t num_instrs2; - replaceprog_build_recurser(val.mem, val.idx, &num_instrs2, o); - - ASSERT(num_instrs2 == num_instrs) - ASSERT(o->num_instrs == num_instrs) - - return 1; -} - -void NCDValReplaceProg_Free (NCDValReplaceProg *o) -{ - BFree(o->instrs); -} - -int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_replace_func replace, void *arg) -{ - NCDVal__AssertMem(mem); - ASSERT(replace) - - for (size_t i = 0; i < prog.num_instrs; i++) { - struct NCDVal__instr instr = prog.instrs[i]; - - switch (instr.type) { - case NCDVAL_INSTR_PLACEHOLDER: { -#ifndef NDEBUG - NCDVal__idx *check_plptr = NCDValMem__BufAt(mem, instr.placeholder.plidx); - ASSERT(*check_plptr < -1) - ASSERT(*check_plptr - NCDVAL_MINIDX == instr.placeholder.plid) -#endif - NCDValRef repval; - if (!replace(arg, instr.placeholder.plid, mem, &repval) || NCDVal_IsInvalid(repval)) { - return 0; - } - ASSERT(repval.mem == mem) - - if (NCDValMem__NeedRegisterLink(mem, repval.idx)) { - NCDValMem__RegisterLink(mem, repval.idx, instr.placeholder.plidx); - } - - NCDVal__idx *plptr = NCDValMem__BufAt(mem, instr.placeholder.plidx); - *plptr = repval.idx; - } break; - - case NCDVAL_INSTR_REINSERT: { - NCDVal__AssertValOnly(mem, instr.reinsert.mapidx); - struct NCDVal__map *map_e = NCDValMem__BufAt(mem, instr.reinsert.mapidx); - ASSERT(get_internal_type(map_e->type) == NCDVAL_MAP) - ASSERT(instr.reinsert.elempos >= 0) - ASSERT(instr.reinsert.elempos < map_e->count) - - NCDVal__MapTreeRef ref = {&map_e->elems[instr.reinsert.elempos], NCDVal__MapElemIdx(instr.reinsert.mapidx, instr.reinsert.elempos)}; - NCDVal__MapTree_Remove(&map_e->tree, mem, ref); - if (!NCDVal__MapTree_Insert(&map_e->tree, mem, ref, NULL)) { - BLog(BLOG_ERROR, "duplicate key in map"); - return 0; - } - } break; - - case NCDVAL_INSTR_BUMPDEPTH: { - NCDVal__AssertValOnly(mem, instr.bumpdepth.parent_idx); - int *parent_type_ptr = NCDValMem__BufAt(mem, instr.bumpdepth.parent_idx); - - NCDVal__idx *child_type_idx_ptr = NCDValMem__BufAt(mem, instr.bumpdepth.child_idx_idx); - NCDVal__AssertValOnly(mem, *child_type_idx_ptr); - int *child_type_ptr = NCDValMem__BufAt(mem, *child_type_idx_ptr); - - if (!bump_depth(parent_type_ptr, get_depth(*child_type_ptr))) { - BLog(BLOG_ERROR, "depth limit exceeded"); - return 0; - } - } break; - - default: ASSERT(0); - } - } - - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDVal.h b/external/badvpn_dns/ncd/NCDVal.h deleted file mode 100644 index 26154da..0000000 --- a/external/badvpn_dns/ncd/NCDVal.h +++ /dev/null @@ -1,857 +0,0 @@ -/** - * @file NCDVal.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDVAL_H -#define BADVPN_NCDVAL_H - -#include <stddef.h> -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/cstring.h> -#include <misc/BRefTarget.h> -#include <structure/CAvl.h> -#include <ncd/NCDStringIndex.h> - -// these are implementation details. The interface is defined below. - -#define NCDVAL_FASTBUF_SIZE 64 -#define NCDVAL_FIRST_SIZE 256 -#define NCDVAL_MAX_DEPTH 32 - -#define NCDVAL_MAXIDX INT_MAX -#define NCDVAL_MINIDX INT_MIN - -typedef int NCDVal__idx; - -struct NCDVal__ref { - NCDVal__idx next; - BRefTarget *target; -}; - -struct NCDVal__string { - int type; - NCDVal__idx length; - char data[]; -}; - -struct NCDVal__list { - int type; - NCDVal__idx maxcount; - NCDVal__idx count; - NCDVal__idx elem_indices[]; -}; - -struct NCDVal__mapelem { - NCDVal__idx key_idx; - NCDVal__idx val_idx; - NCDVal__idx tree_child[2]; - NCDVal__idx tree_parent; - int8_t tree_balance; -}; - -struct NCDVal__idstring { - int type; - NCD_string_id_t string_id; - NCDStringIndex *string_index; -}; - -struct NCDVal__externalstring { - int type; - const char *data; - size_t length; - struct NCDVal__ref ref; -}; - -struct NCDVal__composedstring { - int type; - size_t offset; - size_t length; - void (*func_getptr) (void *, size_t, const char **, size_t *); - void *user; - struct NCDVal__ref ref; -}; - -struct NCDVal__cms_link { - NCDVal__idx link_idx; - NCDVal__idx next_cms_link; -}; - -typedef struct { - char *buf; - NCDVal__idx size; - NCDVal__idx used; - NCDVal__idx first_ref; - NCDVal__idx first_cms_link; - union { - char fastbuf[NCDVAL_FASTBUF_SIZE]; - struct NCDVal__ref align_ref; - struct NCDVal__string align_string; - struct NCDVal__list align_list; - struct NCDVal__mapelem align_mapelem; - struct NCDVal__idstring align_idstring; - struct NCDVal__externalstring align_externalstring; - struct NCDVal__composedstring align_composedstring; - struct NCDVal__cms_link align_cms_link; - }; -} NCDValMem; - -typedef struct { - NCDValMem *mem; - NCDVal__idx idx; -} NCDValRef; - -typedef struct { - NCDVal__idx idx; -} NCDValSafeRef; - -typedef struct NCDVal__mapelem NCDVal__maptree_entry; -typedef NCDValMem *NCDVal__maptree_arg; - -#include "NCDVal_maptree.h" -#include <structure/CAvl_decl.h> - -struct NCDVal__map { - int type; - NCDVal__idx maxcount; - NCDVal__idx count; - NCDVal__MapTree tree; - struct NCDVal__mapelem elems[]; -}; - -typedef struct { - NCDVal__idx elemidx; -} NCDValMapElem; - -#define NCDVAL_INSTR_PLACEHOLDER 0 -#define NCDVAL_INSTR_REINSERT 1 -#define NCDVAL_INSTR_BUMPDEPTH 2 - -struct NCDVal__instr { - int type; - union { - struct { - NCDVal__idx plid; - NCDVal__idx plidx; - } placeholder; - struct { - NCDVal__idx mapidx; - NCDVal__idx elempos; - } reinsert; - struct { - NCDVal__idx parent_idx; - NCDVal__idx child_idx_idx; - } bumpdepth; - }; -}; - -typedef struct { - struct NCDVal__instr *instrs; - size_t num_instrs; -} NCDValReplaceProg; - -typedef struct { - char *data; - int is_allocated; -} NCDValNullTermString; - -typedef struct { - char *data; - int is_allocated; -} NCDValContString; - -// - -#define NCDVAL_STRING 1 -#define NCDVAL_LIST 2 -#define NCDVAL_MAP 3 -#define NCDVAL_PLACEHOLDER 4 - -/** - * Initializes a value memory object. - * A value memory object holds memory for value structures. Values within - * the memory are referenced using {@link NCDValRef} objects, which point - * to values within memory objects. - * - * Values may be added to a memory object using functions such as - * {@link NCDVal_NewString}, {@link NCDVal_NewList} and {@link NCDVal_NewMap}, - * and {@link NCDVal_NewCopy}, which return references to the new values within - * the memory object. - * - * It is not possible to remove values from the memory object, or modify existing - * values other than adding elements to pre-allocated slots in lists and maps. - * Once a value is added, it will consume memory as long as its memory object - * exists. This is by design - this code is intended and optimized for constructing - * and passing around values, not for operating on them in place. In fact, al - * values within a memory object are stored in a single memory buffer, as an - * embedded data structure with relativepointers. For example, map values use an - * embedded AVL tree. - */ -void NCDValMem_Init (NCDValMem *o); - -/** - * Frees a value memory object. - * All values within the memory object cease to exist, and any {@link NCDValRef} - * object pointing to them must no longer be used. - */ -void NCDValMem_Free (NCDValMem *o); - -/** - * Initializes the memory object to be a copy of an existing memory object. - * Value references from the original may be used if they are first turned - * to {@link NCDValSafeRef} using {@link NCDVal_ToSafe} and back to - * {@link NCDValRef} using {@link NCDVal_FromSafe} with the new memory object - * specified. Alternatively, {@link NCDVal_Moved} can be used. - * Returns 1 on success and 0 on failure. - */ -int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other) WARN_UNUSED; - -/** - * For each internal link (e.g. list element) to a ComposedString in the memory - * object, copies the ComposedString to some kind ContinuousString, and updates - * the link to point to the new ContinuousString. - * Additionally, if *\a root_val points to a ComposedString, copies it to a new - * ContinuousString and updates *\a root_val to point to it. - * \a root_val must be non-NULL and *\a root_val must not be an invalid value - * reference. - * Returns 1 on success and 0 on failure. On failure, some strings may have - * been converted, but the memory object is left in a consistent state. - */ -int NCDValMem_ConvertNonContinuousStrings (NCDValMem *o, NCDValRef *root_val) WARN_UNUSED; - -/** - * Does nothing. - * The value reference object must either point to a valid value within a valid - * memory object, or must be an invalid reference (most functions operating on - * {@link NCDValRef} implicitly require that). - */ -void NCDVal_Assert (NCDValRef val); - -/** - * Determines if a value reference is invalid. - */ -int NCDVal_IsInvalid (NCDValRef val); - -/** - * Determines if a value is a placeholder value. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsPlaceholder (NCDValRef val); - -/** - * Returns the type of the value reference, which must not be an invalid reference. - * Possible values are NCDVAL_STRING, NCDVAL_LIST, NCDVAL_MAP and NCDVAL_PLACEHOLDER. - * The placeholder type is only used internally in the interpreter for argument - * resolution, and is never seen by modules; see {@link NCDVal_NewPlaceholder}. - */ -int NCDVal_Type (NCDValRef val); - -/** - * Returns an invalid reference. - * An invalid reference must not be passed to any function here, except: - * {@link NCDVal_Assert}, {@link NCDVal_IsInvalid}, {@link NCDVal_ToSafe}, - * {@link NCDVal_FromSafe}, {@link NCDVal_Moved}. - */ -NCDValRef NCDVal_NewInvalid (void); - -/** - * Returns a new placeholder value reference. A placeholder value is a valid value - * containing an integer placeholder identifier. - * This always succeeds; however, the caller must ensure the identifier is - * non-negative and satisfies (NCDVAL_MINIDX + plid < -1). - * - * The placeholder type is only used internally in the interpreter for argument - * resolution, and is never seen by modules. Also see {@link NCDPlaceholderDb}. - */ -NCDValRef NCDVal_NewPlaceholder (NCDValMem *mem, int plid); - -/** - * Returns the indentifier of a placeholder value. - * The value reference must point to a placeholder value. - */ -int NCDVal_PlaceholderId (NCDValRef val); - -/** - * Copies a value into the specified memory object. The source - * must not be an invalid reference, however it may reside in any memory - * object (including 'mem'). - * Returns a reference to the copied value. On out of memory, returns - * an invalid reference. - */ -NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val); - -/** - * Compares two values, both of which must not be invalid references. - * Returns -1, 0 or 1. - */ -int NCDVal_Compare (NCDValRef val1, NCDValRef val2); - -/** - * Converts a value reference to a safe referece format, which remains valid - * if the memory object is moved (safe references do not contain a pointer - * to the memory object, unlike {@link NCDValRef} references). - */ -NCDValSafeRef NCDVal_ToSafe (NCDValRef val); - -/** - * Converts a safe value reference to a normal value reference. - * This should be used to recover references from safe references - * after the memory object is moved. - */ -NCDValRef NCDVal_FromSafe (NCDValMem *mem, NCDValSafeRef sval); - -/** - * Fixes a value reference after its memory object was moved. - */ -NCDValRef NCDVal_Moved (NCDValMem *mem, NCDValRef val); - -/** - * Determines if all strings within this value are ContinuousString's, - * by recusively walking the entire value. - * If all strings are ContinuousString's, returns 1; if there is at least - * one string which is not a ContinuousString, returns 0. - * The value reference must not be an invalid reference. - */ -int NCDVal_HasOnlyContinuousStrings (NCDValRef val); - -/** - * Determines if the value implements the String interface. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsString (NCDValRef val); - -/** - * Determines if the value implements the ContinuousString interface. - * A ContinuousString also implements the String interface. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsContinuousString (NCDValRef val); - -/** - * Determines if the value is a StoredString. - * A StoredString implements the ContinuousString interface. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsStoredString (NCDValRef val); - -/** - * Determines if the value is an IdString. See {@link NCDVal_NewIdString} - * for details. - * An IdString implements the ContinuousString interface. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsIdString (NCDValRef val); - -/** - * Determines if a value is an ExternalString. - * See {@link NCDVal_NewExternalString} for details. - * An ExternalString implements the ContinuousString interface. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsExternalString (NCDValRef val); - -/** - * Determines if a value is a ComposedString. - * A ComposedString implements the String interface. - */ -int NCDVal_IsComposedString (NCDValRef val); - -/** - * Determines if a value is a String which contains no null bytes. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsStringNoNulls (NCDValRef val); - -/** - * Equivalent to NCDVal_NewStringBin(mem, data, strlen(data)). - */ -NCDValRef NCDVal_NewString (NCDValMem *mem, const char *data); - -/** - * Builds a new StoredString. - * Returns a reference to the new value, or an invalid reference - * on out of memory. - * WARNING: The buffer passed must NOT be part of any value in the - * memory object specified. In particular, you may NOT use this - * function to copy a string that resides in the same memory object. - * - * A StoredString is a kind of ContinuousString which is represented directly in the - * value memory object. - */ -NCDValRef NCDVal_NewStringBin (NCDValMem *mem, const uint8_t *data, size_t len); - -/** - * Builds a new StoredString of the given length with undefined contents. - * You can define the contents of the string later by copying to the address - * returned by {@link NCDVal_StringData}. - */ -NCDValRef NCDVal_NewStringUninitialized (NCDValMem *mem, size_t len); - -/** - * Builds a new IdString. - * Returns a reference to the new value, or an invalid reference - * on out of memory. - * - * An IdString is a kind of ContinuousString which is represented efficiently as a string - * identifier via {@link NCDStringIndex}. - */ -NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id, - NCDStringIndex *string_index); - -/** - * Builds a new ExternalString, pointing to the given external data. A reference to - * the external data is taken using {@link BRefTarget}, unless 'ref_target' is - * NULL. The data must not change while this value exists. - * Returns a reference to the new value, or an invalid reference - * on out of memory. - * - * An ExternalString is a kind of ContinuousString where the actual string contents are - * stored outside of the value memory object. - */ -NCDValRef NCDVal_NewExternalString (NCDValMem *mem, const char *data, size_t len, - BRefTarget *ref_target); - -/** - * Callback function which is called for ComposedString's to access the underlying string resource. - * \a user is whatever was passed to 'resource.user' in {@link NCDVal_NewComposedString}. - * \a offset is the offset from the beginning of the string exposed by the resource; it will be - * >= 'offset' and < 'offset' + 'length' as given to NCDVal_NewComposedString. - * This callback must set *\a out_data and *\a out_length to represent a continuous (sub-)region - * of the string that starts at the byte at index \a offset. The pointed-to data must remain - * valid and unchanged until all references to the string resource are released. - * \a *out_data must be set to non-NULL and *\a out_length must be set to greater than zero, - * since the conditions above imply that there is at least one byte available from \a offset. - */ -typedef void (*NCDVal_ComposedString_func_getptr) (void *user, size_t offset, const char **out_data, size_t *out_length); - -/** - * Structure representing a string resource used by ComposedString's, - * to simplify {@link NCDVal_NewComposedString} and {@link NCDVal_ComposedStringResource}. - */ -typedef struct { - NCDVal_ComposedString_func_getptr func_getptr; - void *user; - BRefTarget *ref_target; -} NCDValComposedStringResource; - -/** - * Returns a cstring referencing a range within a {@link NCDValComposedStringResource}. - * \a offset and \a length specify the range within the resource which the returned - * cstring will reference. To reference the contents of a ComposedString, use: - * - resource = NCDVal_ComposedStringResource(composedstring), - * - offset = NCDVal_ComposedStringOffset(composedstring), - * - length = NCDVal_StringLength(composedstring). - * - * The returned cstring is valid as long as the resource is not released. Note that - * a reference to resource.ref_target may need to be taken to ensure the resource - * is not released while it is being referenced by the returned cstring (unless - * resource.ref_target is NULL). - */ -b_cstring NCDValComposedStringResource_Cstring (NCDValComposedStringResource resource, size_t offset, size_t length); - -/** - * Builds a new ComposedString from a string resource. - * A reference to the underlying string resource via the {@link BRefTarget} object - * specified in 'resource.ref_target'. - * - * A ComposedString is a kind of String with an abstract representation exposed via the - * {@link NCDVal_ComposedString_func_getptr} callback. - */ -NCDValRef NCDVal_NewComposedString (NCDValMem *mem, NCDValComposedStringResource resource, size_t offset, size_t length); - -/** - * Returns a pointer to the data of a ContinuousString. - * WARNING: the string data may not be null-terminated. To get a null-terminated - * version, use {@link NCDVal_StringNullTerminate}. - * The value reference must point to a ContinuousString. - */ -const char * NCDVal_StringData (NCDValRef contstring); - -/** - * Returns the length of a String. - * The value reference must point to a String. - */ -size_t NCDVal_StringLength (NCDValRef string); - -/** - * Returns a {@link b_cstring} interface to the given string value. - * The returned cstring is valid as long as the memory object exists. - * However, if the memory object is moved or copied, the cstring is - * invalid in the new or moved (respectively) memory object. - */ -b_cstring NCDVal_StringCstring (NCDValRef string); - -/** - * Produces a null-terminated continuous version of a String. On success, the result is - * stored into an {@link NCDValNullTermString} structure, and the null-terminated - * string is available via its 'data' member. This function may either simply pass - * through the data pointer (if the string is known to be continuous and null-terminated) or - * produce a null-terminated dynamically allocated copy. - * On success, {@link NCDValNullTermString_Free} should be called to release any allocated - * memory when the null-terminated string is no longer needed. This must be called before - * the memory object is freed, because it may point to data inside the memory object. - * It is guaranteed that *out is not modified on failure. - * Returns 1 on success and 0 on failure. - */ -int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out) WARN_UNUSED; - -/** - * Returns a dummy {@link NCDValNullTermString} which can be freed using - * {@link NCDValNullTermString_Free}, but need not be. - */ -NCDValNullTermString NCDValNullTermString_NewDummy (void); - -/** - * Releases any memory which was dynamically allocated by {@link NCDVal_StringNullTerminate} - * to null-terminate a string. - */ -void NCDValNullTermString_Free (NCDValNullTermString *o); - -/** - * Produces a continuous version of a String. On success, the result is stored into an - * {@link NCDValContString} structure, and the continuous string is available via its - * 'data' member. This function may either simply pass through the data pointer (if the - * string is known to be continuous) or produce a continuous dynamically allocated copy. - * On success, {@link NCDValContString_Free} should be called to release any allocated - * memory when the continuous string is no longer needed. This must be called before - * the memory object is freed, because it may point to data inside the memory object. - * It is guaranteed that *out is not modified on failure. - * Returns 1 on success and 0 on failure. - */ -int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out) WARN_UNUSED; - -/** - * Returns a dummy {@link NCDValContString} which can be freed using - * {@link NCDValContString_Free}, but need not be. - */ -NCDValContString NCDValContString_NewDummy (void); - -/** - * Releases any memory which was dynamically allocated by {@link NCDVal_StringContinuize} - * to continuize a string. - */ -void NCDValContString_Free (NCDValContString *o); - -/** - * Returns the string ID and the string index of an IdString. - * Both the \a out_string_id and \a out_string_index pointers must be non-NULL. - */ -void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id, - NCDStringIndex **out_string_index); - -/** - * Returns the string ID of an IdString. - */ -NCD_string_id_t NCDVal_IdStringId (NCDValRef idstring); - -/** - * Returns the string index of an IdString. - */ -NCDStringIndex * NCDVal_IdStringStringIndex (NCDValRef idstring); - -/** - * Returns the reference target of an ExternalString. This may be NULL - * if the external string is not associated with a reference target. - */ -BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring); - -/** - * Returns the underlying string resource of a ComposedString. - */ -NCDValComposedStringResource NCDVal_ComposedStringResource (NCDValRef composedstring); - -/** - * Returns the resource offset of a ComposedString. - */ -size_t NCDVal_ComposedStringOffset (NCDValRef composedstring); - -/** - * Determines if the String has any null bytes in its contents. - */ -int NCDVal_StringHasNulls (NCDValRef string); - -/** - * Determines if the String value is equal to the given null-terminated - * string. - * The value reference must point to a String value. - */ -int NCDVal_StringEquals (NCDValRef string, const char *data); - -/** - * Determines if the String is equal to the given string represented - * by an {@link NCDStringIndex} identifier. - * NOTE: \a string_index must be equal to the string_index of every ID-string - * that exist within this memory object. - */ -int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id, - NCDStringIndex *string_index); - -/** - * Compares two String's in a manner similar to memcmp(). - * The startN and length arguments must refer to a valid region within - * stringN, i.e. startN + length <= length_of_stringN must hold. - */ -int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, size_t start2, size_t length); - -/** - * Copies a part of a String to a buffer. - * \a start and \a length must refer to a valid region within the string, - * i.e. start + length <= length_of_string must hold. - */ -void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst); - -/** - * Determines if a part of a String is equal to the \a length bytes in \a data. - * \a start and \a length must refer to a valid region within the string, - * i.e. start + length <= length_of_string must hold. - */ -int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data); - -/** - * Determines if a value is a list value. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsList (NCDValRef val); - -/** - * Builds a new list value. The 'maxcount' argument specifies how - * many element slots to preallocate. Not more than that many - * elements may be appended to the list using {@link NCDVal_ListAppend}. - * Returns a reference to the new value, or an invalid reference - * on out of memory. - */ -NCDValRef NCDVal_NewList (NCDValMem *mem, size_t maxcount); - -/** - * Appends a value to to the list value. - * The 'list' reference must point to a list value, and the - * 'elem' reference must be non-invalid and point to a value within - * the same memory object as the list. - * Inserting a value into a list does not in any way change it; - * internally, the list only points to it. - * You must not modify the element after it has been inserted into the - * list. - * Returns 1 on success and 0 on failure (depth limit exceeded). - */ -int NCDVal_ListAppend (NCDValRef list, NCDValRef elem) WARN_UNUSED; - -/** - * Returns the number of elements in a list value, i.e. the number - * of times {@link NCDVal_ListAppend} was called. - * The 'list' reference must point to a list value. - */ -size_t NCDVal_ListCount (NCDValRef list); - -/** - * Returns the maximum number of elements a list value may contain, - * i.e. the 'maxcount' argument to {@link NCDVal_NewList}. - * The 'list' reference must point to a list value. - */ -size_t NCDVal_ListMaxCount (NCDValRef list); - -/** - * Returns a reference to the value at the given position 'pos' in a list, - * starting with zero. - * The 'list' reference must point to a list value. - * The position 'pos' must refer to an existing element, i.e. - * pos < NCDVal_ListCount(). - */ -NCDValRef NCDVal_ListGet (NCDValRef list, size_t pos); - -/** - * Returns references to elements within a list by writing them - * via (NCDValRef *) variable arguments. - * If 'num' == NCDVal_ListCount(), succeeds, returing 1 and writing 'num' - * references, as mentioned. - * If 'num' != NCDVal_ListCount(), fails, returning 0, without writing any - * references - */ -int NCDVal_ListRead (NCDValRef list, int num, ...); - -/** - * Like {@link NCDVal_ListRead}, but the list can contain more than 'num' - * elements. - */ -int NCDVal_ListReadHead (NCDValRef list, int num, ...); - -/** - * Determines if a value is a map value. - * The value reference must not be an invalid reference. - */ -int NCDVal_IsMap (NCDValRef val); - -/** - * Builds a new map value. The 'maxcount' argument specifies how - * many entry slots to preallocate. Not more than that many - * entries may be inserted to the map using {@link NCDVal_MapInsert}. - * Returns a reference to the new value, or an invalid reference - * on out of memory. - */ -NCDValRef NCDVal_NewMap (NCDValMem *mem, size_t maxcount); - -/** - * Inserts an entry to the map value. - * The 'map' reference must point to a map value, and the - * 'key' and 'val' references must be non-invalid and point to values within - * the same memory object as the map. - * Inserting an entry does not in any way change the 'key'and 'val'; - * internally, the map only points to it. - * You must not modify the key after inserting it into a map. This is because - * the map builds an embedded AVL tree of entries indexed by keys. - * If insertion fails due to a maximum depth limit, returns 0. - * Otherwise returns 1, and *out_inserted is set to 1 if the key did not - * yet exist and the entry was inserted, and to 0 if it did exist and the - * entry was not inserted. The 'out_inserted' pointer may be NULL, in which - * case *out_inserted is never set. - */ -int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inserted) WARN_UNUSED; - -/** - * Returns the number of entries in a map value, i.e. the number - * of times {@link NCDVal_MapInsert} was called successfully. - * The 'map' reference must point to a map value. - */ -size_t NCDVal_MapCount (NCDValRef map); - -/** - * Returns the maximum number of entries a map value may contain, - * i.e. the 'maxcount' argument to {@link NCDVal_NewMap}. - * The 'map' reference must point to a map value. - */ -size_t NCDVal_MapMaxCount (NCDValRef map); - -/** - * Determines if a map entry reference is invalid. This is used in combination - * with the map iteration functions to detect the end of iteration. - */ -int NCDVal_MapElemInvalid (NCDValMapElem me); - -/** - * Returns a reference to the first entry in a map, with respect to some - * arbitrary order. - * If the map is empty, returns an invalid map entry reference. - */ -NCDValMapElem NCDVal_MapFirst (NCDValRef map); - -/** - * Returns a reference to the entry in a map that follows the entry referenced - * by 'me', with respect to some arbitrary order. - * The 'me' argument must be a non-invalid reference to an entry in the map. - * If 'me' is the last entry, returns an invalid map entry reference. - */ -NCDValMapElem NCDVal_MapNext (NCDValRef map, NCDValMapElem me); - -/** - * Like {@link NCDVal_MapFirst}, but with respect to the order defined by - * {@link NCDVal_Compare}. - * Ordered iteration is slower and should only be used when needed. - */ -NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map); - -/** - * Like {@link NCDVal_MapNext}, but with respect to the order defined by - * {@link NCDVal_Compare}. - * Ordered iteration is slower and should only be used when needed. - */ -NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me); - -/** - * Returns a reference to the key of the map entry referenced by 'me'. - * The 'me' argument must be a non-invalid reference to an entry in the map. - */ -NCDValRef NCDVal_MapElemKey (NCDValRef map, NCDValMapElem me); - -/** - * Returns a reference to the value of the map entry referenced by 'me'. - * The 'me' argument must be a non-invalid reference to an entry in the map. - */ -NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me); - -/** - * Looks for a key in the map. The 'key' reference must be a non-invalid - * value reference, and may point to a value in a different memory object - * than the map. - * If the key exists in the map, returns a reference to the corresponding - * map entry. - * If the key does not exist, returns an invalid map entry reference. - */ -NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key); - -/** - * Retrieves the value reference to the value of the map entry whose key is a - * string value equal to the given null-terminated string. If there is no such - * entry, returns an invalid value reference. - */ -NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str); - -/** - * Builds a placeholder replacement program, which is a list of instructions for - * efficiently replacing placeholders in identical values in identical memory - * objects. - * To actually perform replacements, make copies of the memory object of this value - * using {@link NCDValMem_InitCopy}, then call {@link NCDValReplaceProg_Execute} - * on the copies. - * The value passed must be a valid value, and not a placeholder. - * Returns 1 on success, 0 on failure. - */ -int NCDValReplaceProg_Init (NCDValReplaceProg *o, NCDValRef val); - -/** - * Frees the placeholder replacement program. - */ -void NCDValReplaceProg_Free (NCDValReplaceProg *o); - -/** - * Callback used by {@link NCDValReplaceProg_Execute} to allow the caller to produce - * values of placeholders. - * This function should build a new value within the memory object 'mem' (which is - * the same as of the memory object where placeholders are being replaced). - * On success, it should return 1, writing a valid value reference to *out. - * On failure, it can either return 0, or return 1 but write an invalid value reference. - * This callback must not access the memory object in any other way than building - * new values in it; it must not modify any values that were already present at the - * point it was called. - */ -typedef int (*NCDVal_replace_func) (void *arg, int plid, NCDValMem *mem, NCDValRef *out); - -/** - * Executes the replacement program, replacing placeholders in a value. - * The memory object must given be identical to the memory object which was used in - * {@link NCDValReplaceProg_Init}; see {@link NCDValMem_InitCopy}. - * This will call the callback 'replace', which should build the values to replace - * the placeholders. - * Returns 1 on success and 0 on failure. On failure, the entire memory object enters - * and inconsistent state and must be freed using {@link NCDValMem_Free} before - * performing any other operation on it. - * The program is passed by value instead of pointer because this appears to be faster. - * Is is not modified in any way. - */ -int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_replace_func replace, void *arg); - -#endif diff --git a/external/badvpn_dns/ncd/NCDValCons.c b/external/badvpn_dns/ncd/NCDValCons.c deleted file mode 100644 index 9872a47..0000000 --- a/external/badvpn_dns/ncd/NCDValCons.c +++ /dev/null @@ -1,283 +0,0 @@ -/** - * @file NCDValCons.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/balloc.h> - -#include "NCDValCons.h" - -#define GROWARRAY_NAME NCDValCons__Array -#define GROWARRAY_OBJECT_TYPE NCDValCons -#define GROWARRAY_ARRAY_MEMBER elems -#define GROWARRAY_CAPACITY_MEMBER elems_capacity -#define GROWARRAY_MAX_CAPACITY INT_MAX -#include <misc/grow_array.h> - -static int alloc_elem (NCDValCons *o) -{ - ASSERT(o->elems_size >= 0) - ASSERT(o->elems_size <= o->elems_capacity) - - if (o->elems_size == o->elems_capacity && !NCDValCons__Array_DoubleUp(o)) { - return -1; - } - - return o->elems_size++; -} - -static void assert_cons_val (NCDValCons *o, NCDValConsVal val) -{ -#ifndef NDEBUG - switch (val.cons_type) { - case NCDVALCONS_TYPE_COMPLETE: { - ASSERT(!NCDVal_IsInvalid(NCDVal_FromSafe(o->mem, val.u.complete_ref))) - } break; - case NCDVALCONS_TYPE_INCOMPLETE_LIST: - case NCDVALCONS_TYPE_INCOMPLETE_MAP: { - ASSERT(val.u.incomplete.elems_idx >= -1) - ASSERT(val.u.incomplete.elems_idx < o->elems_size) - ASSERT(val.u.incomplete.count >= 0) - } break; - default: - ASSERT(0); - } -#endif -} - -static int complete_value (NCDValCons *o, NCDValConsVal val, NCDValSafeRef *out, int *out_error) -{ - assert_cons_val(o, val); - ASSERT(out) - ASSERT(out_error) - - switch (val.cons_type) { - case NCDVALCONS_TYPE_COMPLETE: { - *out = val.u.complete_ref; - } break; - - case NCDVALCONS_TYPE_INCOMPLETE_LIST: { - NCDValRef list = NCDVal_NewList(o->mem, val.u.incomplete.count); - if (NCDVal_IsInvalid(list)) { - goto fail_memory; - } - - int elemidx = val.u.incomplete.elems_idx; - - while (elemidx != -1) { - ASSERT(elemidx >= 0) - ASSERT(elemidx < o->elems_size) - - NCDValRef elem = NCDVal_FromSafe(o->mem, o->elems[elemidx].ref); - - if (!NCDVal_ListAppend(list, elem)) { - *out_error = NCDVALCONS_ERROR_DEPTH; - return 0; - } - - elemidx = o->elems[elemidx].next; - } - - *out = NCDVal_ToSafe(list); - } break; - - case NCDVALCONS_TYPE_INCOMPLETE_MAP: { - NCDValRef map = NCDVal_NewMap(o->mem, val.u.incomplete.count); - if (NCDVal_IsInvalid(map)) { - goto fail_memory; - } - - int keyidx = val.u.incomplete.elems_idx; - - while (keyidx != -1) { - ASSERT(keyidx >= 0) - ASSERT(keyidx < o->elems_size) - - int validx = o->elems[keyidx].next; - ASSERT(validx >= 0) - ASSERT(validx < o->elems_size) - - NCDValRef key = NCDVal_FromSafe(o->mem, o->elems[keyidx].ref); - NCDValRef value = NCDVal_FromSafe(o->mem, o->elems[validx].ref); - - int inserted; - if (!NCDVal_MapInsert(map, key, value, &inserted)) { - *out_error = NCDVALCONS_ERROR_DEPTH; - return 0; - } - if (!inserted) { - *out_error = NCDVALCONS_ERROR_DUPLICATE_KEY; - return 0; - } - - keyidx = o->elems[validx].next; - } - - *out = NCDVal_ToSafe(map); - } break; - - default: - ASSERT(0); - } - - return 1; - -fail_memory: - *out_error = NCDVALCONS_ERROR_MEMORY; - return 0; -} - -int NCDValCons_Init (NCDValCons *o, NCDValMem *mem) -{ - ASSERT(mem) - - o->mem = mem; - o->elems_size = 0; - - if (!NCDValCons__Array_Init(o, 1)) { - return 0; - } - - return 1; -} - -void NCDValCons_Free (NCDValCons *o) -{ - NCDValCons__Array_Free(o); -} - -int NCDValCons_NewString (NCDValCons *o, const uint8_t *data, size_t len, NCDValConsVal *out, int *out_error) -{ - ASSERT(out) - ASSERT(out_error) - - NCDValRef ref = NCDVal_NewStringBin(o->mem, data, len); - if (NCDVal_IsInvalid(ref)) { - *out_error = NCDVALCONS_ERROR_MEMORY; - return 0; - } - - out->cons_type = NCDVALCONS_TYPE_COMPLETE; - out->u.complete_ref = NCDVal_ToSafe(ref); - - return 1; -} - -void NCDValCons_NewList (NCDValCons *o, NCDValConsVal *out) -{ - ASSERT(out) - - out->cons_type = NCDVALCONS_TYPE_INCOMPLETE_LIST; - out->u.incomplete.elems_idx = -1; - out->u.incomplete.count = 0; -} - -void NCDValCons_NewMap (NCDValCons *o, NCDValConsVal *out) -{ - ASSERT(out) - - out->cons_type = NCDVALCONS_TYPE_INCOMPLETE_MAP; - out->u.incomplete.elems_idx = -1; - out->u.incomplete.count = 0; -} - -int NCDValCons_ListPrepend (NCDValCons *o, NCDValConsVal *list, NCDValConsVal elem, int *out_error) -{ - assert_cons_val(o, *list); - ASSERT(list->cons_type == NCDVALCONS_TYPE_INCOMPLETE_LIST) - assert_cons_val(o, elem); - ASSERT(out_error) - - int elemidx = alloc_elem(o); - if (elemidx < 0) { - *out_error = NCDVALCONS_ERROR_MEMORY; - return 0; - } - - o->elems[elemidx].next = list->u.incomplete.elems_idx; - - if (!complete_value(o, elem, &o->elems[elemidx].ref, out_error)) { - return 0; - } - - list->u.incomplete.elems_idx = elemidx; - list->u.incomplete.count++; - - return 1; -} - -int NCDValCons_MapInsert (NCDValCons *o, NCDValConsVal *map, NCDValConsVal key, NCDValConsVal value, int *out_error) -{ - assert_cons_val(o, *map); - ASSERT(map->cons_type == NCDVALCONS_TYPE_INCOMPLETE_MAP) - assert_cons_val(o, key); - assert_cons_val(o, value); - ASSERT(out_error) - - int validx = alloc_elem(o); - if (validx < 0) { - *out_error = NCDVALCONS_ERROR_MEMORY; - return 0; - } - - int keyidx = alloc_elem(o); - if (keyidx < 0) { - *out_error = NCDVALCONS_ERROR_MEMORY; - return 0; - } - - o->elems[validx].next = map->u.incomplete.elems_idx; - o->elems[keyidx].next = validx; - - if (!complete_value(o, value, &o->elems[validx].ref, out_error)) { - return 0; - } - - if (!complete_value(o, key, &o->elems[keyidx].ref, out_error)) { - return 0; - } - - map->u.incomplete.elems_idx = keyidx; - map->u.incomplete.count++; - - return 1; -} - -int NCDValCons_Complete (NCDValCons *o, NCDValConsVal val, NCDValRef *out, int *out_error) -{ - assert_cons_val(o, val); - ASSERT(out) - ASSERT(out_error) - - NCDValSafeRef sref; - if (!complete_value(o, val, &sref, out_error)) { - return 0; - } - - *out = NCDVal_FromSafe(o->mem, sref); - return 1; -} diff --git a/external/badvpn_dns/ncd/NCDValCons.h b/external/badvpn_dns/ncd/NCDValCons.h deleted file mode 100644 index 3b25d66..0000000 --- a/external/badvpn_dns/ncd/NCDValCons.h +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file NCDValCons.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDVALCONS_H -#define BADVPN_NCDVALCONS_H - -#include <limits.h> -#include <stdint.h> - -#include <misc/debug.h> -#include <ncd/NCDVal.h> - -struct NCDValCons__temp_elem { - NCDValSafeRef ref; - int next; -}; - -/** - * Value constructor; implements a mechanism for efficiently constructing - * NCD values into {@link NCDVal} compact representation, but without - * having to know the number of list or map elements in advance. - * For the purpose of value construction, values are representing using - * {@link NCDValConsVal} objects. - */ -typedef struct { - NCDValMem *mem; - struct NCDValCons__temp_elem *elems; - int elems_size; - int elems_capacity; -} NCDValCons; - -#define NCDVALCONS_TYPE_COMPLETE 1 -#define NCDVALCONS_TYPE_INCOMPLETE_LIST 2 -#define NCDVALCONS_TYPE_INCOMPLETE_MAP 3 - -/** - * Abstract handle which represents a value during constuction via - * {@link NCDValCons}. - */ -typedef struct { - int cons_type; - union { - NCDValSafeRef complete_ref; - struct { - int elems_idx; - int count; - } incomplete; - } u; -} NCDValConsVal; - -#define NCDVALCONS_ERROR_MEMORY 1 -#define NCDVALCONS_ERROR_DUPLICATE_KEY 2 -#define NCDVALCONS_ERROR_DEPTH 3 - -/** - * Initializes a value constructor. - * - * @param o value constructor to initialize - * @param mem memory object where values will be stored into - * @return 1 on success, 0 on failure - */ -int NCDValCons_Init (NCDValCons *o, NCDValMem *mem) WARN_UNUSED; - -/** - * Frees the value constructor. This only means the constuctor does - * not exist any more; any values constructed and completed using - * {@link NCDValCons_Complete} remain in the memory object. - * - * @param o value constructor to free - */ -void NCDValCons_Free (NCDValCons *o); - -/** - * Creates a new string value with the given data. - * - * @param o value constructor - * @param data pointer to string data. This must not point into the - * memory object the value constructor is using. The data - * is copied. - * @param len length of the string - * @param out on success, *out will be set to a handle representing - * the new string - * @param out_error on failure, *out_error will be set to an error code - * @return 1 on success, 0 on failure - */ -int NCDValCons_NewString (NCDValCons *o, const uint8_t *data, size_t len, NCDValConsVal *out, int *out_error) WARN_UNUSED; - -/** - * Creates an empty list value. - * - * @param o value constructor - * @param out *out will be set to a handle representing the new list - */ -void NCDValCons_NewList (NCDValCons *o, NCDValConsVal *out); - -/** - * Creates an empty map value. - * - * @param o value constructor - * @param out *out will be set to a handle representing the new map - */ -void NCDValCons_NewMap (NCDValCons *o, NCDValConsVal *out); - -/** - * Prepends an element to a list value. - * - * @param o value constructor - * @param list pointer to the handle representing the list. On success, - * the handle will be modified, and the old handle must not - * be used any more. - * @param elem handle representing the value to be prepended. This handle - * must not be used any more after being prepended to the list. - * @param out_error on failure, *out_error will be set to an error code - * @return 1 on success, 0 on failure - */ -int NCDValCons_ListPrepend (NCDValCons *o, NCDValConsVal *list, NCDValConsVal elem, int *out_error) WARN_UNUSED; - -/** - * Inserts an entry into a map value. - * - * @param o value constructor - * @param map pointer to the handle representing the map. On success, - * the handle will be modified, and the old handle must not - * be used any more. - * @param key handle representing the key of the entry. This handle - * must not be used any more after being inserted into the map. - * @param value handle representing the value of the entry. This handle - * must not be used any more after being inserted into the - * map. - * @param out_error on failure, *out_error will be set to an error code - * @return 1 on success, 0 on failure - */ -int NCDValCons_MapInsert (NCDValCons *o, NCDValConsVal *map, NCDValConsVal key, NCDValConsVal value, int *out_error) WARN_UNUSED; - -/** - * Completes a value represented by a {@link NCDValConsVal} handle, - * producing a {@link NCDValRef} object which refers to this value within - * the memory object. - * - * @param o value constructor - * @param val handle representing the value to be completed. After a value - * is completed, the handle must not be used any more. - * @param out on success, *out will be set to a {@link NCDValRef} object - * referencing the completed value - * @param out_error on failure, *out_error will be set to an error code - * @return 1 on success, 0 on failure - */ -int NCDValCons_Complete (NCDValCons *o, NCDValConsVal val, NCDValRef *out, int *out_error) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDValGenerator.c b/external/badvpn_dns/ncd/NCDValGenerator.c deleted file mode 100644 index 3355f8b..0000000 --- a/external/badvpn_dns/ncd/NCDValGenerator.c +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @file NCDValGenerator.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include <misc/debug.h> -#include <misc/expstring.h> -#include <base/BLog.h> - -#include "NCDValGenerator.h" - -#include <generated/blog_channel_NCDValGenerator.h> - -static int generate_val (NCDValRef value, ExpString *out_str) -{ - ASSERT(!NCDVal_IsInvalid(value)) - - switch (NCDVal_Type(value)) { - case NCDVAL_STRING: { - b_cstring cstr = NCDVal_StringCstring(value); - - if (!ExpString_AppendChar(out_str, '"')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - - B_CSTRING_LOOP_CHARS(cstr, char_pos, ch, { - if (ch == '\0') { - char buf[5]; - snprintf(buf, sizeof(buf), "\x%02"PRIx8, (uint8_t)ch); - - if (!ExpString_Append(out_str, buf)) { - BLog(BLOG_ERROR, "ExpString_Append failed"); - goto fail; - } - - goto next_char; - } - - if (ch == '"' || ch == '\') { - if (!ExpString_AppendChar(out_str, '\')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, ch)) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - next_char:; - }) - - if (!ExpString_AppendChar(out_str, '"')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - } break; - - case NCDVAL_LIST: { - size_t count = NCDVal_ListCount(value); - - if (!ExpString_AppendChar(out_str, '{')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - - for (size_t i = 0; i < count; i++) { - if (i > 0) { - if (!ExpString_Append(out_str, ", ")) { - BLog(BLOG_ERROR, "ExpString_Append failed"); - goto fail; - } - } - - if (!generate_val(NCDVal_ListGet(value, i), out_str)) { - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, '}')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - } break; - - case NCDVAL_MAP: { - if (!ExpString_AppendChar(out_str, '[')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - - int is_first = 1; - - for (NCDValMapElem e = NCDVal_MapOrderedFirst(value); !NCDVal_MapElemInvalid(e); e = NCDVal_MapOrderedNext(value, e)) { - NCDValRef ekey = NCDVal_MapElemKey(value, e); - NCDValRef eval = NCDVal_MapElemVal(value, e); - - if (!is_first) { - if (!ExpString_Append(out_str, ", ")) { - BLog(BLOG_ERROR, "ExpString_Append failed"); - goto fail; - } - } - - if (!generate_val(ekey, out_str)) { - goto fail; - } - - if (!ExpString_AppendChar(out_str, ':')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - - if (!generate_val(eval, out_str)) { - goto fail; - } - - is_first = 0; - } - - if (!ExpString_AppendChar(out_str, ']')) { - BLog(BLOG_ERROR, "ExpString_AppendChar failed"); - goto fail; - } - } break; - - default: ASSERT(0); - } - - return 1; - -fail: - return 0; -} - -char * NCDValGenerator_Generate (NCDValRef value) -{ - ASSERT(!NCDVal_IsInvalid(value)) - - ExpString str; - if (!ExpString_Init(&str)) { - BLog(BLOG_ERROR, "ExpString_Init failed"); - goto fail0; - } - - if (!generate_val(value, &str)) { - goto fail1; - } - - return ExpString_Get(&str); - -fail1: - ExpString_Free(&str); -fail0: - return NULL; -} - -int NCDValGenerator_AppendGenerate (NCDValRef value, ExpString *str) -{ - ASSERT(!NCDVal_IsInvalid(value)) - ASSERT(str) - - return generate_val(value, str); -} diff --git a/external/badvpn_dns/ncd/NCDValGenerator.h b/external/badvpn_dns/ncd/NCDValGenerator.h deleted file mode 100644 index 35fd991..0000000 --- a/external/badvpn_dns/ncd/NCDValGenerator.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file NCDValGenerator.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDVALUEGENERATOR_H -#define BADVPN_NCDVALUEGENERATOR_H - -#include <misc/debug.h> -#include <misc/expstring.h> -#include <ncd/NCDVal.h> - -char * NCDValGenerator_Generate (NCDValRef value); -int NCDValGenerator_AppendGenerate (NCDValRef value, ExpString *str) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDValParser.c b/external/badvpn_dns/ncd/NCDValParser.c deleted file mode 100644 index 7cdb4da..0000000 --- a/external/badvpn_dns/ncd/NCDValParser.c +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file NCDValParser.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <base/BLog.h> -#include <ncd/NCDConfigTokenizer.h> -#include <ncd/NCDValCons.h> - -#include "NCDValParser.h" - -#include <generated/blog_channel_NCDValParser.h> - -struct token { - char *str; - size_t len; -}; - -struct value { - int have; - NCDValConsVal v; -}; - -#define ERROR_FLAG_MEMORY (1 << 0) -#define ERROR_FLAG_TOKENIZATION (1 << 1) -#define ERROR_FLAG_SYNTAX (1 << 2) -#define ERROR_FLAG_DUPLICATE_KEY (1 << 3) -#define ERROR_FLAG_DEPTH (1 << 4) - -struct parser_state { - NCDValCons cons; - NCDValRef value; - int cons_error; - int error_flags; - void *parser; -}; - -static void free_token (struct token o) -{ - if (o.str) { - free(o.str); - } -}; - -static void handle_cons_error (struct parser_state *state) -{ - switch (state->cons_error) { - case NCDVALCONS_ERROR_MEMORY: - state->error_flags |= ERROR_FLAG_MEMORY; - break; - case NCDVALCONS_ERROR_DUPLICATE_KEY: - state->error_flags |= ERROR_FLAG_DUPLICATE_KEY; - break; - case NCDVALCONS_ERROR_DEPTH: - state->error_flags |= ERROR_FLAG_DEPTH; - break; - default: - ASSERT(0); - } -} - -// rename non-static functions defined by our Lemon parser -// to avoid clashes with other Lemon parsers -#define ParseTrace ParseTrace_NCDValParser -#define ParseAlloc ParseAlloc_NCDValParser -#define ParseFree ParseFree_NCDValParser -#define Parse Parse_NCDValParser - -// include the generated Lemon parser -#include "../generated/NCDValParser_parse.c" -#include "../generated/NCDValParser_parse.h" - -static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char) -{ - struct parser_state *state = user; - ASSERT(!state->error_flags) - - if (token == NCD_ERROR) { - state->error_flags |= ERROR_FLAG_TOKENIZATION; - goto fail; - } - - struct token minor; - minor.str = value; - minor.len = value_len; - - switch (token) { - case NCD_EOF: { - Parse(state->parser, 0, minor, state); - } break; - - case NCD_TOKEN_CURLY_OPEN: { - Parse(state->parser, CURLY_OPEN, minor, state); - } break; - - case NCD_TOKEN_CURLY_CLOSE: { - Parse(state->parser, CURLY_CLOSE, minor, state); - } break; - - case NCD_TOKEN_COMMA: { - Parse(state->parser, COMMA, minor, state); - } break; - - case NCD_TOKEN_STRING: { - Parse(state->parser, STRING, minor, state); - } break; - - case NCD_TOKEN_COLON: { - Parse(state->parser, COLON, minor, state); - } break; - - case NCD_TOKEN_BRACKET_OPEN: { - Parse(state->parser, BRACKET_OPEN, minor, state); - } break; - - case NCD_TOKEN_BRACKET_CLOSE: { - Parse(state->parser, BRACKET_CLOSE, minor, state); - } break; - - default: - state->error_flags |= ERROR_FLAG_TOKENIZATION; - free_token(minor); - goto fail; - } - - if (state->error_flags) { - goto fail; - } - - return 1; - -fail: - ASSERT(state->error_flags) - - if ((state->error_flags & ERROR_FLAG_MEMORY)) { - BLog(BLOG_ERROR, "line %zu, character %zu: memory allocation error", line, line_char); - } - - if ((state->error_flags & ERROR_FLAG_TOKENIZATION)) { - BLog(BLOG_ERROR, "line %zu, character %zu: tokenization error", line, line_char); - } - - if ((state->error_flags & ERROR_FLAG_SYNTAX)) { - BLog(BLOG_ERROR, "line %zu, character %zu: syntax error", line, line_char); - } - - if ((state->error_flags & ERROR_FLAG_DUPLICATE_KEY)) { - BLog(BLOG_ERROR, "line %zu, character %zu: duplicate key in map error", line, line_char); - } - - if ((state->error_flags & ERROR_FLAG_DEPTH)) { - BLog(BLOG_ERROR, "line %zu, character %zu: depth limit exceeded", line, line_char); - } - - return 0; -} - -int NCDValParser_Parse (const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out_value) -{ - ASSERT(str_len == 0 || str) - ASSERT(mem) - ASSERT(out_value) - - int ret = 0; - - struct parser_state state; - state.value = NCDVal_NewInvalid(); - state.error_flags = 0; - - if (!NCDValCons_Init(&state.cons, mem)) { - BLog(BLOG_ERROR, "NCDValCons_Init failed"); - goto fail0; - } - - if (!(state.parser = ParseAlloc(malloc))) { - BLog(BLOG_ERROR, "ParseAlloc failed"); - goto fail1; - } - - NCDConfigTokenizer_Tokenize((char *)str, str_len, tokenizer_output, &state); - - ParseFree(state.parser, free); - - if (state.error_flags) { - goto fail1; - } - - ASSERT(!NCDVal_IsInvalid(state.value)) - - *out_value = state.value; - ret = 1; - -fail1: - NCDValCons_Free(&state.cons); -fail0: - return ret; -} diff --git a/external/badvpn_dns/ncd/NCDValParser.h b/external/badvpn_dns/ncd/NCDValParser.h deleted file mode 100644 index 57d37b0..0000000 --- a/external/badvpn_dns/ncd/NCDValParser.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file NCDValParser.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDVALUEPARSER_H -#define BADVPN_NCDVALUEPARSER_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <ncd/NCDVal.h> - -/** - * Parses an NCD value string into {@link NCDVal} compact representation. - * - * @param str pointer to the string to be parsed - * @param str_len length of the string in bytes - * @param mem value memory object which the result will be stored in - * @param out_value on success, the value reference of the result will be - * written here - * @return 1 on success, 0 on failure - */ -int NCDValParser_Parse (const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out_value) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/ncd/NCDValParser_parse.y b/external/badvpn_dns/ncd/NCDValParser_parse.y deleted file mode 100644 index ced123d..0000000 --- a/external/badvpn_dns/ncd/NCDValParser_parse.y +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file NCDConfigParser_parse.y - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// argument for passing state to parser hooks -%extra_argument { struct parser_state *parser_out } - -// type of structure representing tokens -%token_type { struct token } - -// token destructor frees extra memory allocated for tokens -%token_destructor { free_token($$); } - -// types of nonterminals -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type value { struct value } - -// mention parser_out in some destructor to and avoid unused variable warning -%destructor list_contents { (void)parser_out; } - -// try to dynamically grow the parse stack -%stack_size 0 - -// on syntax error, set the corresponding error flag -%syntax_error { - parser_out->error_flags |= ERROR_FLAG_SYNTAX; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= value(A). { - if (!A.have) { - goto failZ0; - } - - if (!NCDVal_IsInvalid(parser_out->value)) { - // should never happen - parser_out->error_flags |= ERROR_FLAG_SYNTAX; - goto failZ0; - } - - if (!NCDValCons_Complete(&parser_out->cons, A.v, &parser_out->value, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failZ0; - } - -failZ0:; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValCons_NewList(&parser_out->cons, &R.v); - - if (!NCDValCons_ListPrepend(&parser_out->cons, &R.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failL0; - } - - R.have = 1; - goto doneL; - -failL0: - R.have = 0; -doneL:; -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValCons_ListPrepend(&parser_out->cons, &N.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failM0; - } - - R.have = 1; - R.v = N.v; - goto doneM; - -failM0: - R.have = 0; -doneM:; -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - NCDValCons_NewList(&parser_out->cons, &R.v); - R.have = 1; -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValCons_NewMap(&parser_out->cons, &R.v); - - if (!NCDValCons_MapInsert(&parser_out->cons, &R.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failS0; - } - - R.have = 1; - goto doneS; - -failS0: - R.have = 0; -doneS:; -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValCons_MapInsert(&parser_out->cons, &N.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failT0; - } - - R.have = 1; - R.v = N.v; - goto doneT; - -failT0: - R.have = 0; -doneT:; -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - NCDValCons_NewMap(&parser_out->cons, &R.v); - R.have = 1; -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)A.str, A.len, &R.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; -doneU:; - free_token(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} diff --git a/external/badvpn_dns/ncd/NCDVal_maptree.h b/external/badvpn_dns/ncd/NCDVal_maptree.h deleted file mode 100644 index d5b9c0c..0000000 --- a/external/badvpn_dns/ncd/NCDVal_maptree.h +++ /dev/null @@ -1,15 +0,0 @@ -#define CAVL_PARAM_NAME NCDVal__MapTree -#define CAVL_PARAM_FEATURE_COUNTS 0 -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0 -#define CAVL_PARAM_FEATURE_NOKEYS 0 -#define CAVL_PARAM_TYPE_ENTRY NCDVal__maptree_entry -#define CAVL_PARAM_TYPE_LINK NCDVal__idx -#define CAVL_PARAM_TYPE_KEY NCDValRef -#define CAVL_PARAM_TYPE_ARG NCDVal__maptree_arg -#define CAVL_PARAM_VALUE_NULL ((NCDVal__idx)-1) -#define CAVL_PARAM_FUN_DEREF(arg, link) ((struct NCDVal__mapelem *)NCDValMem__BufAt((arg), (link))) -#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, node1, node2) NCDVal_Compare(NCDVal__Ref((arg), (node1).ptr->key_idx), NCDVal__Ref((arg), (node2).ptr->key_idx)) -#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, node2) NCDVal_Compare((key1), NCDVal__Ref((arg), (node2).ptr->key_idx)) -#define CAVL_PARAM_MEMBER_CHILD tree_child -#define CAVL_PARAM_MEMBER_BALANCE tree_balance -#define CAVL_PARAM_MEMBER_PARENT tree_parent diff --git a/external/badvpn_dns/ncd/README b/external/badvpn_dns/ncd/README deleted file mode 100644 index 05d638f..0000000 --- a/external/badvpn_dns/ncd/README +++ /dev/null @@ -1,386 +0,0 @@ -# This file contains some examples of using NCD, the Network Configuration Daemon. -# -# A short introduction to NCD follows. -# -# NCD is a general-purpose system configuration system, operated with a unique programming language. -# The configuration consists of one or more so-called processes that can be considered executing in -# parallel. Further, each process consists of one or more statements, representing the individual -# actions. Statements are implemented as modules built into NCD. -# -# Inside a process, statements can be considered "executed" one after another. That is, when NCD -# starts up, it initializes the first statement, putting it in the DOWN state. When the statement -# reports having transitioned into the UP state, it initializes the next statement in the DOWN state, -# and so on. -# -# However, execution can go in the other direction too. A statement in the UP state can, at any time, -# report having transitioned into the DOWN state. At this point, any statements after that one will -# automatically be de-initialized. The de-initiazation is done from the bottom up. First the last -# initialized statement after the problematic statement is requested to terminate and enters the -# DYING state. After it terminates, its preceding statement enters the DYING state, and so on, until -# all statements following the problematic statement have been de-initiazed. -# -# The backward-execution is the key feature of NCD, and is particularly well suited for programming -# system configurations. Read on to see why. -# -# Statements in NCD can be divided into two categories: -# - Statements that configure something. These statements transition into the UP state "immediately". -# On de-initialization, such statements perform the reverse operation of what they did when initialized. -# Imaginary example: a statement that turn a light on intialization, and turns if off on de-initialization. -# - Statements that wait for something. These statements may remain in the DOWN state indefinitely. -# They enter the UP state when the waited-for condition is satisfied, and also go back into the DOWN -# state when it is no longer satisfied. -# Imaginary example: a statement that is UP when a switch is turned on, and DOWN when it is turned off. -# -# Using the two example statements, we can constuct a process that controls the light based on the switch: -# (these are not really implemented in NCD :) -# -# process light { -# wait_switch(); -# turn_light(); -# } -# -# When the switch is turned on, wait_switch() will transition to UP, initializing turn_light(), turning the -# light on. When the switch is turned off, wait_switch() will transition to DOWN, causing the de-initialization -# of turn_light(), turning the light off. -# We can add another turn_light() at the end to make the switch control two lights. -# -# A more complex example: We have a christmas three with lights on it. There are multiple "regular" lights, -# controlled with switches, and a special "top" light. The regular lights take a long time to turn on, and -# each takes a different, unpredictable time. We want the top light to be turned on if and only if all the regular -# lights are completely on. -# -# This problem can easily be solved using dependencies. NCD has built-in support for dependencies, provided -# in the form of provide() and depend() statements. A depend() statement is DOWN when its corresponding -# provide() statement is not initialized, and UP when it is. When a provide() is requested to de-initialize, it -# transitions the depend() statements back into the DOWN state, and, before actually dying, waits for any -# statements following them to de-initialize. -# -# The christmas three problem can then be programmed as follows: -# -# process light1 { -# wait_switch1(); -# turn_light1(); -# provide("L1"); -# } -# -# process light2 { -# wait_switch2(); -# turn_light2(); -# provide("L2"); -# } -# -# process top_light { -# depend("L1"); -# depend("L2"); -# turn_top_light(); -# } -# -# Follow some real examples of network configuration using NCD. -# For a list of implemented statements and their descriptions, take a look at the BadVPN source code, in -# the ncd/modules/ folder. -# - -# -# Network card using DHCP. -# - -process lan { - # Make the interface name a variable so we can refer to it. - # The NCD language has no notion of assigning a variable. Instead variables are - # provided by statements preceding the statement where they are used. - # The built-in var() statement can be used to make an alias. - var("eth0") dev; - - # Wait for the network card to appear, set it up and wait for the cable to be - # plugged it. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Start DHCP. - net.ipv4.dhcp(dev) dhcp; - - # DHCP has obtained an address. - # Because net.ipv4.dhcp does no checks of the IP address, as a safety measure, do not proceed - # if the address is local. - ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local; - ifnot(test_local); - - # Assign the obtained address to the interface. - net.ipv4.addr(dev, dhcp.addr, dhcp.prefix); - - # Add a default route. - # <dest> <dest_prefix> <gateway/"none"> <metric> <device> - net.ipv4.route("0.0.0.0", "0", dhcp.gateway, "20", dev); - - # Add DNS servers, as provided by DHCP. - # "20" is the priority of the servers. When applying DNS servers, NCD collects the servers - # from all active net.dns() statements, sorts them by priority ascending (stable), and writes - # them to /etc/resolv.conf, overwriting anything that was previously there. - net.dns(dhcp.dns_servers, "20"); -} - -# -# Network card with static configuration. -# - -process lan2 { - # Make the interface name a variable so we can refer to it. - var("eth1") dev; - - # Wait for the network card to appear, set it up and wait for the cable to be - # plugged it. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Assign an IP address. - # "24" is prefix length, i.e. subnet mask 255.255.255.0 - net.ipv4.addr(dev, "192.168.62.3", "24"); - - # Add a default route. - net.ipv4.route("0.0.0.0", "0", "192.168.62.3", "20", dev); - - # Build a list of DNS servers. - # The NCD language does not support "expressions" - statement arguments must be - # constant strings or variables referring to preceding statements. - # A list can be constructed using the built-in list() statement. - list("192.168.62.5", "192.168.62.6") dns_servers; - - # Add the DNS servers. - net.dns(dns_servers, "20"); -} - -# -# Wireless network interface using wpa_supplicant. -# - -process WLAN { - # Set device. - var("wlan0") dev; - - # Wait for device and rfkill switch. - net.backend.waitdevice(dev); - net.backend.rfkill("wlan", dev); - - # Start wpa_supplicant on this interface, using configuration in /etc/wpa_supplicant/all.conf . - list() args; - net.backend.wpa_supplicant(dev, "/etc/wpa_supplicant/all.conf", "/usr/sbin/wpa_supplicant", args) sup; - - # wpa_supplicant tells us what network we connected to. Look below for how this can be used to - # have different configurations, "BadVPN, but configured differently based on what network we're in". - println("connected to wireless network: bssid=", sup.bssid, " ssid=", sup.ssid); - - # Wireless connection successful, here comes network config (DHCP/static/whatever) ... -} - -# -# A BadVPN VPN interface for access to the virtual network (only). -# - -process lan { - ... (something like above) ... - - # Alias our IP address for easy access from the "vpn" process (or, for a static address, alias - # it before assigning it, and assign it using the alias). - var(dhcp.addr) ipaddr; - - # Allow VPN to start at this point. - # (and require it to stop before deconfiguring the interface if e.g. the cable is plugged out) - provide("LAN"); -} - -process vpn { - # Need the local interface to be working in order start VPN. - depend("LAN") landep; - - # Choose the name of the network interface. - var("tap3") dev; - - # Construct command line arguments for badvpn-client. Adapt according to your setup. - # "--tapdev" will be provided automatically. - - # Alias the port number that the VPN process will bind to. - var("6000") port; - - # Construct dynamic parts of command line options. - # The VPN client program needs to know some IP addresses in order to tell other peers where to connect to. - # Obtain this informations from variables in the "lan" process through the depend() statement. - - # Construct the local address (addr + port). - concat(landep.ipaddr, ":", port) local_addr_arg; - - # Construct the Internet address (assuming we are behind a NAT). - # Need to know the NAT's external address here. But we could queried it somehow. - # That is if we have preconfigured the NAT router to forward ports. But we could implement a statement - # that obtains the mappings dynamically with UPnP! - concat("1.2.3.4", ":", port) internet_addr_arg; - - # Finally construct the complete arguments, using the above address arguments. - list( - "--logger", "syslog", "--syslog-ident", "badvpn", - "--server-addr", "badvpn.example.com:7000", - "--ssl", "--nssdb", "sql:/home/badvpn/nssdb", "--client-cert-name", "peer-someone", - "--transport-mode", "udp", "--encryption-mode", "blowfish", "--hash-mode", "md5", "--otp", "blowfish", "3000", "2000", - "--scope", "mylan", "--scope", "internet", - "--bind-addr", "0.0.0.0:6000", "--num-ports", "20", - "--ext-addr", local_addr_arg, "mylan", - "--ext-addr", internet_addr_arg, "internet" - ) args; - - # Start the BadVPN backend. - # "badvpn" is the user account which the VPN client will run as. - # If you use SSL, the NSS database must be accessible to this user. - net.backend.badvpn(dev, "badvpn", "/usr/bin/badvpn-client-26", args); - - # Assign an IP address to the VPN interface. - # (we could easily use DHCP here!) - net.ipv4.addr(dev, "10.0.0.1", "24"); -} - -# -# BadVPN, but configured differently based on what network we're in. -# The network is identified based on the IP address we were assigned by DHCP. -# The different configuration provide specific arguents to badvpn-client. -# - -process lan { - ... (interface config stuff using DHCP, see above) ... - ... (the 'ipaddr' variable holds the local IP address) ... - - # Match the address to various known networks. - ip_in_network(ipaddr, "192.168.4.0", "24") is_lan1; - ip_in_network(ipaddr, "192.168.7.0", "24") is_lan2; - - # Allow VPN to start at this point. - provide("LAN"); -} - -process vpn { - ... - - # Construct common arguments here ... - list( ... ) common_args; - - # Choose appropriate configuration by waking up the configuration processes - # and waiting for one to complete. - provide("VPN_CONF_START"); - depend("VPN_CONF_END") config; - - # Concatenate common and configuration-specific arguments. - concatlist(common_args, config.args) args; - - ... -} - -process vpn_config_lan1 { - depend("VPN_CONF_START") dep; - - # Proceed only if we're in lan1. - if(dep.landep.is_lan1); - - list( - ... - ) args; - - provide("VPN_CONF_END"); -} - -process vpn_config_lan2 { - depend("VPN_CONF_START") dep; - - # Proceed only if we're in lan2. - if(dep.landep.is_lan2); - - list( - ... - ) args; - - provide("VPN_CONF_END"); -} - -process vpn_config_inet { - depend("VPN_CONF_START") dep; - - # Proceed only if we're not in any known network. - ifnot(dep.landep.is_lan1); - ifnot(dep.landep.is_lan2); - - list( - ... - ) args; - - provide("VPN_CONF_END"); -} - -# -# Two wired network interfaces (eth0, eth1), both of which may be used for Internet access. -# When both are working, give priority to eth1 (e.g. if eth0 is up, but later eth1 also comes -# up, the configuration will be changed to use eth1 for Internet access). -# - -process eth0 { - # Set device. - var("eth0") dev; - - # Wait for device. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # DHCP configuration. - net.ipv4.dhcp(dev) dhcp; - ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local; - ifnot(test_local); - var(dhcp.addr) addr; - var(dhcp.prefix) addr_prefix; - var(dhcp.gateway) gateway; - var(dhcp.dns_servers) dns_servers; - - # Assign IP address. - net.ipv4.addr(dev, addr, addr_prefix); - - # Go on configuring the network. - multiprovide("NET-eth0"); -} - -process eth1 { - # Set device. - var("eth1") dev; - - # Wait for device. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Static configuration. - var("192.168.111.116") addr; - var("24") addr_prefix; - var("192.168.111.1") gateway; - list("192.168.111.14", "193.2.1.66") dns_servers; - - # Assign IP address. - net.ipv4.addr(dev, addr, addr_prefix); - - # Go on configuring the network. - multiprovide("NET-eth1"); -} - -process NETCONF { - # Wait for some network connection. Prefer eth1 by putting it in front of eth0. - list("NET-eth1", "NET-eth0") pnames; - multidepend(pnames) ifdep; - - # Alias device values. - var(ifdep.dev) dev; - var(ifdep.addr) addr; - var(ifdep.addr_prefix) addr_prefix; - var(ifdep.gateway) gateway; - var(ifdep.dns_servers) dns_servers; - - # Add default route. - net.ipv4.route("0.0.0.0", "0", gateway, "20", dev); - - # Configure DNS servers. - net.dns(dns_servers, "20"); -} diff --git a/external/badvpn_dns/ncd/emncd.c b/external/badvpn_dns/ncd/emncd.c deleted file mode 100644 index db41968..0000000 --- a/external/badvpn_dns/ncd/emncd.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file emncd.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/version.h> -#include <misc/debug.h> -#include <base/BLog.h> -#include <system/BTime.h> -#include <system/BReactor.h> -#include <ncd/NCDInterpreter.h> -#include <ncd/NCDConfigParser.h> - -#include <generated/blog_channel_ncd.h> - -static BReactor reactor; -static int running; -static NCDInterpreter interpreter; - -static void interpreter_handler_finished (void *user, int exit_code) -{ - ASSERT(running) - - fprintf(stderr, "--- interpreter terminated ---\n"); - - NCDInterpreter_Free(&interpreter); - - running = 0; -} - -__attribute__((used)) -int main () -{ - BLog_InitStderr(); - - fprintf(stderr, "--- initializing emncd version "GLOBAL_VERSION" ---\n"); - - BTime_Init(); - - BReactor_EmscriptenInit(&reactor); - - running = 0; - - return 0; -} - -__attribute__((used)) -void emncd_start (const char *program_text, int loglevel) -{ - ASSERT(program_text); - ASSERT(loglevel >= 0); - ASSERT(loglevel <= BLOG_DEBUG); - - if (running) { - fprintf(stderr, "--- cannot start, interpreter is already running! ---\n"); - return; - } - - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - BLog_SetChannelLoglevel(i, loglevel); - } - - // parse program - NCDProgram program; - if (!NCDConfigParser_Parse((char *)program_text ,strlen(program_text), &program)) { - fprintf(stderr, "--- error: failed to parse the program ---\n"); - return; - } - - // include commands are not implemented currently - if (NCDProgram_ContainsElemType(&program, NCDPROGRAMELEM_INCLUDE) || NCDProgram_ContainsElemType(&program, NCDPROGRAMELEM_INCLUDE_GUARD)) { - fprintf(stderr, "--- error: include mechanism is not supported in emncd ---\n"); - NCDProgram_Free(&program); - return; - } - - fprintf(stderr, "--- starting interpreter ---\n"); - - struct NCDInterpreter_params params; - params.handler_finished = interpreter_handler_finished; - params.user = NULL; - params.retry_time = 5000; - params.extra_args = NULL; - params.num_extra_args = 0; - params.reactor = &reactor; - - if (!NCDInterpreter_Init(&interpreter, program, params)) { - fprintf(stderr, "--- failed to initialize the interpreter ---\n"); - return; - } - - running = 1; - - BReactor_EmscriptenSync(&reactor); -} - -__attribute__((used)) -void emncd_stop (void) -{ - if (!running) { - fprintf(stderr, "--- cannot request termination, interpreter is not running! ---\n"); - return; - } - - fprintf(stderr, "--- requesting interpreter termination ---\n"); - - NCDInterpreter_RequestShutdown(&interpreter, 0); - - BReactor_EmscriptenSync(&reactor); -} diff --git a/external/badvpn_dns/ncd/emncd.html b/external/badvpn_dns/ncd/emncd.html deleted file mode 100644 index befc070..0000000 --- a/external/badvpn_dns/ncd/emncd.html +++ /dev/null @@ -1,320 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title>NCD in Javascript</title> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -</head> -<body> - -<script src="emncd.js"></script> - -<script> - -var cfunc_emncd_start = Module.cwrap('emncd_start', 'null', ['string']); -var cfunc_emncd_stop = Module.cwrap('emncd_stop', 'null', []); - -function on_start () -{ - var code = document.getElementById('codetext').value; - - var loglevel = 0; - for (i = 0; i <= 5; i++) { - if (document.getElementById('loglevel' + i).checked) { - loglevel = i; - } - } - - cfunc_emncd_start(code, loglevel); -} - -function on_stop () -{ - cfunc_emncd_stop(); -} - -function load_example (num) -{ - document.getElementById('codetext').value = document.getElementById('example' + num).value; -} - -</script> - -This is a quick port of my <a href="http://code.google.com/p/badvpn/wiki/NCD">NCD programming language</a> -to Javascript using the <a href="https://github.com/kripken/emscripten">Emscripten</a> compiler. -<br /> - -Please open the Javascript console so you can see the output (Chrome: CTRL+Shift+J. Firefox: CTRL+Shift+K). -<br /> - -<textarea id="example1" style="display:none;"> -process hello { - println("hello, world"); - exit("0"); -} -</textarea> - -<textarea id="example2" style="display:none;"> -process foo { - println("Starting up, please wait..."); - rprintln("Goodbye World!"); - - sleep("500", "300"); # sleeps 500ms on init and 300ms on deinit - - println("Hello World!"); - rprintln("Shutting down, please wait..."); -} -</textarea> - -<textarea id="example3" style="display:none;"> -process hello { - var("0") ctr; - - blocker() blk; - blk->up(); - blk->use(); - - num_modulo(ctr, "3") m_three; - num_modulo(ctr, "5") m_five; - num_equal(m_three, "0") d_three; - num_equal(m_five, "0") d_five; - and(d_three, d_five) d_three_five; - - If (d_three_five) { - var("fizzbuzz") text; - } Elif (d_three) { - var("fizz") text; - } Elif (d_five) { - var("buzz") text; - } else { - var(ctr) text; - } branch; - - println(branch.text); - - num_add(ctr, "1") i; - num_modulo(i, "20") i; - ctr->set(i); - - sleep("100", "0"); - blk->downup(); - -} -</textarea> - -<textarea id="example4" style="display:none;"> -process main { - var({"0", "1", "3", "2", "2", "3", "1", "1", "6", "end"}) list; - value(["1":"one", "2":"two", "3":"three"]) map; - - call("replace", {"_caller.list", "_caller.map"}) replace; - - to_string(replace.result) str; - println(str); - exit("0"); -} - -template replace { - alias(_arg0) list; - alias(_arg1) map; - - value({}) new_list; - Foreach (list As elem) { - map->try_get(elem) y; - If (y.exists) { - new_list->insert(new_list.length, y); - } Else { - new_list->insert(new_list.length, elem); - }; - }; - - alias("new_list") result; -} -</textarea> - -<textarea id="example5" style="display:none;"> -process hello { - println("Hello, NCD in Javascript!"); - println("Will now wait 2 seconds."); - rprintln("Goodbye."); - - sleep("2000", "3000"); - rprintln("Waiting 3 seconds before dying."); - - call("func", {"FirstArg", "SecondArg"}); - - var({"one", "two", "three"}) list; - to_string(list) str; - println(str); - - Foreach (list As elem) { - println("start ", elem); - rprintln("stop ", elem); - }; - - println("We're finished. Press "Request termination" to unwind us."); - rprintln("Terminating..."); -} - -template func { - println("func here, my args are: ", _arg0, " ", _arg1); - rprintln("func going away"); -} -</textarea> - -<textarea id="example6" style="display:none;"> -process main { - # Turing machine specification. - var("B") blank; - var([ - {"0", "0"}:{"0", "0", "right"}, - {"0", "1"}:{"1", "x", "right"}, - {"1", "1"}:{"1", "1", "right"}, - {"1", "0"}:{"2", "0", "right"}, - {"2", "0"}:{"2", "0", "right"}, - {"2", "1"}:{"3", "1", "right"}, - {"3", "1"}:{"3", "1", "right"}, - {"3", "0"}:{"4", "1", "left"}, - {"3", "B"}:{"4", "1", "left"}, - {"4", "1"}:{"4", "1", "left"}, - {"4", "0"}:{"5", "0", "left"}, - {"5", "0"}:{"5", "0", "left"}, - {"5", "1"}:{"6", "1", "left"}, - {"5", "x"}:{"h", "x", "stay"}, - {"6", "1"}:{"6", "1", "left"}, - {"6", "x"}:{"0", "x", "right"}, - {"6", "0"}:{"0", "0", "right"} - ]) rules; - var("0") initial_state; - var({}) initial_tape_left; - var({ - "1", "1", "1", "1", "0", "0", "1", "1", "1", "1" - }) initial_tape_right; - - # Perform the computation, stopping when no rule matches. - call("turing", {blank, rules, initial_state, initial_tape_left, initial_tape_right}) results; - - # Print results. - to_string(results.tape_left) tape_left; - to_string(results.tape_right) tape_right; - to_string({results.side, results.pos}) head_pos; - to_string(results.state) head_state; - println("Tape L: ", tape_left); - println("Tape R: ", tape_right); - println("Head position: ", head_pos); - println("Head state: ", head_state); - - exit("0"); -} - -template turing { - alias("_arg0") blank; - value(_arg1) rules; - alias("_arg2") initial_state; - alias("_arg3") initial_tape_left; - alias("_arg4") initial_tape_right; - - # Head state. - var(initial_state) state; - - # Tape. Positions go like this: ... L2 L1 L0 R0 R1 R2 ... - value(initial_tape_left) tape_left; - value(initial_tape_right) tape_right; - - # Make sure each side of the tape has at least one symbol so we can flip easily. - tape_left->insert(tape_left.length, blank); - tape_right->insert(tape_right.length, blank); - - # Head position. - var("right") side; - var("0") pos; - - # Enter loop. - blocker() loop_blk; - loop_blk->up(); - loop_blk->use(); - - # Get symbol under head. - concat("tape_", side) tape_name; - alias(tape_name) cur_tape; - cur_tape->get(pos) symbol; - - # Look for a matching rule. - rules->try_get({state, symbol}) rule; - - If (rule.exists) { - # Extract directions from rule. - rule->get("0") new_state; - rule->get("1") new_symbol; - rule->get("2") move; - - # Change head state. - state->set(new_state); - - # Replace symbol under head. - cur_tape->remove(pos); - cur_tape->insert(pos, new_symbol); - - # Branch based on how we move. - strcmp(move, side) is_outside; - strcmp(move, "stay") is_stay; - strcmp(pos, "0") is_zero; - If (is_outside) { - # Increment position. - num_add(pos, "1") new_pos; - pos->set(new_pos); - - # If the new position is out of range, extend tape. - strcmp(pos, cur_tape.length) need_extend; - If (need_extend) { - cur_tape->insert(pos, blank); - }; - } elif (is_stay) { - # Nop. - getargs(); - } elif (is_zero) { - # Flip side, leave pos at zero. - side->set(move); - } else { - # Decrement position. - num_subtract(pos, "1") new_pos; - pos->set(new_pos); - }; - - # Continue loop. - loop_blk->downup(); - }; -} -</textarea> - -Examples: -<button onclick="load_example(1)">Hello World</button> -<button onclick="load_example(2)">Sleep</button> -<button onclick="load_example(3)">FizzBuzz</button> -<button onclick="load_example(4)">Replace</button> -<button onclick="load_example(5)">Foreach, call</button> -<button onclick="load_example(6)">Turing Machine</button> -<br /> - -<textarea rows=30 cols=80 id="codetext"> -process hello { - println("hello, world"); - exit("0"); -} -</textarea> -<br /> - -Loglevel: -<input type="radio" name="loglevel" id="loglevel0"> None -<input type="radio" name="loglevel" id="loglevel1"> Error -<input type="radio" name="loglevel" id="loglevel2" checked> Warning -<input type="radio" name="loglevel" id="loglevel3"> Notice -<input type="radio" name="loglevel" id="loglevel4"> Info -<input type="radio" name="loglevel" id="loglevel5"> Debug <br /> - -<button onclick="on_start()">Start NCD</button> -<button onclick="on_stop()">Request termination</button> -<br /> -Note: if you get the interpreter stuck and unable to terminate, just refresh the page - -</body> -</html> diff --git a/external/badvpn_dns/ncd/examples/dbus_start.ncd b/external/badvpn_dns/ncd/examples/dbus_start.ncd deleted file mode 100644 index 832b359..0000000 --- a/external/badvpn_dns/ncd/examples/dbus_start.ncd +++ /dev/null @@ -1,82 +0,0 @@ -process main { - call("dbus_start", {{"--session", "--nopidfile"}}) dbus_start; - - println("Got dbus: ", dbus_start.dbus_address); - rprintln("Lost dbus"); -} - -template dbus_start { - alias("_arg0") dbus_args; - - var("false") retrying; - - backtrack_point() retry_point; - If (retrying) { - println("dbus_start: retrying in one second"); - sleep("1000", "0"); - }; - - retrying->set("true"); - - listfrom({"/usr/bin/dbus-daemon"}, dbus_args, {"--print-address"}) dbus_command; - - sys.start_process(dbus_command, "r") proc; - If (proc.is_error) { - println("dbus_start: error starting process"); - retry_point->go(); - }; - - var("") dbus_address; - blocker() finished_blocker; - - process_manager() mgr; - mgr->start("dbus_start__waiter", {}); - mgr->start("dbus_start__reader", {}); - - finished_blocker->use(); -} - -template dbus_start__waiter { - alias("_caller.proc") proc; - alias("_caller.retry_point") retry_point; - - proc->wait(); - println("dbus_start: process terminated"); - retry_point->go(); -} - -template dbus_start__reader { - alias("_caller.proc") proc; - alias("_caller.retry_point") retry_point; - alias("_caller.dbus_address") dbus_address; - alias("_caller.finished_blocker") finished_blocker; - - proc->read_pipe() rpipe; - If (rpipe.is_error) { - println("dbus_start: read pipe error"); - retry_point->go(); - }; - - value("") buffer; - - backtrack_point() read_point; - rpipe->read() data; - - If (data.not_eof) { - buffer->append(data); - - explode("\n", buffer, "2") exp; - value(exp) exp; - - num_greater(exp.length, "1") found; - If (found) { - exp->get("0") address; - dbus_address->set(address); - finished_blocker->up(); - }; - - read_point->go(); - }; - - println("dbus_start: read pipe eof"); -} diff --git a/external/badvpn_dns/ncd/examples/dhcpd.conf.template b/external/badvpn_dns/ncd/examples/dhcpd.conf.template deleted file mode 100644 index 9ce5ad2..0000000 --- a/external/badvpn_dns/ncd/examples/dhcpd.conf.template +++ /dev/null @@ -1,11 +0,0 @@ -default-lease-time 600; -max-lease-time 7200; -log-facility local7; -ddns-update-style none; -local-address <LOCAL_ADDRESS>; - -subnet <NETWORK> netmask <NETMASK> { - range <RANGE_START> <RANGE_END>; - option routers <ROUTERS>; - option domain-name-servers <DNS_SERVERS>; -} diff --git a/external/badvpn_dns/ncd/examples/directory_updater.ncd b/external/badvpn_dns/ncd/examples/directory_updater.ncd deleted file mode 100644 index cb546ff..0000000 --- a/external/badvpn_dns/ncd/examples/directory_updater.ncd +++ /dev/null @@ -1,72 +0,0 @@ -# -# Watches a directory and runs an update program whenever something -# changes. This is race-free, and if the directory changes while the -# update is running, it will be done again. -# -# NOTE: the update should not modify the directory. If it does, the -# the result will be endless and constant updating. -# - -process watcher { - # Blocker object used to trigger an update. - blocker() blk; - - # State: updating - if updater script is running - # updating_dirty - if something changed while - # script was running - var("false") updating; - var("false") updating_dirty; - - # Start update process. - spawn("updater", {}); - - # Wait for directory event. - # CHANGE THIS - sys.watch_directory("/home/ambro") watcher; - - # Print event details (e.g. "added somefile"). - println(watcher.filename, " ", watcher.event_type); - - # If updating is in progress, mark dirty. - If (updating) { - updating_dirty->set("true"); - }; - - # Request update. This makes use() proceed forward. - blk->up(); - - # Wait for next event (execution moves up). - watcher->nextevent(); -} - -template updater { - # Wait for update request. - _caller.blk->use(); - - # Wait some time. - sleep("1000", "0"); - - # We're about to start update script - set updating - # variable and mark as non dirty. - _caller.updating_dirty->set("false"); - _caller.updating->set("true"); - - println("Update started"); - - # CHANGE THIS - sleep("3000", "0"); - #runonce({"/bin/echo", "Updater speaking"}, {"keep_stdout", "keep_stderr"}); - - println("Update finished"); - - # No longer running update script. - _caller.updating->set("false"); - - # If something changed while script was running, restart - # update; else wait for next update request. - If (_caller.updating_dirty) { - _caller.blk->downup(); - } else { - _caller.blk->down(); - }; -} diff --git a/external/badvpn_dns/ncd/examples/events.ncd b/external/badvpn_dns/ncd/examples/events.ncd deleted file mode 100644 index 9fe80a8..0000000 --- a/external/badvpn_dns/ncd/examples/events.ncd +++ /dev/null @@ -1,101 +0,0 @@ -# -# NCD input event handling example program. -# -# This program responds to volume key presses by synchronously calling an external -# script for muting and adjusting volume, and responds to power button presses by -# suspending using pm-suspend. -# -# It uses process_manager() and sys.watch_input() to dynamically create and remove -# processes that deal with specific input devices. The individual input device processes -# then use sys.evdev() to handle input events from their input device. -# - -process events_main { - # Volume control script, called with argument "up", "down" or "mute". - var("/usr/local/bin/volumekey") volume_script; - - # Suspend command. - list("/usr/sbin/pm-suspend") suspend_cmd; - - provide("GLOBAL"); -} - -process events_watcher { - depend("GLOBAL"); - - # Create process manager. - process_manager() manager; - - # Wait for input device events. - sys.watch_input("event") watcher; - - # Dispatch. - concat("events_watcher_", watcher.event_type) func; - call(func, {}); - - # Next event. - watcher->nextevent(); -} - -template events_watcher_added { - # Start event handling process for this device. - _caller.manager->start(_caller.watcher.devname, "events_input_device", {_caller.watcher.devname}); -} - -template events_watcher_removed { - # Stop event handling process for this device. - _caller.manager->stop(_caller.watcher.devname); -} - -template events_input_device { - # Alias arguments. - var(_arg0) dev; - - # Get global. - depend("GLOBAL") gdep; - - # Wait for input events. - sys.evdev(dev) evdev; - - # Query event details. - strcmp(evdev.code, "KEY_MUTE") is_mute; - strcmp(evdev.code, "KEY_VOLUMEUP") is_vup; - strcmp(evdev.code, "KEY_VOLUMEDOWN") is_vdown; - strcmp(evdev.code, "KEY_POWER") is_power; - strcmp(evdev.value, "1") is_pressed; - - # Compute where to dispatch the event. - and(is_mute, is_pressed) dispatch_mute; - and(is_vup, is_pressed) dispatch_vup; - and(is_vdown, is_pressed) dispatch_vdown; - and(is_power, is_pressed) dispatch_power; - - # Dispatch event. - choose({ - {dispatch_mute, "events_input_event_mute"}, - {dispatch_vup, "events_input_event_vup"}, - {dispatch_vdown, "events_input_event_vdown"}, - {dispatch_power, "events_input_event_power"}}, - "<none>" - ) func; - call(func, {}); - - # Next event. - evdev->nextevent(); -} - -template events_input_event_mute { - runonce({_caller.gdep.volume_script, "mute"}); -} - -template events_input_event_vup { - runonce({_caller.gdep.volume_script, "up"}); -} - -template events_input_event_vdown { - runonce({_caller.gdep.volume_script, "down"}); -} - -template events_input_event_power { - runonce(_caller.gdep.suspend_cmd); -} diff --git a/external/badvpn_dns/ncd/examples/igmpproxy.conf.template b/external/badvpn_dns/ncd/examples/igmpproxy.conf.template deleted file mode 100644 index 9e5a83c..0000000 --- a/external/badvpn_dns/ncd/examples/igmpproxy.conf.template +++ /dev/null @@ -1,10 +0,0 @@ -quickleave - -phyint <UPSTREAM_IFACE> upstream ratelimit 0 threshold 1 - altnet 89.143.8.0/24 - altnet 95.176.0.0/16 - -phyint <DOWNSTREAM_IFACE> downstream ratelimit 0 threshold 1 - -# A lot of these will be appended by make_igmpproxy_config: -# phyint eth0 disabled diff --git a/external/badvpn_dns/ncd/examples/make_dhcp_config.ncd b/external/badvpn_dns/ncd/examples/make_dhcp_config.ncd deleted file mode 100644 index 201a052..0000000 --- a/external/badvpn_dns/ncd/examples/make_dhcp_config.ncd +++ /dev/null @@ -1,27 +0,0 @@ -process main { - call("make_dhcp_config", {"192.168.1.1", "24", "192.168.1.100", "192.168.1.199", {"192.168.1.1"}, {"192.168.1.1", "4.4.4.4"}, "dhcpd.conf.template", "dhcpd.conf"}) config; - exit("0"); -} - -template make_dhcp_config { - alias("_arg0") addr; - alias("_arg1") prefix; - alias("_arg2") range_start; - alias("_arg3") range_end; - alias("_arg4") routers; - alias("_arg5") dns_servers; - alias("_arg6") template_file; - alias("_arg7") output_file; - - ipv4_net_from_addr_and_prefix(addr, prefix) network; - ipv4_prefix_to_mask(prefix) netmask; - implode(", ", routers) routers_str; - implode(", ", dns_servers) dns_servers_str; - - var({"<LOCAL_ADDRESS>", "<NETWORK>", "<NETMASK>", "<RANGE_START>", "<RANGE_END>", "<ROUTERS>", "<DNS_SERVERS>"}) regex; - var({addr, network, netmask, range_start, range_end, routers_str, dns_servers_str}) replace; - - file_read(template_file) template_data; - regex_replace(template_data, regex, replace) replaced_data; - file_write(output_file, replaced_data); -} diff --git a/external/badvpn_dns/ncd/examples/make_igmpproxy_config.ncd b/external/badvpn_dns/ncd/examples/make_igmpproxy_config.ncd deleted file mode 100644 index 77ca0a9..0000000 --- a/external/badvpn_dns/ncd/examples/make_igmpproxy_config.ncd +++ /dev/null @@ -1,53 +0,0 @@ -process main { - call("make_igmpproxy_config", {"br0", "eth1", "./igmpproxy.conf.template", "./igmpproxy.conf"}); - - println("Done."); - exit("0"); -} - -template make_igmpproxy_config { - alias("_arg0") upstream_iface; - alias("_arg1") downstream_iface; - alias("_arg2") template_file; - alias("_arg3") output_file; - - # Make a list of interfaces to add as disabled (upstream and downstream will not be disabled). - var({ - "eth0", "eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "eth7", "eth8", "eth9", - "wlan0", "wlan1", "wlan2", "wlan3", "wlan4", "wlan5", "wlan6", "wlan7", "wlan8", "wlan9", - "tap0", "tap1", "tap2", "tap3", "tap4", "tap5", "tap6", "tap7", "tap8", "tap9", - "br0", "br1", "br2", "br3", "br4", "br5", "br6", "br7", "br8", "br9" - }) disabled_ifaces; - - # Build replacements for template config. - var({"<UPSTREAM_IFACE>", "<DOWNSTREAM_IFACE>"}) regex; - var({upstream_iface, downstream_iface}) replace; - - # Read template config. - file_read(template_file) template_data; - - # Perform replacements. - regex_replace(template_data, regex, replace) replaced_data; - - # Build string value from replaced_data, to which we will append - # configuration for disabled interfaces. - value(replaced_data) output_data; - - # Build disabled strings. - Foreach (disabled_ifaces As iface) { - # Determine if the interface is disabled. - val_equal(iface, upstream_iface) is_up; - val_equal(iface, downstream_iface) is_down; - or(is_up, is_down) is_not_disabled; - not(is_not_disabled) is_disabled; - - # If it's disabled, append to the configuration file. - If (is_disabled) { - concat("phyint ", iface, " disabled\n") str; - output_data->append(str); - }; - }; - - # Write config. - file_write(output_file, output_data); -} diff --git a/external/badvpn_dns/ncd/examples/network.ncd b/external/badvpn_dns/ncd/examples/network.ncd deleted file mode 100644 index 2eaeb8f..0000000 --- a/external/badvpn_dns/ncd/examples/network.ncd +++ /dev/null @@ -1,123 +0,0 @@ -# An example NCD script for network configuration. -# -# The first three processes demonstrate different kinds of interfaces -# and configurations. They are all disabled by default. -# -# The last process waits for one of the interfaces to come up -# and sets up routes and DNS entries to use that interface for -# Internet access. -# -# Be sure to change the dependency list in the last process to name -# the interfaces you use. - -# Example wired interface with static configuration. -process wired_example_static { - if("false"); # remove/comment to enable - - # Set device. - var("eth0") dev; - - # Wait for device. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Static configuration. - var("192.168.111.116") addr; - var("24") addr_prefix; - var("192.168.111.1") gateway; - var({"192.168.111.14", "193.2.1.66"}) dns_servers; - - # Assign IP address. - net.ipv4.addr(dev, addr, addr_prefix); - - # Go on configuring the network. - concat("NET-", dev) provide_name; - multiprovide(provide_name); -} - -# Example wired interface with DHCP configuration. -process wired_example_dhcp { - if("false"); # remove/comment to enable - - # Set device. - var("eth1") dev; - - # Wait for device. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # DHCP configuration. - net.ipv4.dhcp(dev) dhcp; - ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local; - ifnot(test_local); - var(dhcp.addr) addr; - var(dhcp.prefix) addr_prefix; - var(dhcp.gateway) gateway; - var(dhcp.dns_servers) dns_servers; - - # Assign IP address. - net.ipv4.addr(dev, addr, addr_prefix); - - # Go on configuring the network. - concat("NET-", dev) provide_name; - multiprovide(provide_name); -} - -# Example wireless interface with DHCP configuration. -# This will use the wpa_supplicant configuration file /etc/wpa_supplicant/all.conf -# which should specify the wireless networks and other options. -process wireless_example_dhcp { - if("false"); # remove/comment to enable - - # Set device. - var("wlan0") dev; - - # Wait for device and rfkill. - net.backend.waitdevice(dev); - net.backend.rfkill("wlan", dev); - - # Connect to wireless network. - net.backend.wpa_supplicant(dev, "/etc/wpa_supplicant/all.conf", "/usr/sbin/wpa_supplicant", {}); - - # DHCP configuration. - net.ipv4.dhcp(dev) dhcp; - ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local; - ifnot(test_local); - var(dhcp.addr) addr; - var(dhcp.prefix) addr_prefix; - var(dhcp.gateway) gateway; - var(dhcp.dns_servers) dns_servers; - - # Assign IP address. - net.ipv4.addr(dev, addr, addr_prefix); - - # Go on configuring the network. - concat("NET-", dev) provide_name; - multiprovide(provide_name); -} - -# This process sets up routes and DNS servers for at most one of -# the working interfaces. It will change the configuration if a -# more important interface comes up while one is already up. -process NETCONF { - # Choose devices and priorities; put preferred devices to the front. - var({"NET-eth0", "NET-eth1", "NET-wlan0"}) provide_names; - - # Wait for one of the interfaces (and deinit/switch appropriately). - multidepend(provide_names) ifdep; - - # Alias device values. - var(ifdep.dev) dev; - var(ifdep.addr) addr; - var(ifdep.addr_prefix) addr_prefix; - var(ifdep.gateway) gateway; - var(ifdep.dns_servers) dns_servers; - - # Add default route. - net.ipv4.route("0.0.0.0", "0", gateway, "20", dev); - - # Configure DNS servers. - net.dns(dns_servers, "20"); -} diff --git a/external/badvpn_dns/ncd/examples/onoff_server.ncdi b/external/badvpn_dns/ncd/examples/onoff_server.ncdi deleted file mode 100644 index a380cde..0000000 --- a/external/badvpn_dns/ncd/examples/onoff_server.ncdi +++ /dev/null @@ -1,82 +0,0 @@ -include_guard "onoff_server" - -template onoff_server_main { - alias("_arg0") socket_path; - - depend_scope() depsc; - process_manager() mgr; - - sys.request_server({"unix", socket_path}, "onoff_server__request_handler", {}); -} - -template onoff_server_onoff { - alias(_arg0) main; - alias("_arg1") onoff_id; - alias("_arg2") default_state; - - main.mgr->start(onoff_id, "onoff_server__id_proc", {onoff_id, default_state}); - main.depsc->depend({onoff_id}) id_proc; - - id_proc.blk->use(); -} - -template onoff_server__id_proc { - alias("_caller") main; - alias("_arg0") onoff_id; - alias("_arg1") default_state; - - blocker() blk; - If (default_state) { - blk->up(); - }; - main.depsc->provide(onoff_id); -} - -template onoff_server__request_handler { - alias("_caller") main; - - try("onoff_server__try_request", {}); - - _request->reply({"error", "Bad request."}); - _request->finish(); -} - -template onoff_server__try_request { - alias("_caller.main") main; - alias("_caller._request") request; - - value(request.data) data; - - val_equal(data.type, "list") a; - _try->assert(a); - - num_greater_equal(data.length, "1") a; - _try->assert(a); - - data->get("0") request_cmd; - val_equal(request_cmd, "set_onoff") is_set_onoff; - - If (is_set_onoff) { - num_equal(data.length, "3") a; - _try->assert(a); - - data->get("1") onoff_id; - data->get("2") new_state; - - main.mgr->start(onoff_id, "onoff_server__id_proc", {onoff_id, new_state}); - main.depsc->depend({onoff_id}) id_proc; - - val_equal(new_state, "true") is_on; - If (is_on) { - id_proc.blk->up(); - } Else { - id_proc.blk->down(); - }; - } - Else { - _try->assert("false"); - }; - - request->reply({"OK", "state has been set"}); - request->finish(); -} diff --git a/external/badvpn_dns/ncd/examples/onoff_server_test.ncd b/external/badvpn_dns/ncd/examples/onoff_server_test.ncd deleted file mode 100644 index 7ff0b16..0000000 --- a/external/badvpn_dns/ncd/examples/onoff_server_test.ncd +++ /dev/null @@ -1,20 +0,0 @@ -include "onoff_server.ncdi" - -process main { - call("onoff_server_main", {"/home/ambro/onoff.socket"}) onoff_server; - - process_manager() mgr; - mgr->start("service1", {}); - #mgr->start("service2", {}); -} - -template service1 { - alias("_caller") main; - - call("onoff_server_onoff", {"_caller.main.onoff_server", "ServiceId1", "true"}); - - println("service1 up"); - rprintln("service1 down"); - - # Do your stuff. -} diff --git a/external/badvpn_dns/ncd/examples/router/README b/external/badvpn_dns/ncd/examples/router/README deleted file mode 100644 index 7be3743..0000000 --- a/external/badvpn_dns/ncd/examples/router/README +++ /dev/null @@ -1,36 +0,0 @@ -NCD Router Example - --- Operation --- - -These are the NCD scripts I run on my home router. -Three network interfaces are being configured: - -1. The LAN interface. -The DHCP server is started for this interface, and also a DNS server (unbound). -2. The Internet interface. -This is a PPPoE interface with NAT. -3. The ServerIf interface. -This one behaves similarly to the LAN interface, except that there is no DHCP server. -The intention is to put servers here so you can restrict communication not only between Internet and the servers, -but also between LAN and the servers (though this configuration doesn't actually do the latter). - -Hosts on the LAN and ServerIf interfaces can access the Internet, and source NAT is used here. -Additionally, it is possible to add port forwardings (DNAT) from the Internet interface to either -of those two interfaces. These can be managed with the scripts {list,add,remove}-port-forwarding. -The list of port forwarding is stored in the file /var/lib/ncd-port-forwardings.ncdvalue. -However, you should NOT modify this file while NCD is running. You should not modify it at all, because -NCD may accidentally overwrite your changes. Just use the scripts. - -Iptables is used to filter incoming connections from the Internet interface. -Exceptions can be added; for example, there's a commented line in template network_internet_pppoe_preup which allows access to the local SSH server. -To allow access to servers running on other hosts (LAN or ServerIf interface), a port forwarding should be added dynamically. - --- Installation -- - -The following pppd patch is required for PPPoE to work: -https://code.google.com/p/ambro-gentoo-overlay/source/browse/trunk/net-dialu... - -Copy ncd.conf to /etc/, and copy all other files here into a new directory /etc/ncd-network. -Explanation: ncd.conf just loads network.ncdi, which is where the bulk of the configuration is defined. -Make the {list,add,remove}-port-forwarding scripts executable. Additionally, if your NCD interpreter is not located at /usr/bin/badvpn-ncd, -adjust the interpreter paths inside them. diff --git a/external/badvpn_dns/ncd/examples/router/add-port-forwarding b/external/badvpn_dns/ncd/examples/router/add-port-forwarding deleted file mode 100644 index 5d8a508..0000000 --- a/external/badvpn_dns/ncd/examples/router/add-port-forwarding +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/badvpn-ncd - -process main { - getargs() args; - value(args) args; - - num_different(args.length, "4") bad_args; - If (bad_args) { - println("Usage: add-port-forwarding <protocol> <port_start> <port_end> <dest_addr>"); - exit("1"); - }; - - args->get("0") protocol; - args->get("1") port_start; - args->get("2") port_end; - args->get("3") dest_addr; - - var("0") exit_status; - - sys.request_client({"unix", "/run/ncd-control.socket"}) client; - - var({"add-port-forwarding", protocol, port_start, port_end, dest_addr}) request_data; - - client->request(request_data, "reply_handler", "finished_handler", {}); -} - -template reply_handler { - value(_reply.data) reply_data; - reply_data->get("0") status; - reply_data->get("1") text; - - val_equal(status, "ok") is_ok; - If (is_ok) { - println(text); - } Else { - _caller.exit_status->set("1"); - println("Error: ", text); - }; -} - -template finished_handler { - exit(_caller.exit_status); -} diff --git a/external/badvpn_dns/ncd/examples/router/dhcp_server.ncdi b/external/badvpn_dns/ncd/examples/router/dhcp_server.ncdi deleted file mode 100644 index 98c2543..0000000 --- a/external/badvpn_dns/ncd/examples/router/dhcp_server.ncdi +++ /dev/null @@ -1,60 +0,0 @@ -include_guard "dhcp_server" - -template dhcp_server { - alias("_arg0") addr; - alias("_arg1") prefix; - alias("_arg2") range_start; - alias("_arg3") range_end; - alias("_arg4") routers; - alias("_arg5") dns_servers; - - # Choose lease file. - concat("/var/lib/dhcp/dhcpd-", addr, ".leases") leases_file; - - # Create leases file if it doesn't exist. - file_stat(leases_file) stat; - If (stat.succeeded) { print(); } Else { - file_write(leases_file, ""); - }; - - # Create a temporary directory. - concat("/run/ncd-dhcp-server-", addr) run_dir; - run({"/bin/rm", "-rf", run_dir}, {}); - run({"/bin/mkdir", run_dir}, {"/bin/rm", "-rf", run_dir}); - - # Compute path for dhcp.conf. - concat(run_dir, "/dhcp.conf") dhcp_conf_path; - - # This is a template for dhcp.conf. - var(" -default-lease-time 43200; -max-lease-time 43200; -log-facility local7; -ddns-update-style none; -local-address <LOCAL_ADDRESS>; - -subnet <NETWORK> netmask <NETMASK> { - authoritative; - range <RANGE_START> <RANGE_END>; - option routers <ROUTERS>; - option domain-name-servers <DNS_SERVERS>; -} -" ) config_template; - - # Compute some of the variables. - ipv4_net_from_addr_and_prefix(addr, prefix) network; - ipv4_prefix_to_mask(prefix) netmask; - implode(", ", routers) routers_str; - implode(", ", dns_servers) dns_servers_str; - - # Perform substitutions. - var({"<LOCAL_ADDRESS>", "<NETWORK>", "<NETMASK>", "<RANGE_START>", "<RANGE_END>", "<ROUTERS>", "<DNS_SERVERS>"}) regex; - var({addr, network, netmask, range_start, range_end, routers_str, dns_servers_str}) replace; - regex_replace(config_template, regex, replace) config_data; - - # Write dhcp.conf. - file_write(dhcp_conf_path, config_data); - - # Start dhcpd. - daemon({"/usr/sbin/dhcpd", "-f", "-cf", dhcp_conf_path, "-user", "dhcp", "-group", "dhcp", "--no-pid", "-lf", leases_file}); -} diff --git a/external/badvpn_dns/ncd/examples/router/list-port-forwardings b/external/badvpn_dns/ncd/examples/router/list-port-forwardings deleted file mode 100644 index 3244c56..0000000 --- a/external/badvpn_dns/ncd/examples/router/list-port-forwardings +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/badvpn-ncd - -process main { - getargs() args; - value(args) args; - - num_different(args.length, "0") bad_args; - If (bad_args) { - println("Usage: list-port-forwardings"); - exit("1"); - }; - - var("0") exit_status; - - sys.request_client({"unix", "/run/ncd-control.socket"}) client; - - var({"list-port-forwardings"}) request_data; - - client->request(request_data, "reply_handler", "finished_handler", {}); -} - -template reply_handler { - value(_reply.data) reply_data; - reply_data->get("0") status; - reply_data->get("1") arg; - - val_equal(status, "ok") is_ok; - If (is_ok) { - println("Protocol Start End Destination"); - Foreach (arg As entry) { - value(entry) entry; - entry->get("0") protocol; - entry->get("1") port_start; - entry->get("2") port_end; - entry->get("3") dest_addr; - call("append_spaces", {port_start, "5"}) fixed_start; - call("append_spaces", {port_end, "5"}) fixed_end; - println(protocol, " ", fixed_start.result, " ", fixed_end.result, " ", dest_addr); - }; - } Else { - _caller.exit_status->set("1"); - println("Error: ", arg); - }; -} - -template finished_handler { - exit(_caller.exit_status); -} - -template append_spaces { - alias("_arg0") input; - alias("_arg1") min_length; - - value(input) result; - backtrack_point() point; - num_lesser(result.length, min_length) more; - If (more) { - result->append(" "); - point->go(); - }; -} diff --git a/external/badvpn_dns/ncd/examples/router/ncd.conf b/external/badvpn_dns/ncd/examples/router/ncd.conf deleted file mode 100644 index 56f6a73..0000000 --- a/external/badvpn_dns/ncd/examples/router/ncd.conf +++ /dev/null @@ -1,6 +0,0 @@ -include "/etc/ncd-network/network.ncdi" - -process main { - process_manager() mgr; - mgr->start("network_main", {}); -} diff --git a/external/badvpn_dns/ncd/examples/router/network.ncdi b/external/badvpn_dns/ncd/examples/router/network.ncdi deleted file mode 100644 index f2a02cd..0000000 --- a/external/badvpn_dns/ncd/examples/router/network.ncdi +++ /dev/null @@ -1,356 +0,0 @@ -include_guard "network" - -include "pppoe.ncdi" -include "dhcp_server.ncdi" -include "unbound.ncdi" -include "network_control_server.ncdi" -include "port_forwarding.ncdi" - -template network_main { - log("notice", "NCD starting"); - log_r("notice", "NCD stopped"); - - # Load ipv6 module so we can disable ipv6. - runonce({"/sbin/modprobe", "ipv6"}); - - # Set some sysctl's. - runonce({"/sbin/sysctl", "net.ipv4.ip_forward=1"}); - runonce({"/sbin/sysctl", "net.ipv6.conf.all.disable_ipv6=1"}); - - # Setup iptables INPUT chain. - net.iptables.policy("filter", "INPUT", "ACCEPT", "ACCEPT"); - net.iptables.append("filter", "INPUT", "-i", "lo", "-j", "ACCEPT"); - net.iptables.append("filter", "INPUT", "-m", "conntrack", "--ctstate", "ESTABLISHED", "-j", "ACCEPT"); - - # Setup iptables OUTPUT chain. - net.iptables.policy("filter", "OUTPUT", "ACCEPT", "ACCEPT"); - - # Setup iptables FORWARD chain. - net.iptables.policy("filter", "FORWARD", "DROP", "ACCEPT"); - net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "ESTABLISHED", "-j", "ACCEPT"); - net.iptables.append("filter", "FORWARD", "-m", "connmark", "--mark", "0x1/0x1", "-j", "ACCEPT"); - - # Create dependency scope. - depend_scope() depsc; - - # Start processes. - process_manager() mgr; - mgr->start("network_lan", {}); - mgr->start("network_serverif", {}); - mgr->start("network_internet", {}); - mgr->start("network_lan_internet_rules", {}); - mgr->start("network_serverif_internet_rules", {}); - mgr->start("network_lan_serverif_rules", {}); - mgr->start("network_lan_dhcp_server", {}); - mgr->start("network_unbound", {}); - mgr->start("network_port_forwarding", {}); - mgr->start("network_start_control_server", {}); -} - -template network_weak_hostmodel_rules { - alias("_arg0") dev; - alias("_arg1") addr; - - concat("INPUT_hostmodel_drop_", dev) drop_chain; - - net.iptables.newchain("filter", drop_chain); - net.iptables.append("filter", drop_chain, "-j", "DROP"); - net.iptables.append("filter", "INPUT", "-d", addr, "!", "-i", dev, "-j", drop_chain); -} - -template network_weak_hostmodel_exception { - alias("_arg0") dev; - alias("_arg1") match; - - concat("INPUT_hostmodel_drop_", dev) drop_chain; - - listfrom({"filter", drop_chain}, match, {"-j", "RETURN"}) args; - net.iptables.insert(args); -} - -template network_lan { - alias("_caller") main; - - # Some configuration. - var("enp1s0") dev; - var("192.168.111.1") addr; - var("24") prefix; - var("192.168.111.100") dhcp_start; - var("192.168.111.149") dhcp_end; - - main.depsc->provide("lan_config"); - - # Wait for device, set up, wait for link. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Weak host model. - call("network_weak_hostmodel_rules", {dev, addr}); - - # Assign IP address. - net.ipv4.addr(dev, addr, prefix); - - # Do SNAT for port forwardings when connections originate from the inside. - net.iptables.append("nat", "POSTROUTING", "-m", "connmark", "--mark", "0x2/0x2", "-j", "SNAT", "--to-source", addr, "--random"); - - main.depsc->provide("lan"); -} - -template network_serverif { - alias("_caller") main; - - # Some configuration. - var("enp3s0") dev; - var("192.168.113.1") addr; - var("24") prefix; - - main.depsc->provide("serverif_config"); - - # Wait for device, set up, wait for link. - net.backend.waitdevice(dev); - net.up(dev); - net.backend.waitlink(dev); - - # Weak host model. - call("network_weak_hostmodel_rules", {dev, addr}); - - # Assign IP address. - net.ipv4.addr(dev, addr, prefix); - - # Do SNAT for port forwardings when connections originate from the inside. - net.iptables.append("nat", "POSTROUTING", "-m", "connmark", "--mark", "0x4/0x4", "-j", "SNAT", "--to-source", addr, "--random"); - - main.depsc->provide("serverif"); -} - -template network_internet { - alias("_caller") main; - - # Some configuration. - var("enp2s0") pppoe_dev; - var("MISSING") pppoe_username; - var("MISSING") pppoe_password; - - # Wait for device, set up, wait for link. - net.backend.waitdevice(pppoe_dev); - net.up(pppoe_dev); - net.backend.waitlink(pppoe_dev); - - log("notice", "PPPoE started"); - log_r("notice", "PPPoE stopped"); - - # Start PPPoE. - call("pppoe", {pppoe_dev, pppoe_username, pppoe_password, "network_internet_pppoe_preup"}) pppoe; - - # Grab configuration. - var(pppoe.ifname) dev; - var(pppoe.local_ip) addr; - var(pppoe.remote_ip) remote_addr; - var(pppoe.dns_servers) dns_servers; - - to_string(dns_servers) dns_str; - log("notice", "PPPoE up dev=", dev, " local=", addr, " remote=", remote_addr, " dns=", dns_str); - log_r("notice", "PPPoE down"); - - # Add default route. - net.ipv4.route("0.0.0.0/0", remote_addr, "20", dev); - - main.depsc->provide("internet"); -} - -template network_internet_pppoe_preup { - alias("_arg0") dev; - alias("_arg1") addr; - alias("_arg2") remote_ip; - alias("_arg3") dns_servers; - - # Weak host model. - call("network_weak_hostmodel_rules", {dev, addr}); - - # Drop packets to this system, except some things. - net.iptables.newchain("filter", "INPUT_internet_drop"); - #net.iptables.append("filter", "INPUT_internet_drop", "-p", "tcp", "--dport", "22", "-j", "RETURN"); - net.iptables.append("filter", "INPUT_internet_drop", "-j", "DROP"); - net.iptables.append("filter", "INPUT", "-i", dev, "-j", "INPUT_internet_drop"); - - # Do SNAT for packets going out. - net.iptables.append("nat", "POSTROUTING", "-o", dev, "-j", "SNAT", "--to-source", addr, "--random"); - - # Do MMS clamping. - net.iptables.append("mangle", "OUTPUT", "-o", dev, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu"); - net.iptables.append("mangle", "FORWARD", "-o", dev, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu"); -} - -template network_lan_internet_rules { - alias("_caller") main; - main.depsc->depend({"lan"}) lan; - main.depsc->depend({"internet"}) internet; - - # Add exception to weak host model of internet interface. - call("network_weak_hostmodel_exception", {internet.dev, {"-i", lan.dev}}); - net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", lan.dev, "-o", internet.dev, "-j", "ACCEPT"); -} - -template network_serverif_internet_rules { - alias("_caller") main; - main.depsc->depend({"serverif"}) serverif; - main.depsc->depend({"internet"}) internet; - - # Allow traffic from LAN to Internet. - call("network_weak_hostmodel_exception", {internet.dev, {"-i", serverif.dev}}); - net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", serverif.dev, "-o", internet.dev, "-j", "ACCEPT"); -} - -template network_lan_serverif_rules { - alias("_caller") main; - main.depsc->depend({"lan"}) lan; - main.depsc->depend({"serverif"}) serverif; - - # Allow traffic from serverif to LAN. - call("network_weak_hostmodel_exception", {serverif.dev, {"-i", lan.dev}}); - net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", lan.dev, "-o", serverif.dev, "-j", "ACCEPT"); - - # Allow traffic from LAN to serverif. - call("network_weak_hostmodel_exception", {lan.dev, {"-i", serverif.dev}}); - net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", serverif.dev, "-o", lan.dev, "-j", "ACCEPT"); -} - -template network_lan_dhcp_server { - alias("_caller") main; - main.depsc->depend({"lan"}) lan; - - # Start DHCP server. - call("dhcp_server", {lan.addr, lan.prefix, lan.dhcp_start, lan.dhcp_end, {lan.addr}, {lan.addr}}); -} - -template network_unbound { - alias("_caller") main; - main.depsc->depend({"lan_config"}) lan_config; - main.depsc->depend({"serverif_config"}) serverif_config; - - # Add DNS servers. - net.dns({"127.0.0.1"}, "20"); - - # Build configuration. - ipv4_net_from_addr_and_prefix(lan_config.addr, lan_config.prefix) lan_network; - ipv4_net_from_addr_and_prefix(serverif_config.addr, serverif_config.prefix) serverif_network; - var({ - {lan_network, lan_config.prefix, "allow"}, - {serverif_network, serverif_config.prefix, "allow"} - }) access_control_rules; - - # Start Unbound. - call("unbound", {"lan", access_control_rules}); -} - -template network_port_forwarding { - alias("_caller") main; - - # Start forwarding. - call("port_forwarding", {"/var/lib/ncd-port-forwardings.ncdvalue", "network_port_forwarding_rules"}) pf; - - main.depsc->provide("port_forwarding"); -} - -template network_port_forwarding_rules { - alias("_caller.main") main; - alias("_arg0") protocol; - alias("_arg1") port_start; - alias("_arg2") port_end; - alias("_arg3") dest_addr; - - # Get access to lan and serverif configuration. - main.depsc->depend({"lan_config"}) lan; - main.depsc->depend({"serverif_config"}) serverif; - - # Wait for Internet interface. - main.depsc->depend({"internet"}) internet; - - # Build port range string. - concat(port_start, ":", port_end) port_range; - - # Add rules. - net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", lan.dev, "-j", "CONNMARK", "--set-xmark", "0x3/0x3"); - net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", serverif.dev, "-j", "CONNMARK", "--set-xmark", "0x5/0x5"); - net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", internet.dev, "-j", "CONNMARK", "--set-xmark", "0x1/0x1"); - net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-j", "DNAT", "--to-destination", dest_addr); -} - -template network_start_control_server { - alias("_caller") main; - main.depsc->depend({"lan_config"}) lan_config; - - # Start control server. - call("network_control_server", {"/run/ncd-control.socket", - "network_control_list_port_forwardings", - "network_control_add_port_forwarding", - "network_control_remove_port_forwarding"}); -} - -template network_control_list_port_forwardings { - alias("_caller.main") main; - - main.depsc->depend({"port_forwarding"}) port_forwarding; - var(port_forwarding.pf.map.keys) port_forwardings; -} - -template network_control_add_port_forwarding { - alias("_caller.main") main; - alias("_arg0") protocol; - alias("_arg1") port_start; - alias("_arg2") port_end; - alias("_arg3") dest_addr; - - var("") try_error_text; - try("network_verify_port_forwarding_try", {}) verify_try; - - If (verify_try.succeeded) { - main.depsc->depend({"port_forwarding"}) port_forwarding; - - call("port_forwarding_add", {"_caller.port_forwarding.pf", protocol, port_start, port_end, dest_addr}) call; - alias("call.succeeded") succeeded; - alias("call.error_text") error_text; - } Else { - var("false") succeeded; - alias("try_error_text") error_text; - } branch; - - alias("branch.succeeded") succeeded; - alias("branch.error_text") error_text; -} - -template network_control_remove_port_forwarding { - alias("_caller.main") main; - alias("_arg0") protocol; - alias("_arg1") port_start; - alias("_arg2") port_end; - alias("_arg3") dest_addr; - - main.depsc->depend({"port_forwarding"}) port_forwarding; - - call("port_forwarding_remove", {"_caller.port_forwarding.pf", protocol, port_start, port_end, dest_addr}) call; - alias("call.succeeded") succeeded; - alias("call.error_text") error_text; -} - -template network_verify_port_forwarding_try { - alias("_caller") c; - - c.main.depsc->depend({"lan_config"}) lan; - c.main.depsc->depend({"serverif_config"}) serverif; - - net.ipv4.addr_in_network(c.dest_addr, lan.addr, lan.prefix) in_lan; - net.ipv4.addr_in_network(c.dest_addr, serverif.addr, serverif.prefix) in_serverif; - - If (in_lan) { - print(); - } - Elif (in_serverif) { - print(); - } - Else { - c.try_error_text->set("Destination address does not belong to any permitted network."); - _try->assert("false"); - }; -} diff --git a/external/badvpn_dns/ncd/examples/router/network_control_server.ncdi b/external/badvpn_dns/ncd/examples/router/network_control_server.ncdi deleted file mode 100644 index e94f05e..0000000 --- a/external/badvpn_dns/ncd/examples/router/network_control_server.ncdi +++ /dev/null @@ -1,96 +0,0 @@ -include_guard "network_control_server" - -template network_control_server { - alias("_arg0") socket_path; - alias("_arg1") template_list_port_forwardings; - alias("_arg2") template_add_port_forwarding; - alias("_arg3") template_remove_port_forwarding; - - # Start request server. - sys.request_server({"unix", socket_path}, "network_control_server__request_handler", {}); -} - -template network_control_server__request_handler { - alias("_caller") server; - - value(_request.data) data; - - try("network_control_server__try", {}); - - _request->reply({"error", "Bad request."}); - _request->finish(); -} - -template network_control_server__try { - alias("_caller._request") request; - alias("_caller.server") server; - alias("_caller.data") data; - - val_equal(data.type, "list") a1; - _try->assert(a1); - - num_greater_equal(data.length, "1") a2; - _try->assert(a2); - - data->get("0") request_cmd; - - val_equal(request_cmd, "list-port-forwardings") is_list_port_forwardings; - val_equal(request_cmd, "add-port-forwarding") is_add_port_forwarding; - val_equal(request_cmd, "remove-port-forwarding") is_remove_port_forwarding; - or(is_add_port_forwarding, is_remove_port_forwarding) is_add_remove_port_forwarding; - - If (is_list_port_forwardings) { - num_equal(data.length, "1") a3; - _try->assert(a3); - - call_with_caller_target(server.template_list_port_forwardings, {}, "server._caller") call; - request->reply({"ok", call.port_forwardings}); - } - Elif (is_add_remove_port_forwarding) { - num_equal(data.length, "5") a4; - _try->assert(a4); - - data->get("1") req_protocol; - data->get("2") req_port_start; - data->get("3") req_port_end; - data->get("4") req_dest_addr; - - val_equal(req_protocol, "tcp") is_tcp; - val_equal(req_protocol, "udp") is_udp; - or(is_tcp, is_udp) a5; - _try->assert(a5); - - parse_number(req_port_start) port_start; - _try->assert(port_start.succeeded); - - parse_number(req_port_end) port_end; - _try->assert(port_end.succeeded); - - num_lesser_equal(port_start, port_end) a6; - _try->assert(a6); - - parse_ipv4_addr(req_dest_addr) dest_addr; - _try->assert(dest_addr.succeeded); - - If (is_add_port_forwarding) { - call_with_caller_target(server.template_add_port_forwarding, {req_protocol, port_start, port_end, dest_addr}, "server._caller") call; - If (call.succeeded) { - request->reply({"ok", "Port forwarding added."}); - } Else { - request->reply({"error", call.error_text}); - }; - } Else { - call_with_caller_target(server.template_remove_port_forwarding, {req_protocol, port_start, port_end, dest_addr}, "server._caller") call; - If (call.succeeded) { - request->reply({"ok", "Port forwarding removed."}); - } Else { - request->reply({"error", call.error_text}); - }; - }; - } - Else { - _try->assert("false"); - }; - - request->finish(); -} diff --git a/external/badvpn_dns/ncd/examples/router/port_forwarding.ncdi b/external/badvpn_dns/ncd/examples/router/port_forwarding.ncdi deleted file mode 100644 index 1ac727b..0000000 --- a/external/badvpn_dns/ncd/examples/router/port_forwarding.ncdi +++ /dev/null @@ -1,170 +0,0 @@ -include_guard "port_forwarding" - -template port_forwarding { - alias("_arg0") forwardings_file; - alias("_arg1") template_forward; - - # Map which holds the set of current port forwardings. - # Enties are: {protocol, port_start, port_end, dest_addr}:"" - value([]) map; - - # Blocker which is initially down and is toggled down-up - # whenever the forwarding change. - blocker() update_blocker; - - # Process manager, each forwarding has a port_forwarding__instance process. - # The process identifiers are the same as the keys in the map. - process_manager() mgr; - - # Spawn a process for dealing with storage of port forwardings on disk. - spawn("port_forwarding__stored", {}); -} - -template port_forwarding__instance { - alias("_caller") pf; - alias("_arg0") protocol; - alias("_arg1") port_start; - alias("_arg2") port_end; - alias("_arg3") dest_addr; - - log("notice", "adding port forwarding ", protocol, ":", port_start, ":", port_end, " to ", dest_addr); - log_r("notice", "removed port forwarding ", protocol, ":", port_start, ":", port_end, " to ", dest_addr); - - # Do the forwarding. - call_with_caller_target(pf.template_forward, {protocol, port_start, port_end, dest_addr}, "pf._caller"); -} - -template port_forwarding_add { - alias(_arg0) pf; - alias("_arg1") protocol; - alias("_arg2") port_start; - alias("_arg3") port_end; - alias("_arg4") dest_addr; - - var("false") succeeded; - var("") error_text; - var("true") not_finished; - backtrack_point() finished_point; - - If (not_finished) { - # Check for conflicts with existing forwardings. - Foreach (pf.map.keys As entry) { - value(entry) entry; - entry->get("0") e_protocol; - entry->get("1") e_port_start; - entry->get("2") e_port_end; - - val_different(protocol, e_protocol) different_protocol; - num_lesser(port_end, e_port_start) before; - num_greater(port_start, e_port_end) after; - or(different_protocol, before, after) no_conflict; - not(no_conflict) conflict; - - If (conflict) { - error_text->set("Port forwarding conflicts with an existing forwarding."); - not_finished->set("false"); - finished_point->go(); - }; - }; - - # Build entry key. - var({protocol, port_start, port_end, dest_addr}) key; - - # Insert to map and toggle blocker. - pf.map->insert(key, ""); - pf.update_blocker->downup(); - - # Start process. - pf.mgr->start(key, "port_forwarding__instance", {protocol, port_start, port_end, dest_addr}); - - succeeded->set("true"); - not_finished->set("false"); - finished_point->go(); - }; -} - -template port_forwarding_remove { - alias(_arg0) pf; - alias("_arg1") protocol; - alias("_arg2") port_start; - alias("_arg3") port_end; - alias("_arg4") dest_addr; - - var("false") succeeded; - var("") error_text; - var("true") not_finished; - backtrack_point() finished_point; - - If (not_finished) { - # Build entry key. - var({protocol, port_start, port_end, dest_addr}) key; - - # Check if the forwarding exists. - pf.map->try_get(key) entry; - not(entry.exists) does_not_exist; - If (does_not_exist) { - error_text->set("Port forwarding does not exist."); - not_finished->set("false"); - finished_point->go(); - }; - - # Stop process. - pf.mgr->stop(key); - - # Remove from map and toggle blocker. - pf.map->remove(key); - pf.update_blocker->downup(); - - succeeded->set("true"); - not_finished->set("false"); - finished_point->go(); - }; -} - -template port_forwarding__stored { - alias("_caller") pf; - - # Create file if it doesn't exist. - file_stat(pf.forwardings_file) stat; - If (stat.succeeded) { print(); } Else { - file_write(pf.forwardings_file, "{}\n"); - }; - - # Read port forwardings from file. - file_read(pf.forwardings_file) data; - from_string(data) forwardings; - - # Add them. - Foreach (forwardings As fwd) { - value(fwd) fwd; - fwd->get("0") protocol; - fwd->get("1") port_start; - fwd->get("2") port_end; - fwd->get("3") dest_addr; - call("port_forwarding_add", {"_caller.pf", protocol, port_start, port_end, dest_addr}); - }; - - # Write forwardings to file on exit. - imperative("<none>", {}, "port_forwarding__write", {}, "6000"); - - # Also write forwardings whenever they are changed. - pf.update_blocker->use(); - call("port_forwarding__write", {}); -} - -template port_forwarding__write { - alias("_caller.pf") pf; - - # Convert forwardings to string. - to_string(pf.map.keys) data; - concat(data, "\n") data; - - # Build name of temporary file. - concat(pf.forwardings_file, ".new") temp_file; - - # Write temporary file. - file_write(temp_file, data); - - # Move to live file. - runonce({"/bin/mv", temp_file, pf.forwardings_file}); -} diff --git a/external/badvpn_dns/ncd/examples/router/pppoe.ncdi b/external/badvpn_dns/ncd/examples/router/pppoe.ncdi deleted file mode 100644 index 676a8fe..0000000 --- a/external/badvpn_dns/ncd/examples/router/pppoe.ncdi +++ /dev/null @@ -1,296 +0,0 @@ -include_guard "pppoe" - -template pppoe { - alias("_arg0") dev; - alias("_arg1") username; - alias("_arg2") password; - alias("_arg3") pre_up_template; - - # Choose which NCD interpreter will be used for the pppd event scripts. - var("/usr/local/badvpn/bin/badvpn-ncd") ncd_interpreter_path; - - # Retry point here. - var("false") retrying; - backtrack_point() retry_point; - If (retrying) { - sleep("5000"); - }; - retrying->set("true"); - - # Create a temporary directory. - concat("/run/ncd-pppoe-", dev) run_dir; - run({"/bin/rm", "-rf", run_dir}, {}); - run({"/bin/mkdir", run_dir}, {"/bin/rm", "-rf", run_dir}); - - # Build paths for pppd scripts and other files. - concat(run_dir, "/ncd-request.socket") socket_path; - concat(run_dir, "/pppoe.pid") pppoe_pid_path; - concat(run_dir, "/pap-secrets") pap_secrets_path; - concat(run_dir, "/chap-secrets") chap_secrets_path; - concat(run_dir, "/pppd2.tdb") pppdb_path; - concat(run_dir, "/resolv.conf") resolv_conf_path; - concat(run_dir, "/script-auth-up") path_auth_up; - concat(run_dir, "/script-auth-down") path_auth_down; - concat(run_dir, "/script-auth-fail") path_auth_fail; - concat(run_dir, "/script-ip-pre-up") path_ip_pre_up; - concat(run_dir, "/script-ip-up") path_ip_up; - concat(run_dir, "/script-ip-down") path_ip_down; - concat(run_dir, "/script-ipv6-up") path_ipv6_up; - concat(run_dir, "/script-ipv6-down") path_ipv6_down; - concat(run_dir, "/script-ipx-up") path_ipx_up; - concat(run_dir, "/script-ipx-down") path_ipx_down; - - # Write secrets files. - call("pppoe__write_secrets", {pap_secrets_path, username, password}); - call("pppoe__write_secrets", {chap_secrets_path, username, password}); - - # Write pppd scripts. These will contact us via the request socket. - call("pppoe__write_script", {"ip-pre-up", path_ip_pre_up}); - call("pppoe__write_script", {"ip-up", path_ip_up}); - call("pppoe__write_script", {"ip-down", path_ip_down}); - - # Build path arguments for pppd; - concat("pid-dir=", run_dir) arg_pid_dir; - concat("pap-secrets=", pap_secrets_path) arg_pap_secrets; - concat("chap-secrets=", chap_secrets_path) arg_chap_secrets; - concat("pppdb=", pppdb_path) arg_pppdb; - concat("resolv.conf=", resolv_conf_path) arg_resolv_conf; - concat("auth-up=", path_auth_up) arg_auth_up; - concat("auth-down=", path_auth_down) arg_auth_down; - concat("auth-fail=", path_auth_fail) arg_auth_fail; - concat("ip-pre-up=", path_ip_pre_up) arg_ip_pre_up; - concat("ip-up=", path_ip_up) arg_ip_up; - concat("ip-down=", path_ip_down) arg_ip_down; - concat("ipv6-up=", path_ipv6_up) arg_ipv6_up; - concat("ipv6-down=", path_ipv6_down) arg_ipv6_down; - concat("ipx-up=", path_ipx_up) arg_ipx_up; - concat("ipx-down=", path_ipx_down) arg_ipx_down; - - # Create state variables and blockers. When the request server - # receives requests it will update those variables and blockers. - var("down") state; - var("") current_ifname; - var("") current_local_ip; - var("") current_remote_ip; - value({}) current_dns_servers; - blocker() ip_pre_up_blocker; - blocker() ip_pre_up_done_blocker; - blocker() ip_up_blocker; - - # Start request server. - sys.request_server({"unix", socket_path}, "pppoe__request_handler", {}); - - # Start pppd. - sys.start_process({ - "/usr/sbin/pppd", "nodetach", "plugin", "rp-pppoe.so", dev, "noipdefault", "hide-password", - "usepeerdns", "user", username, - "path", arg_pid_dir, "path", arg_pap_secrets, "path", arg_chap_secrets, "path", arg_pppdb, - "path", arg_resolv_conf, - "path", arg_auth_up, "path", arg_auth_down, "path", arg_auth_fail, "path", arg_ip_pre_up, - "path", arg_ip_up, "path", arg_ip_down, "path", arg_ipv6_up, "path", arg_ipv6_down, - "path", arg_ipx_up, "path", arg_ipx_down - }, "", ["deinit_kill_time":"2000"]) pppd; - - # Start a process which will cause retrying when pppd dies. - spawn("pppoe__pppd_wait", {}); - - # Wait for ip-pre-up. - ip_pre_up_blocker->use(); - - # Grab the current state variables, so the user doesn't - # see any unexpected changes. - var(current_ifname) ifname; - var(current_local_ip) local_ip; - var(current_remote_ip) remote_ip; - var(current_dns_servers) dns_servers; - - # Call pre-up callback template. - call_with_caller_target(pre_up_template, {ifname, local_ip, remote_ip, dns_servers}, "_caller"); - - # Allow pre-up script to terminate. - ip_pre_up_done_blocker->up(); - - # Wait for connection to go up. - ip_up_blocker->use(); -} - -template pppoe__pppd_wait { - # Wait for pppd to die. - _caller.pppd->wait(); - - # Retry. - _caller.retry_point->go(); -} - -template pppoe__write_secrets { - alias("_arg0") file_path; - alias("_arg1") username; - alias("_arg2") password; - - # Escape username and password. - regex_replace(username, {"""}, {"\""}) username_esc; - regex_replace(password, {"""}, {"\""}) password_esc; - - # Write empty file and chmod it. - file_write(file_path, ""); - run({"/bin/chmod", "600", file_path}, {}); - - # Build contents. - concat(""", username_esc, "" * "", password_esc, ""\n") contents; - - # Write file. - file_write(file_path, contents); -} - -template pppoe__write_script { - alias("_arg0") event; - alias("_arg1") script_path; - - # This string is an NCD script which will be run by pppd. - # When run, it will contact us via the request server, - # and the requests will be processed in pppoe__request_handler. - var("#!<NCD_INTERPRETER_PATH> - -process main { - # Hardcoded strings. - var("<EVENT>") hardcoded_event; - var("<SOCKET>") hardcoded_socket; - - # Start timeout to kill us after some time if we don't manage - # to contact the server. - spawn("timeout_process", {}); - - # Build event data map. - getargs() args; - value(["EVENT":hardcoded_event, "ARGS":args]) msg_map; - var({"DEVICE", "IFNAME", "IPLOCAL", "IPREMOTE", "PEERNAME", "LOCALNAME", - "SPEED", "ORIG_UID", "PPPLOGNAME", "CONNECT_TIME", "BYTES_SENT", - "BYTES_RCVD", "LINKNAME", "DNS1", "DNS2", "WINS1", "WINS2"}) var_names; - Foreach (var_names As var_name) { - getenv(var_name) env; - If (env.exists) { - msg_map->insert(var_name, env); - }; - }; - - # Connect to socket. - sys.request_client({"unix", hardcoded_socket}) client; - - # Send request. - client->request(msg_map, "reply_handler", "finished_handler", {}); -} - -template reply_handler { - print(); -} - -template finished_handler { - # Request was received by server, exit now. - exit("0"); -} - -template timeout_process { - # Sleep some time. - sleep("5000"); - # Timed out, exit now. - exit("1"); -} - -" ) script_contents_template; - - # Replace some constants in the script with the right values. - regex_replace(script_contents_template, - {"<NCD_INTERPRETER_PATH>", "<EVENT>", "<SOCKET>"}, - {_caller.ncd_interpreter_path, event, _caller.socket_path} - ) script_contents; - - # Write the script. - file_write(script_path, script_contents); - - # Make it executable. - run({"/bin/chmod", "+x", script_path}, {}); -} - -template pppoe__request_handler { - alias("_caller") pppoe; - - # Get event type from request. - value(_request.data) request; - request->get("EVENT") event; - - # Match to known types. - val_equal(event, "ip-down") is_ip_down; - val_equal(event, "ip-pre-up") is_ip_pre_up; - val_equal(event, "ip-up") is_ip_up; - - If (is_ip_down) { - # Set state. - pppoe.state->set("down"); - - # Set blockers down. - pppoe.ip_up_blocker->down(); - pppoe.ip_pre_up_done_blocker->down(); - pppoe.ip_pre_up_blocker->down(); - } - Elif (is_ip_pre_up) { - # Expecting to be in "down" state here. - val_different(pppoe.state, "down") state_is_wrong; - If (state_is_wrong) { - pppoe.retry_point->go(); - _request->finish(); - }; - - # Get variables from request. - request->get("IFNAME") ifname; - request->get("IPLOCAL") local_ip; - request->get("IPREMOTE") remote_ip; - request->try_get("DNS1") dns1; - request->try_get("DNS2") dns2; - - # Write variables. - pppoe.current_ifname->set(ifname); - pppoe.current_local_ip->set(local_ip); - pppoe.current_remote_ip->set(remote_ip); - pppoe.current_dns_servers->reset({}); - If (dns1.exists) { - pppoe.current_dns_servers->insert(pppoe.current_dns_servers.length, dns1); - }; - If (dns2.exists) { - pppoe.current_dns_servers->insert(pppoe.current_dns_servers.length, dns2); - }; - - # Set state. - pppoe.state->set("pre-up"); - - # Set ip-pre-up blocker up. - pppoe.ip_pre_up_blocker->up(); - - # Wait for pre-up to be finished. This causes the script contacting - # us to not return until then, and effectively delays pppd in setting - # the device up and calling the ip-up script. - pppoe.ip_pre_up_done_blocker->use(); - } - Elif(is_ip_up) { - # Expecting to be in "pre-up" state here. - val_different(pppoe.state, "pre-up") state_is_wrong; - If (state_is_wrong) { - pppoe.retry_point->go(); - _request->finish(); - }; - - # Set state. - pppoe.state->set("up"); - - # Set ip-up blocker up. - pppoe.ip_up_blocker->up(); - }; - - # Finish request. - _request->finish(); -} - -template pppoe__escapeshellarg { - alias("_arg0") input; - regex_replace(input, {"'"}, {"\'"}) replaced; - concat("'", replaced, "'") result; -} diff --git a/external/badvpn_dns/ncd/examples/router/remove-port-forwarding b/external/badvpn_dns/ncd/examples/router/remove-port-forwarding deleted file mode 100644 index 6019404..0000000 --- a/external/badvpn_dns/ncd/examples/router/remove-port-forwarding +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/badvpn-ncd - -process main { - getargs() args; - value(args) args; - - num_different(args.length, "4") bad_args; - If (bad_args) { - println("Usage: remove-port-forwarding <protocol> <port_start> <port_end> <dest_addr>"); - exit("1"); - }; - - args->get("0") protocol; - args->get("1") port_start; - args->get("2") port_end; - args->get("3") dest_addr; - - var("0") exit_status; - - sys.request_client({"unix", "/run/ncd-control.socket"}) client; - - var({"remove-port-forwarding", protocol, port_start, port_end, dest_addr}) request_data; - - client->request(request_data, "reply_handler", "finished_handler", {}); -} - -template reply_handler { - value(_reply.data) reply_data; - reply_data->get("0") status; - reply_data->get("1") text; - - val_equal(status, "ok") is_ok; - If (is_ok) { - println(text); - } Else { - _caller.exit_status->set("1"); - println("Error: ", text); - }; -} - -template finished_handler { - exit(_caller.exit_status); -} diff --git a/external/badvpn_dns/ncd/examples/router/unbound.ncdi b/external/badvpn_dns/ncd/examples/router/unbound.ncdi deleted file mode 100644 index 9ea0d41..0000000 --- a/external/badvpn_dns/ncd/examples/router/unbound.ncdi +++ /dev/null @@ -1,42 +0,0 @@ -include_guard "unbound" - -template unbound { - alias("_arg0") unique_id; - alias("_arg1") access_control_rules; - - # Create a temporary directory. - concat("/run/ncd-unbound-", unique_id) run_dir; - run({"/bin/rm", "-rf", run_dir}, {}); - run({"/bin/mkdir", run_dir}, {"/bin/rm", "-rf", run_dir}); - - # Compute path for unbound.conf. - concat(run_dir, "/unbound.conf") unbound_conf_path; - - # This is a template for unbound.conf. - value(" -server: - verbosity: 1 - do-ip4: yes - do-ip6: no - do-udp: yes - do-tcp: no - interface: 0.0.0.0 - access-control: 127.0.0.0/8 allow -" ) config; - - # Append access control rules. - Foreach (access_control_rules As rule) { - value(rule) rule; - rule->get("0") network; - rule->get("1") prefix; - rule->get("2") action; - concat(" access-control: ", network, "/", prefix, " ", action, "\n") line; - config->append(line); - }; - - # Write unbound.conf. - file_write(unbound_conf_path, config); - - # Start unbound. - daemon({"/usr/sbin/unbound", "-d", "-c", unbound_conf_path}); -} diff --git a/external/badvpn_dns/ncd/examples/tcp_echo_client.ncd b/external/badvpn_dns/ncd/examples/tcp_echo_client.ncd deleted file mode 100644 index 47dd999..0000000 --- a/external/badvpn_dns/ncd/examples/tcp_echo_client.ncd +++ /dev/null @@ -1,35 +0,0 @@ -process main { - getargs() args; - value(args) args; - - num_different(args.length, "2") bad_args; - If (bad_args) { - println("bad arguments"); - exit("1"); - }; - - args->get("0") addr_ip; - args->get("1") addr_port; - - sys.connect({"tcp", {"ipv4", addr_ip, addr_port}}) socket; - If (socket.is_error) { - println("connection error!"); - exit("1"); - }; - - println("connected"); - - socket->write("This echo client is implemented in NCD!\n\n"); - - backtrack_point() recv_point; - - socket->read() data; - If (data.not_eof) { - socket->write(data); - recv_point->go(); - }; - - println("server disconnected"); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/examples/tcp_echo_server.ncd b/external/badvpn_dns/ncd/examples/tcp_echo_server.ncd deleted file mode 100644 index a3c6267..0000000 --- a/external/badvpn_dns/ncd/examples/tcp_echo_server.ncd +++ /dev/null @@ -1,40 +0,0 @@ -process main { - getargs() args; - value(args) args; - - num_different(args.length, "2") bad_args; - If (bad_args) { - println("bad arguments"); - exit("1"); - }; - - args->get("0") addr_ip; - args->get("1") addr_port; - - sys.listen({"tcp", {"ipv4", addr_ip, addr_port}}, "client_handler", {}) listener; - If (listener.is_error) { - println("failed to listen"); - exit("1"); - }; - - println("listening"); -} - -template client_handler { - to_string(_socket.client_addr) addr_str; - - println("client ", addr_str, ": connected"); - rprintln("client ", addr_str, ": disconnected"); - - _socket->write("This echo server is implemented in NCD!\n\n"); - - backtrack_point() recv_point; - - _socket->read() data; - If (data.not_eof) { - _socket->write(data); - recv_point->go(); - }; - - _socket->close(); -} diff --git a/external/badvpn_dns/ncd/extra/BEventLock.c b/external/badvpn_dns/ncd/extra/BEventLock.c deleted file mode 100644 index e65bd20..0000000 --- a/external/badvpn_dns/ncd/extra/BEventLock.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file BEventLock.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/offset.h> - -#include "BEventLock.h" - -static void exec_job_handler (BEventLock *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->jobs)) - DebugObject_Access(&o->d_obj); - - // get job - BEventLockJob *j = UPPER_OBJECT(LinkedList1_GetFirst(&o->jobs), BEventLockJob, pending_node); - ASSERT(j->pending) - - // call handler - j->handler(j->user); - return; -} - -void BEventLock_Init (BEventLock *o, BPendingGroup *pg) -{ - // init jobs list - LinkedList1_Init(&o->jobs); - - // init exec job - BPending_Init(&o->exec_job, pg, (BPending_handler)exec_job_handler, o); - - DebugObject_Init(&o->d_obj); - DebugCounter_Init(&o->pending_ctr); -} - -void BEventLock_Free (BEventLock *o) -{ - ASSERT(LinkedList1_IsEmpty(&o->jobs)) - DebugCounter_Free(&o->pending_ctr); - DebugObject_Free(&o->d_obj); - - // free exec jobs - BPending_Free(&o->exec_job); -} - -void BEventLockJob_Init (BEventLockJob *o, BEventLock *l, BEventLock_handler handler, void *user) -{ - // init arguments - o->l = l; - o->handler = handler; - o->user = user; - - // set not pending - o->pending = 0; - - DebugObject_Init(&o->d_obj); - DebugCounter_Increment(&l->pending_ctr); -} - -void BEventLockJob_Free (BEventLockJob *o) -{ - BEventLock *l = o->l; - - DebugCounter_Decrement(&l->pending_ctr); - DebugObject_Free(&o->d_obj); - - if (o->pending) { - int was_first = (&o->pending_node == LinkedList1_GetFirst(&l->jobs)); - - // remove from jobs list - LinkedList1_Remove(&l->jobs, &o->pending_node); - - // schedule/unschedule job - if (was_first) { - if (LinkedList1_IsEmpty(&l->jobs)) { - BPending_Unset(&l->exec_job); - } else { - BPending_Set(&l->exec_job); - } - } - } -} - -void BEventLockJob_Wait (BEventLockJob *o) -{ - BEventLock *l = o->l; - ASSERT(!o->pending) - - // append to jobs - LinkedList1_Append(&l->jobs, &o->pending_node); - - // set pending - o->pending = 1; - - // schedule next job if needed - if (&o->pending_node == LinkedList1_GetFirst(&l->jobs)) { - BPending_Set(&l->exec_job); - } -} - -void BEventLockJob_Release (BEventLockJob *o) -{ - BEventLock *l = o->l; - ASSERT(o->pending) - - int was_first = (&o->pending_node == LinkedList1_GetFirst(&l->jobs)); - - // remove from jobs list - LinkedList1_Remove(&l->jobs, &o->pending_node); - - // set not pending - o->pending = 0; - - // schedule/unschedule job - if (was_first) { - if (LinkedList1_IsEmpty(&l->jobs)) { - BPending_Unset(&l->exec_job); - } else { - BPending_Set(&l->exec_job); - } - } -} diff --git a/external/badvpn_dns/ncd/extra/BEventLock.h b/external/badvpn_dns/ncd/extra/BEventLock.h deleted file mode 100644 index 2664318..0000000 --- a/external/badvpn_dns/ncd/extra/BEventLock.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file BEventLock.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A FIFO lock for events using the job queue ({@link BPending}). - */ - -#ifndef BADVPN_BEVENTLOCK_H -#define BADVPN_BEVENTLOCK_H - -#include <misc/debugcounter.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <base/BPending.h> - -/** - * Event context handler called when the lock job has acquired the lock - * after requesting the lock with {@link BEventLockJob_Wait}. - * The object was in waiting state. - * The object enters locked state before the handler is called. - * - * @param user as in {@link BEventLockJob_Init} - */ -typedef void (*BEventLock_handler) (void *user); - -/** - * A FIFO lock for events using the job queue ({@link BPending}). - */ -typedef struct { - LinkedList1 jobs; - BPending exec_job; - DebugObject d_obj; - DebugCounter pending_ctr; -} BEventLock; - -/** - * An object that can request a {@link BEventLock} lock. - */ -typedef struct { - BEventLock *l; - BEventLock_handler handler; - void *user; - int pending; - LinkedList1Node pending_node; - DebugObject d_obj; -} BEventLockJob; - -/** - * Initializes the object. - * - * @param o the object - * @param pg pending group - */ -void BEventLock_Init (BEventLock *o, BPendingGroup *pg); - -/** - * Frees the object. - * There must be no {@link BEventLockJob} objects using this lock - * (regardless of their state). - * - * @param o the object - */ -void BEventLock_Free (BEventLock *o); - -/** - * Initializes the object. - * The object is initialized in idle state. - * - * @param o the object - * @param l the lock - * @param handler handler to call when the lock is aquired - * @param user value to pass to handler - */ -void BEventLockJob_Init (BEventLockJob *o, BEventLock *l, BEventLock_handler handler, void *user); - -/** - * Frees the object. - * - * @param o the object - */ -void BEventLockJob_Free (BEventLockJob *o); - -/** - * Requests the lock. - * The object must be in idle state. - * The object enters waiting state. - * - * @param o the object - */ -void BEventLockJob_Wait (BEventLockJob *o); - -/** - * Aborts the lock request or releases the lock. - * The object must be in waiting or locked state. - * The object enters idle state. - * - * @param o the object - */ -void BEventLockJob_Release (BEventLockJob *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDBProcessOpts.c b/external/badvpn_dns/ncd/extra/NCDBProcessOpts.c deleted file mode 100644 index 2af4beb..0000000 --- a/external/badvpn_dns/ncd/extra/NCDBProcessOpts.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file NCDBProcessOpts.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/balloc.h> - -#include <ncd/extra/value_utils.h> - -#include "NCDBProcessOpts.h" - -int NCDBProcessOpts_Init (NCDBProcessOpts *o, NCDValRef opts_arg, NCDBProcessOpts_func_unknown func_unknown, void *func_unknown_user, NCDModuleInst *i, int blog_channel) -{ - return NCDBProcessOpts_Init2(o, opts_arg, func_unknown, func_unknown_user, i, blog_channel, NULL, NULL); -} - -int NCDBProcessOpts_Init2 (NCDBProcessOpts *o, NCDValRef opts_arg, NCDBProcessOpts_func_unknown func_unknown, void *func_unknown_user, NCDModuleInst *i, int blog_channel, - int *out_keep_stdout, int *out_keep_stderr) -{ - if (!NCDVal_IsInvalid(opts_arg) && !NCDVal_IsMap(opts_arg)) { - NCDModuleInst_Backend_Log(i, blog_channel, BLOG_ERROR, "options must be a map"); - goto fail0; - } - - o->username = NULL; - o->do_setsid = 0; - - int keep_stdout = 0; - int keep_stderr = 0; - - if (!NCDVal_IsInvalid(opts_arg)) { - for (NCDValMapElem me = NCDVal_MapFirst(opts_arg); !NCDVal_MapElemInvalid(me); me = NCDVal_MapNext(opts_arg, me)) { - NCDValRef key = NCDVal_MapElemKey(opts_arg, me); - NCDValRef val = NCDVal_MapElemVal(opts_arg, me); - - if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "keep_stdout")) { - keep_stdout = ncd_read_boolean(val); - } - else if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "keep_stderr")) { - keep_stderr = ncd_read_boolean(val); - } - else if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "do_setsid")) { - o->do_setsid = ncd_read_boolean(val); - } - else if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "username")) { - if (!NCDVal_IsStringNoNulls(val)) { - NCDModuleInst_Backend_Log(i, blog_channel, BLOG_ERROR, "username must be a string without nulls"); - goto fail1; - } - b_cstring cstr = NCDVal_StringCstring(val); - o->username = b_cstring_strdup(cstr, 0, cstr.length); - if (!o->username) { - NCDModuleInst_Backend_Log(i, blog_channel, BLOG_ERROR, "b_cstring_strdup failed"); - goto fail1; - } - } - else { - if (!func_unknown || !func_unknown(func_unknown_user, key, val)) { - NCDModuleInst_Backend_Log(i, blog_channel, BLOG_ERROR, "unknown option"); - goto fail1; - } - } - } - } - - o->nfds = 0; - if (keep_stdout) { - o->fds[o->nfds] = 1; - o->fds_map[o->nfds++] = 1; - } - if (keep_stderr) { - o->fds[o->nfds] = 2; - o->fds_map[o->nfds++] = 2; - } - o->fds[o->nfds] = -1; - - if (out_keep_stdout) { - *out_keep_stdout = keep_stdout; - } - if (out_keep_stderr) { - *out_keep_stderr = keep_stderr; - } - - return 1; - -fail1: - if (o->username) { - BFree(o->username); - } -fail0: - return 0; -} - -void NCDBProcessOpts_InitOld (NCDBProcessOpts *o, int keep_stdout, int keep_stderr, int do_setsid) -{ - o->username = NULL; - o->do_setsid = do_setsid; - - o->nfds = 0; - if (keep_stdout) { - o->fds[o->nfds] = 1; - o->fds_map[o->nfds++] = 1; - } - if (keep_stderr) { - o->fds[o->nfds] = 2; - o->fds_map[o->nfds++] = 2; - } - o->fds[o->nfds] = -1; -} - -void NCDBProcessOpts_Free (NCDBProcessOpts *o) -{ - if (o->username) { - BFree(o->username); - } -} - -struct BProcess_params NCDBProcessOpts_GetParams (NCDBProcessOpts *o) -{ - struct BProcess_params params; - - params.username = o->username; - params.fds = o->fds; - params.fds_map = o->fds_map; - params.do_setsid = o->do_setsid; - - return params; -} diff --git a/external/badvpn_dns/ncd/extra/NCDBProcessOpts.h b/external/badvpn_dns/ncd/extra/NCDBProcessOpts.h deleted file mode 100644 index 9a9a79c..0000000 --- a/external/badvpn_dns/ncd/extra/NCDBProcessOpts.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file NCDBProcessOpts.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_BPROCESS_OPTS_H -#define NCD_BPROCESS_OPTS_H - -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <system/BProcess.h> - -typedef struct { - char *username; - int do_setsid; - int fds[3]; - int fds_map[2]; - int nfds; -} NCDBProcessOpts; - -typedef int (*NCDBProcessOpts_func_unknown) (void *user, NCDValRef key, NCDValRef val); - -int NCDBProcessOpts_Init (NCDBProcessOpts *o, NCDValRef opts_arg, NCDBProcessOpts_func_unknown func_unknown, void *func_unknown_user, NCDModuleInst *i, int blog_channel) WARN_UNUSED; -int NCDBProcessOpts_Init2 (NCDBProcessOpts *o, NCDValRef opts_arg, NCDBProcessOpts_func_unknown func_unknown, void *func_unknown_user, NCDModuleInst *i, int blog_channel, - int *out_keep_stdout, int *out_keep_stderr) WARN_UNUSED; -void NCDBProcessOpts_InitOld (NCDBProcessOpts *o, int keep_stdout, int keep_stderr, int do_setsid); -void NCDBProcessOpts_Free (NCDBProcessOpts *o); -struct BProcess_params NCDBProcessOpts_GetParams (NCDBProcessOpts *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDBuf.c b/external/badvpn_dns/ncd/extra/NCDBuf.c deleted file mode 100644 index 6262652..0000000 --- a/external/badvpn_dns/ncd/extra/NCDBuf.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file NCDBuf.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "NCDBuf.h" - -#include <misc/balloc.h> -#include <misc/offset.h> -#include <misc/debug.h> - -static void ref_target_func_release (BRefTarget *ref_target) -{ - NCDBuf *o = UPPER_OBJECT(ref_target, NCDBuf, ref_target); - NCDBufStore *store = o->store; - - if (store) { - LinkedList0_Remove(&store->used_bufs_list, &o->list_node); - LinkedList0_Prepend(&store->free_bufs_list, &o->list_node); - } else { - BFree(o); - } -} - -void NCDBufStore_Init (NCDBufStore *o, size_t buf_size) -{ - o->buf_size = buf_size; - LinkedList0_Init(&o->used_bufs_list); - LinkedList0_Init(&o->free_bufs_list); - - DebugObject_Init(&o->d_obj); -} - -void NCDBufStore_Free (NCDBufStore *o) -{ - DebugObject_Free(&o->d_obj); - - LinkedList0Node *ln; - - ln = LinkedList0_GetFirst(&o->used_bufs_list); - while (ln) { - NCDBuf *buf = UPPER_OBJECT(ln, NCDBuf, list_node); - ASSERT(buf->store == o) - buf->store = NULL; - ln = LinkedList0Node_Next(ln); - } - - ln = LinkedList0_GetFirst(&o->free_bufs_list); - while (ln) { - LinkedList0Node *next_ln = LinkedList0Node_Next(ln); - NCDBuf *buf = UPPER_OBJECT(ln, NCDBuf, list_node); - ASSERT(buf->store == o) - BFree(buf); - ln = next_ln; - } -} - -size_t NCDBufStore_BufSize (NCDBufStore *o) -{ - DebugObject_Access(&o->d_obj); - - return o->buf_size; -} - -NCDBuf * NCDBufStore_GetBuf (NCDBufStore *o) -{ - DebugObject_Access(&o->d_obj); - - NCDBuf *buf; - - LinkedList0Node *ln = LinkedList0_GetFirst(&o->free_bufs_list); - if (ln) { - buf = UPPER_OBJECT(ln, NCDBuf, list_node); - ASSERT(buf->store == o) - LinkedList0_Remove(&o->free_bufs_list, &buf->list_node); - } else { - bsize_t size = bsize_add(bsize_fromsize(sizeof(NCDBuf)), bsize_fromsize(o->buf_size)); - buf = BAllocSize(size); - if (!buf) { - return NULL; - } - buf->store = o; - } - - LinkedList0_Prepend(&o->used_bufs_list, &buf->list_node); - BRefTarget_Init(&buf->ref_target, ref_target_func_release); - - return buf; -} - -BRefTarget * NCDBuf_RefTarget (NCDBuf *o) -{ - return &o->ref_target; -} - -char * NCDBuf_Data (NCDBuf *o) -{ - return o->data; -} diff --git a/external/badvpn_dns/ncd/extra/NCDBuf.h b/external/badvpn_dns/ncd/extra/NCDBuf.h deleted file mode 100644 index 8542dcd..0000000 --- a/external/badvpn_dns/ncd/extra/NCDBuf.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file NCDBuf.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_NCDBUF_H -#define NCD_NCDBUF_H - -#include <stddef.h> - -#include <misc/BRefTarget.h> -#include <structure/LinkedList0.h> -#include <base/DebugObject.h> - -typedef struct { - size_t buf_size; - LinkedList0 used_bufs_list; - LinkedList0 free_bufs_list; - DebugObject d_obj; -} NCDBufStore; - -typedef struct { - NCDBufStore *store; - LinkedList0Node list_node; - BRefTarget ref_target; - char data[]; -} NCDBuf; - -void NCDBufStore_Init (NCDBufStore *o, size_t buf_size); -void NCDBufStore_Free (NCDBufStore *o); -size_t NCDBufStore_BufSize (NCDBufStore *o); -NCDBuf * NCDBufStore_GetBuf (NCDBufStore *o); - -BRefTarget * NCDBuf_RefTarget (NCDBuf *o); -char * NCDBuf_Data (NCDBuf *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDIfConfig.c b/external/badvpn_dns/ncd/extra/NCDIfConfig.c deleted file mode 100644 index 2d89d5d..0000000 --- a/external/badvpn_dns/ncd/extra/NCDIfConfig.c +++ /dev/null @@ -1,483 +0,0 @@ -/** - * @file NCDIfConfig.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <inttypes.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <linux/if_tun.h> -#include <pwd.h> - -#include <misc/debug.h> -#include <base/BLog.h> - -#include "NCDIfConfig.h" - -#include <generated/blog_channel_NCDIfConfig.h> - -#define IP_CMD "ip" -#define MODPROBE_CMD "modprobe" -#define RESOLVCONF_FILE "/etc/resolv.conf" -#define RESOLVCONF_TEMP_FILE "/etc/resolv.conf-ncd-temp" -#define TUN_DEVNODE "/dev/net/tun" - -static int run_command (const char *cmd) -{ - BLog(BLOG_INFO, "run: %s", cmd); - - return system(cmd); -} - -static int write_to_file (uint8_t *data, size_t data_len, FILE *f) -{ - while (data_len > 0) { - size_t bytes = fwrite(data, 1, data_len, f); - if (bytes == 0) { - return 0; - } - data += bytes; - data_len -= bytes; - } - - return 1; -} - -int NCDIfConfig_query (const char *ifname) -{ - struct ifreq ifr; - - int flags = 0; - - int s = socket(AF_INET, SOCK_DGRAM, 0); - if (!s) { - BLog(BLOG_ERROR, "socket failed"); - goto fail0; - } - - memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname); - if (ioctl(s, SIOCGIFFLAGS, &ifr)) { - BLog(BLOG_ERROR, "SIOCGIFFLAGS failed"); - goto fail1; - } - - flags |= NCDIFCONFIG_FLAG_EXISTS; - - if ((ifr.ifr_flags&IFF_UP)) { - flags |= NCDIFCONFIG_FLAG_UP; - - if ((ifr.ifr_flags&IFF_RUNNING)) { - flags |= NCDIFCONFIG_FLAG_RUNNING; - } - } - -fail1: - close(s); -fail0: - return flags; -} - -int NCDIfConfig_set_up (const char *ifname) -{ - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - char cmd[50 + IFNAMSIZ]; - sprintf(cmd, IP_CMD" link set %s up", ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_set_down (const char *ifname) -{ - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - char cmd[50 + IFNAMSIZ]; - sprintf(cmd, IP_CMD" link set %s down", ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr) -{ - ASSERT(ifaddr.prefix >= 0) - ASSERT(ifaddr.prefix <= 32) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - uint8_t *addr = (uint8_t *)&ifaddr.addr; - - char cmd[50 + IFNAMSIZ]; - sprintf(cmd, IP_CMD" addr add %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d dev %s", addr[0], addr[1], addr[2], addr[3], ifaddr.prefix, ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_remove_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr) -{ - ASSERT(ifaddr.prefix >= 0) - ASSERT(ifaddr.prefix <= 32) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - uint8_t *addr = (uint8_t *)&ifaddr.addr; - - char cmd[50 + IFNAMSIZ]; - sprintf(cmd, IP_CMD" addr del %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d dev %s", addr[0], addr[1], addr[2], addr[3], ifaddr.prefix, ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv6_addr (const char *ifname, struct ipv6_ifaddr ifaddr) -{ - ASSERT(ifaddr.prefix >= 0) - ASSERT(ifaddr.prefix <= 128) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - char addr_str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(ifaddr.addr, addr_str); - - char cmd[40 + IPADDR6_PRINT_MAX + IFNAMSIZ]; - sprintf(cmd, IP_CMD" addr add %s/%d dev %s", addr_str, ifaddr.prefix, ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_remove_ipv6_addr (const char *ifname, struct ipv6_ifaddr ifaddr) -{ - ASSERT(ifaddr.prefix >= 0) - ASSERT(ifaddr.prefix <= 128) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - char addr_str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(ifaddr.addr, addr_str); - - char cmd[40 + IPADDR6_PRINT_MAX + IFNAMSIZ]; - sprintf(cmd, IP_CMD" addr del %s/%d dev %s", addr_str, ifaddr.prefix, ifname); - - return !run_command(cmd); -} - -static int route_cmd (const char *cmdtype, struct ipv4_ifaddr dest, const uint32_t *gateway, int metric, const char *ifname) -{ - ASSERT(!strcmp(cmdtype, "add") || !strcmp(cmdtype, "del")) - ASSERT(dest.prefix >= 0) - ASSERT(dest.prefix <= 32) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - uint8_t *d_addr = (uint8_t *)&dest.addr; - - char gwstr[30]; - if (gateway) { - const uint8_t *g_addr = (uint8_t *)gateway; - sprintf(gwstr, " via %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, g_addr[0], g_addr[1], g_addr[2], g_addr[3]); - } else { - gwstr[0] = '\0'; - } - - char cmd[120 + IFNAMSIZ]; - sprintf(cmd, IP_CMD" route %s %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d%s metric %d dev %s", - cmdtype, d_addr[0], d_addr[1], d_addr[2], d_addr[3], dest.prefix, gwstr, metric, ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv4_route (struct ipv4_ifaddr dest, const uint32_t *gateway, int metric, const char *device) -{ - return route_cmd("add", dest, gateway, metric, device); -} - -int NCDIfConfig_remove_ipv4_route (struct ipv4_ifaddr dest, const uint32_t *gateway, int metric, const char *device) -{ - return route_cmd("del", dest, gateway, metric, device); -} - -static int route_cmd6 (const char *cmdtype, struct ipv6_ifaddr dest, const struct ipv6_addr *gateway, int metric, const char *ifname) -{ - ASSERT(!strcmp(cmdtype, "add") || !strcmp(cmdtype, "del")) - ASSERT(dest.prefix >= 0) - ASSERT(dest.prefix <= 128) - - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return 0; - } - - char dest_str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(dest.addr, dest_str); - - char gwstr[10 + IPADDR6_PRINT_MAX]; - if (gateway) { - strcpy(gwstr, " via "); - ipaddr6_print_addr(*gateway, gwstr + strlen(gwstr)); - } else { - gwstr[0] = '\0'; - } - - char cmd[70 + IPADDR6_PRINT_MAX + IPADDR6_PRINT_MAX + IFNAMSIZ]; - sprintf(cmd, IP_CMD" route %s %s/%d%s metric %d dev %s", - cmdtype, dest_str, dest.prefix, gwstr, metric, ifname); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv6_route (struct ipv6_ifaddr dest, const struct ipv6_addr *gateway, int metric, const char *device) -{ - return route_cmd6("add", dest, gateway, metric, device); -} - -int NCDIfConfig_remove_ipv6_route (struct ipv6_ifaddr dest, const struct ipv6_addr *gateway, int metric, const char *device) -{ - return route_cmd6("del", dest, gateway, metric, device); -} - -static int blackhole_route_cmd (const char *cmdtype, struct ipv4_ifaddr dest, int metric) -{ - ASSERT(!strcmp(cmdtype, "add") || !strcmp(cmdtype, "del")) - ASSERT(dest.prefix >= 0) - ASSERT(dest.prefix <= 32) - - uint8_t *d_addr = (uint8_t *)&dest.addr; - - char cmd[120]; - sprintf(cmd, IP_CMD" route %s blackhole %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d metric %d", - cmdtype, d_addr[0], d_addr[1], d_addr[2], d_addr[3], dest.prefix, metric); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv4_blackhole_route (struct ipv4_ifaddr dest, int metric) -{ - return blackhole_route_cmd("add", dest, metric); -} - -int NCDIfConfig_remove_ipv4_blackhole_route (struct ipv4_ifaddr dest, int metric) -{ - return blackhole_route_cmd("del", dest, metric); -} - -static int blackhole_route_cmd6 (const char *cmdtype, struct ipv6_ifaddr dest, int metric) -{ - ASSERT(!strcmp(cmdtype, "add") || !strcmp(cmdtype, "del")) - ASSERT(dest.prefix >= 0) - ASSERT(dest.prefix <= 128) - - char dest_str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(dest.addr, dest_str); - - char cmd[70 + IPADDR6_PRINT_MAX]; - sprintf(cmd, IP_CMD" route %s blackhole %s/%d metric %d", - cmdtype, dest_str, dest.prefix, metric); - - return !run_command(cmd); -} - -int NCDIfConfig_add_ipv6_blackhole_route (struct ipv6_ifaddr dest, int metric) -{ - return blackhole_route_cmd6("add", dest, metric); -} - -int NCDIfConfig_remove_ipv6_blackhole_route (struct ipv6_ifaddr dest, int metric) -{ - return blackhole_route_cmd6("del", dest, metric); -} - -int NCDIfConfig_set_resolv_conf (const char *data, size_t data_len) -{ - FILE *temp_file = fopen(RESOLVCONF_TEMP_FILE, "w"); - if (!temp_file) { - BLog(BLOG_ERROR, "failed to open resolvconf temp file"); - goto fail0; - } - - char line[] = "# generated by badvpn-ncd\n"; - if (!write_to_file((uint8_t *)line, strlen(line), temp_file) || - !write_to_file((uint8_t *)data, data_len, temp_file) - ) { - BLog(BLOG_ERROR, "failed to write to resolvconf temp file"); - goto fail1; - } - - if (fclose(temp_file) != 0) { - BLog(BLOG_ERROR, "failed to close resolvconf temp file"); - return 0; - } - - if (rename(RESOLVCONF_TEMP_FILE, RESOLVCONF_FILE) < 0) { - BLog(BLOG_ERROR, "failed to rename resolvconf temp file to resolvconf file"); - return 0; - } - - return 1; - -fail1: - fclose(temp_file); -fail0: - return 0; -} - -static int open_tuntap (const char *ifname, int flags) -{ - if (strlen(ifname) >= IFNAMSIZ) { - BLog(BLOG_ERROR, "ifname too long"); - return -1; - } - - int fd = open(TUN_DEVNODE, O_RDWR); - if (fd < 0) { - BLog(BLOG_ERROR, "open tun failed"); - return -1; - } - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = flags; - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); - - if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { - BLog(BLOG_ERROR, "TUNSETIFF failed"); - close(fd); - return -1; - } - - return fd; -} - -int NCDIfConfig_make_tuntap (const char *ifname, const char *owner, int tun) -{ - // load tun module if needed - if (access(TUN_DEVNODE, F_OK) < 0) { - if (run_command(MODPROBE_CMD" tun") != 0) { - BLog(BLOG_ERROR, "modprobe tun failed"); - } - } - - int fd; - if ((fd = open_tuntap(ifname, (tun ? IFF_TUN : IFF_TAP))) < 0) { - goto fail0; - } - - if (owner) { - long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize < 0) { - bufsize = 16384; - } - - char *buf = malloc(bufsize); - if (!buf) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail1; - } - - struct passwd pwd; - struct passwd *res; - getpwnam_r(owner, &pwd, buf, bufsize, &res); - if (!res) { - BLog(BLOG_ERROR, "getpwnam_r failed"); - free(buf); - goto fail1; - } - - int uid = pwd.pw_uid; - - free(buf); - - if (ioctl(fd, TUNSETOWNER, uid) < 0) { - BLog(BLOG_ERROR, "TUNSETOWNER failed"); - goto fail1; - } - } - - if (ioctl(fd, TUNSETPERSIST, (void *)1) < 0) { - BLog(BLOG_ERROR, "TUNSETPERSIST failed"); - goto fail1; - } - - close(fd); - - return 1; - -fail1: - close(fd); -fail0: - return 0; -} - -int NCDIfConfig_remove_tuntap (const char *ifname, int tun) -{ - int fd; - if ((fd = open_tuntap(ifname, (tun ? IFF_TUN : IFF_TAP))) < 0) { - goto fail0; - } - - if (ioctl(fd, TUNSETPERSIST, (void *)0) < 0) { - BLog(BLOG_ERROR, "TUNSETPERSIST failed"); - goto fail1; - } - - close(fd); - - return 1; - -fail1: - close(fd); -fail0: - return 0; -} diff --git a/external/badvpn_dns/ncd/extra/NCDIfConfig.h b/external/badvpn_dns/ncd/extra/NCDIfConfig.h deleted file mode 100644 index 711979f..0000000 --- a/external/badvpn_dns/ncd/extra/NCDIfConfig.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file NCDIfConfig.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_NCDIFCONFIG_H -#define BADVPN_NCD_NCDIFCONFIG_H - -#include <stddef.h> - -#include <misc/ipaddr.h> -#include <misc/ipaddr6.h> - -#define NCDIFCONFIG_FLAG_EXISTS (1 << 0) -#define NCDIFCONFIG_FLAG_UP (1 << 1) -#define NCDIFCONFIG_FLAG_RUNNING (1 << 2) - -int NCDIfConfig_query (const char *ifname); - -int NCDIfConfig_set_up (const char *ifname); -int NCDIfConfig_set_down (const char *ifname); - -int NCDIfConfig_add_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr); -int NCDIfConfig_remove_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr); - -int NCDIfConfig_add_ipv6_addr (const char *ifname, struct ipv6_ifaddr ifaddr); -int NCDIfConfig_remove_ipv6_addr (const char *ifname, struct ipv6_ifaddr ifaddr); - -int NCDIfConfig_add_ipv4_route (struct ipv4_ifaddr dest, const uint32_t *gateway, int metric, const char *device); -int NCDIfConfig_remove_ipv4_route (struct ipv4_ifaddr dest, const uint32_t *gateway, int metric, const char *device); - -int NCDIfConfig_add_ipv6_route (struct ipv6_ifaddr dest, const struct ipv6_addr *gateway, int metric, const char *device); -int NCDIfConfig_remove_ipv6_route (struct ipv6_ifaddr dest, const struct ipv6_addr *gateway, int metric, const char *device); - -int NCDIfConfig_add_ipv4_blackhole_route (struct ipv4_ifaddr dest, int metric); -int NCDIfConfig_remove_ipv4_blackhole_route (struct ipv4_ifaddr dest, int metric); - -int NCDIfConfig_add_ipv6_blackhole_route (struct ipv6_ifaddr dest, int metric); -int NCDIfConfig_remove_ipv6_blackhole_route (struct ipv6_ifaddr dest, int metric); - -int NCDIfConfig_set_resolv_conf (const char *data, size_t data_len); - -int NCDIfConfig_make_tuntap (const char *ifname, const char *owner, int tun); -int NCDIfConfig_remove_tuntap (const char *ifname, int tun); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.c b/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.c deleted file mode 100644 index 8b457ef..0000000 --- a/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.c +++ /dev/null @@ -1,446 +0,0 @@ -/** - * @file NCDInterfaceMonitor.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <unistd.h> -#include <stdint.h> - -#include <sys/socket.h> -#include <net/if.h> -#include <netinet/in.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <asm/types.h> -#include <asm/types.h> - -#include <misc/debug.h> -#include <misc/nonblocking.h> -#include <base/BLog.h> - -#include <ncd/extra/NCDInterfaceMonitor.h> - -#include <generated/blog_channel_NCDInterfaceMonitor.h> - -#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) - -static int send_wilddump_request (NCDInterfaceMonitor *o, int fd, uint32_t seq, int family, int type); -static int get_attr (int type, struct rtattr *rta, int rta_len, void **out_attr, int *out_attr_len); -static void report_error (NCDInterfaceMonitor *o); -static int send_next_dump_request (NCDInterfaceMonitor *o); -static void netlink_fd_handler (NCDInterfaceMonitor *o, int events); -static void process_buffer (NCDInterfaceMonitor *o); -static void more_job_handler (NCDInterfaceMonitor *o); - -static int send_wilddump_request (NCDInterfaceMonitor *o, int fd, uint32_t seq, int family, int type) -{ - struct { - struct nlmsghdr nlh; - struct rtgenmsg g; - } req; - - memset(&req, 0, sizeof(req)); - req.nlh.nlmsg_len = sizeof(req); - req.nlh.nlmsg_type = type; - req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; - req.nlh.nlmsg_pid = 0; - req.nlh.nlmsg_seq = seq; - req.g.rtgen_family = family; - - int res = write(fd, &req, sizeof(req)); - if (res < 0) { - BLog(BLOG_ERROR, "write failed"); - return 0; - } - if (res != sizeof(req)) { - BLog(BLOG_ERROR, "write short"); - return 0; - } - - return 1; -} - -static int get_attr (int type, struct rtattr *rta, int rta_len, void **out_attr, int *out_attr_len) -{ - for (; RTA_OK(rta, rta_len); rta = RTA_NEXT(rta, rta_len)) { - uint8_t *attr = RTA_DATA(rta); - int attr_len = RTA_PAYLOAD(rta); - - if (rta->rta_type == type) { - *out_attr = attr; - *out_attr_len = attr_len; - return 1; - } - } - - return 0; -} - -static void report_error (NCDInterfaceMonitor *o) -{ - DEBUGERROR(&o->d_err, o->handler_error(o->user)) -} - -static int send_next_dump_request (NCDInterfaceMonitor *o) -{ - ASSERT(o->dump_queue) - - if (o->dump_queue & NCDIFMONITOR_WATCH_LINK) { - o->dump_queue &= ~NCDIFMONITOR_WATCH_LINK; - return send_wilddump_request(o, o->netlink_fd, o->dump_seq, 0, RTM_GETLINK); - } - else if (o->dump_queue & NCDIFMONITOR_WATCH_IPV4_ADDR) { - o->dump_queue &= ~NCDIFMONITOR_WATCH_IPV4_ADDR; - return send_wilddump_request(o, o->netlink_fd, o->dump_seq, AF_INET, RTM_GETADDR); - } - else if (o->dump_queue & NCDIFMONITOR_WATCH_IPV6_ADDR) { - o->dump_queue &= ~NCDIFMONITOR_WATCH_IPV6_ADDR; - return send_wilddump_request(o, o->netlink_fd, o->dump_seq, AF_INET6, RTM_GETADDR); - } - - ASSERT(0) - return 0; -} - -void netlink_fd_handler (NCDInterfaceMonitor *o, int events) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_bfd) - - // handler fd error - if (o->buf_left >= 0) { - BLog(BLOG_ERROR, "file descriptor error"); - goto fail; - } - - // read from netlink fd - int len = read(o->netlink_fd, o->buf.buf, sizeof(o->buf)); - if (len < 0) { - BLog(BLOG_ERROR, "read failed"); - goto fail; - } - - // stop receiving fd events - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, 0); - - // set buffer - o->buf_nh = &o->buf.nlh; - o->buf_left = len; - - // process buffer - process_buffer(o); - return; - -fail: - report_error(o); -} - -void process_buffer (NCDInterfaceMonitor *o) -{ - ASSERT(o->buf_left >= 0) - ASSERT(o->have_bfd) - - int done = 0; - - for (; NLMSG_OK(o->buf_nh, o->buf_left); o->buf_nh = NLMSG_NEXT(o->buf_nh, o->buf_left)) { - if (o->buf_nh->nlmsg_type == NLMSG_DONE) { - done = 1; - break; - } - - struct nlmsghdr *buf = o->buf_nh; - void *pl = NLMSG_DATA(buf); - int pl_len = NLMSG_PAYLOAD(buf, 0); - - struct NCDInterfaceMonitor_event ev; - - switch (buf->nlmsg_type) { - case RTM_NEWLINK: { // not RTM_DELLINK! who knows what these mean... - if (pl_len < sizeof(struct ifinfomsg)) { - BLog(BLOG_ERROR, "ifinfomsg too short"); - goto fail; - } - struct ifinfomsg *msg = pl; - - if (msg->ifi_index == o->ifindex && (o->watch_events & NCDIFMONITOR_WATCH_LINK)) { - ev.event = (buf->nlmsg_type == RTM_NEWLINK && (msg->ifi_flags & IFF_RUNNING)) ? NCDIFMONITOR_EVENT_LINK_UP : NCDIFMONITOR_EVENT_LINK_DOWN; - goto dispatch; - } - } break; - - case RTM_NEWADDR: - case RTM_DELADDR: { - if (pl_len < sizeof(struct ifaddrmsg)) { - BLog(BLOG_ERROR, "ifaddrmsg too short"); - goto fail; - } - struct ifaddrmsg *msg = pl; - - void *addr; - int addr_len; - if (!get_attr(IFA_ADDRESS, IFA_RTA(msg), buf->nlmsg_len - NLMSG_LENGTH(sizeof(*msg)), &addr, &addr_len)) { - break; - } - - if (msg->ifa_index == o->ifindex && msg->ifa_family == AF_INET && (o->watch_events & NCDIFMONITOR_WATCH_IPV4_ADDR)) { - if (addr_len != 4 || msg->ifa_prefixlen > 32) { - BLog(BLOG_ERROR, "bad ipv4 ifaddrmsg"); - goto fail; - } - - ev.event = (buf->nlmsg_type == RTM_NEWADDR) ? NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED : NCDIFMONITOR_EVENT_IPV4_ADDR_REMOVED; - ev.u.ipv4_addr.addr.addr = ((struct in_addr *)addr)->s_addr; - ev.u.ipv4_addr.addr.prefix = msg->ifa_prefixlen; - goto dispatch; - } - - if (msg->ifa_index == o->ifindex && msg->ifa_family == AF_INET6 && (o->watch_events & NCDIFMONITOR_WATCH_IPV6_ADDR)) { - if (addr_len != 16 || msg->ifa_prefixlen > 128) { - BLog(BLOG_ERROR, "bad ipv6 ifaddrmsg"); - goto fail; - } - - ev.event = (buf->nlmsg_type == RTM_NEWADDR) ? NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED : NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED; - memcpy(ev.u.ipv6_addr.addr.addr.bytes, ((struct in6_addr *)addr)->s6_addr, 16); - ev.u.ipv6_addr.addr.prefix = msg->ifa_prefixlen; - ev.u.ipv6_addr.addr_flags = 0; - ev.u.ipv6_addr.scope = msg->ifa_scope; - if (!(msg->ifa_flags & IFA_F_PERMANENT)) { - ev.u.ipv6_addr.addr_flags |= NCDIFMONITOR_ADDR_FLAG_DYNAMIC; - } - goto dispatch; - } - } break; - } - - continue; - - dispatch: - // move to next message - o->buf_nh = NLMSG_NEXT(o->buf_nh, o->buf_left); - - // schedule more job - BPending_Set(&o->more_job); - - // dispatch event - o->handler(o->user, ev); - return; - } - - if (done) { - if (o->dump_queue) { - // increment dump request sequence number - o->dump_seq++; - - // send next dump request - if (!send_next_dump_request(o)) { - goto fail; - } - } - else if (o->event_netlink_fd >= 0) { - // stop watching dump fd - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - o->have_bfd = 0; - - // close dump fd, make event fd current - close(o->netlink_fd); - o->netlink_fd = o->event_netlink_fd; - o->event_netlink_fd = -1; - - // start watching event fd - BFileDescriptor_Init(&o->bfd, o->netlink_fd, (BFileDescriptor_handler)netlink_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail; - } - o->have_bfd = 1; - } - } - - // set no buffer - o->buf_left = -1; - - // continue receiving fd events - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - return; - -fail: - report_error(o); -} - -void more_job_handler (NCDInterfaceMonitor *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->buf_left >= 0) - - // process buffer - process_buffer(o); - return; -} - -int NCDInterfaceMonitor_Init (NCDInterfaceMonitor *o, int ifindex, int watch_events, BReactor *reactor, void *user, - NCDInterfaceMonitor_handler handler, - NCDInterfaceMonitor_handler_error handler_error) -{ - ASSERT(watch_events) - ASSERT((watch_events&~(NCDIFMONITOR_WATCH_LINK|NCDIFMONITOR_WATCH_IPV4_ADDR|NCDIFMONITOR_WATCH_IPV6_ADDR)) == 0) - ASSERT(handler) - ASSERT(handler_error) - BNetwork_Assert(); - - // init arguments - o->ifindex = ifindex; - o->watch_events = watch_events; - o->reactor = reactor; - o->user = user; - o->handler = handler; - o->handler_error = handler_error; - - // init dump netlink fd - if ((o->netlink_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail0; - } - if (!badvpn_set_nonblocking(o->netlink_fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // init event netlink fd - if ((o->event_netlink_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail1; - } - if (!badvpn_set_nonblocking(o->event_netlink_fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail2; - } - - // build bind address - struct sockaddr_nl sa; - memset(&sa, 0, sizeof(sa)); - sa.nl_family = AF_NETLINK; - sa.nl_groups = 0; - if (watch_events & NCDIFMONITOR_WATCH_LINK) sa.nl_groups |= RTMGRP_LINK; - if (watch_events & NCDIFMONITOR_WATCH_IPV4_ADDR) sa.nl_groups |= RTMGRP_IPV4_IFADDR; - if (watch_events & NCDIFMONITOR_WATCH_IPV6_ADDR) sa.nl_groups |= RTMGRP_IPV6_IFADDR; - - // bind event netlink fd - if (bind(o->event_netlink_fd, (void *)&sa, sizeof(sa)) < 0) { - BLog(BLOG_ERROR, "bind failed"); - goto fail2; - } - - // set dump state - o->dump_queue = watch_events; - o->dump_seq = 0; - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->netlink_fd, (BFileDescriptor_handler)netlink_fd_handler, o); - if (!BReactor_AddFileDescriptor(reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail2; - } - o->have_bfd = 1; - - // set nothing in buffer - o->buf_left = -1; - - // init more job - BPending_Init(&o->more_job, BReactor_PendingGroup(reactor), (BPending_handler)more_job_handler, o); - - // send first dump request - if (!send_next_dump_request(o)) { - goto fail3; - } - - // wait for reading fd - BReactor_SetFileDescriptorEvents(reactor, &o->bfd, BREACTOR_READ); - - DebugError_Init(&o->d_err, BReactor_PendingGroup(reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail3: - BPending_Free(&o->more_job); - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); -fail2: - close(o->event_netlink_fd); -fail1: - close(o->netlink_fd); -fail0: - return 0; -} - -void NCDInterfaceMonitor_Free (NCDInterfaceMonitor *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free more job - BPending_Free(&o->more_job); - - // free BFileDescriptor - if (o->have_bfd) { - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - } - - // close event fd, in case we're still dumping - if (o->event_netlink_fd >= 0) { - close(o->event_netlink_fd); - } - - // close fd - close(o->netlink_fd); -} - -void NCDInterfaceMonitor_Pause (NCDInterfaceMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->have_bfd) - - if (o->buf_left >= 0) { - BPending_Unset(&o->more_job); - } else { - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, 0); - } -} - -void NCDInterfaceMonitor_Continue (NCDInterfaceMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->have_bfd) - - if (o->buf_left >= 0) { - BPending_Set(&o->more_job); - } else { - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - } -} diff --git a/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.h b/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.h deleted file mode 100644 index 805b8de..0000000 --- a/external/badvpn_dns/ncd/extra/NCDInterfaceMonitor.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file NCDInterfaceMonitor.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_NCDINTERFACEMONITOR_H -#define BADVPN_NCD_NCDINTERFACEMONITOR_H - -#include <stdint.h> -#include <sys/socket.h> -#include <linux/netlink.h> - -#include <misc/debug.h> -#include <misc/ipaddr.h> -#include <misc/ipaddr6.h> -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> - -#define NCDIFMONITOR_WATCH_LINK (1 << 0) -#define NCDIFMONITOR_WATCH_IPV4_ADDR (1 << 1) -#define NCDIFMONITOR_WATCH_IPV6_ADDR (1 << 2) - -#define NCDIFMONITOR_EVENT_LINK_UP 1 -#define NCDIFMONITOR_EVENT_LINK_DOWN 2 -#define NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED 3 -#define NCDIFMONITOR_EVENT_IPV4_ADDR_REMOVED 4 -#define NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED 5 -#define NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED 6 - -#define NCDIFMONITOR_ADDR_FLAG_DYNAMIC (1 << 0) - -struct NCDInterfaceMonitor_event { - int event; - union { - struct { - struct ipv4_ifaddr addr; - } ipv4_addr; - struct { - struct ipv6_ifaddr addr; - int addr_flags; - uint8_t scope; - } ipv6_addr; - } u; -}; - -/** - * Handler called to report an interface event. - * Note that the event reporter does not keep any interface state, and as such may - * report redundant events. You should therefore handle events in an idempotent - * fashion. - * - * @param event.event event type. One of: - * - NCDIFMONITOR_EVENT_LINK_UP, NCDIFMONITOR_EVENT_LINK_DOWN, - * - NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED, NCDIFMONITOR_EVENT_IPV4_ADDR_REMOVED, - * - NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED, NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED. - * Only events that correspont to enabled watch flags are reported. - * @param event.ipv4_addr.addr the IPv4 address and prefix length - * @param event.ipv6_addr.addr the IPv6 address, prefix length and scope - * @param event.ipv6_addr.addr_flags IPv6 address flags. Valid flags: - * - NCDIFMONITOR_ADDR_FLAG_DYNAMIC - this address was assigned dynamically (NDP) - */ -typedef void (*NCDInterfaceMonitor_handler) (void *user, struct NCDInterfaceMonitor_event event); - -/** - * Handler called when an error occurs. - * The event reporter must be freed from within the job context of this - * handler, and no other operations must be performed. - */ -typedef void (*NCDInterfaceMonitor_handler_error) (void *user); - -/** - * Watches for network interface events using a Linux rtnetlink socket. - */ -typedef struct { - int ifindex; - int watch_events; - BReactor *reactor; - void *user; - NCDInterfaceMonitor_handler handler; - NCDInterfaceMonitor_handler_error handler_error; - int netlink_fd; - int event_netlink_fd; - int dump_queue; - uint32_t dump_seq; - BFileDescriptor bfd; - int have_bfd; - union { - uint8_t buf[4096]; - struct nlmsghdr nlh; - } buf; - struct nlmsghdr *buf_nh; - int buf_left; - BPending more_job; - DebugError d_err; - DebugObject d_obj; -} NCDInterfaceMonitor; - -/** - * Initializes the event reporter. - * The reporter is not paused initially. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param ifindex index of network interface to report events for - * @param watch_events mask specifying what kind of events to report. Valid flags are - * NCDIFMONITOR_WATCH_LINK, NCDIFMONITOR_WATCH_IPV4_ADDR, NCDIFMONITOR_WATCH_IPV6_ADDR. - * At least one flag must be provided. - * @param reactor reactor we live in - * @param user argument to handlers - * @param handler handler to report interface events to - * @param handler_error error handler - * @return 1 on success, 0 on failure - */ -int NCDInterfaceMonitor_Init (NCDInterfaceMonitor *o, int ifindex, int watch_events, BReactor *reactor, void *user, - NCDInterfaceMonitor_handler handler, - NCDInterfaceMonitor_handler_error handler_error) WARN_UNUSED; - -/** - * Frees the event reporter. - */ -void NCDInterfaceMonitor_Free (NCDInterfaceMonitor *o); - -/** - * Pauses event reporting. - * This operation is idempotent. - */ -void NCDInterfaceMonitor_Pause (NCDInterfaceMonitor *o); - -/** - * Resumes event reporting. - * This operation is idempotent. - */ -void NCDInterfaceMonitor_Continue (NCDInterfaceMonitor *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDRequestClient.c b/external/badvpn_dns/ncd/extra/NCDRequestClient.c deleted file mode 100644 index edf6378..0000000 --- a/external/badvpn_dns/ncd/extra/NCDRequestClient.c +++ /dev/null @@ -1,647 +0,0 @@ -/** - * @file NCDRequestClient.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> -#include <limits.h> -#include <inttypes.h> -#include <string.h> - -#include <misc/byteorder.h> -#include <misc/expstring.h> -#include <misc/offset.h> -#include <misc/compare.h> -#include <protocol/packetproto.h> -#include <protocol/requestproto.h> -#include <base/BLog.h> - -#include "NCDRequestClient.h" - -#include <generated/blog_channel_NCDRequestClient.h> - -#define SEND_PAYLOAD_MTU 32768 -#define RECV_PAYLOAD_MTU 32768 - -#define SEND_MTU (SEND_PAYLOAD_MTU + sizeof(struct requestproto_header)) -#define RECV_MTU (RECV_PAYLOAD_MTU + sizeof(struct requestproto_header)) - -#define CSTATE_CONNECTING 1 -#define CSTATE_CONNECTED 2 - -#define RSTATE_SENDING_REQUEST 1 -#define RSTATE_READY 2 -#define RSTATE_SENDING_REQUEST_ABORT 3 -#define RSTATE_SENDING_ABORT 4 -#define RSTATE_WAITING_END 5 -#define RSTATE_DEAD_SENDING 6 - -static int uint32_comparator (void *unused, void *vv1, void *vv2); -static void report_error (NCDRequestClient *o); -static void request_report_finished (NCDRequestClientRequest *o, int is_error); -static void connector_handler (NCDRequestClient *o, int is_error); -static void connection_handler (NCDRequestClient *o, int event); -static void decoder_handler_error (NCDRequestClient *o); -static void recv_if_handler_send (NCDRequestClient *o, uint8_t *data, int data_len); -static struct NCDRequestClient_req * find_req (NCDRequestClient *o, uint32_t request_id); -static int get_free_request_id (NCDRequestClient *o, uint32_t *out); -static int build_requestproto_packet (uint32_t request_id, uint32_t type, NCDValRef payload_value, uint8_t **out_data, int *out_len); -static void build_nodata_packet (uint32_t request_id, uint32_t type, uint8_t *data, int *out_len); -static int req_is_aborted (struct NCDRequestClient_req *req); -static void req_abort (struct NCDRequestClient_req *req); -static void req_free (struct NCDRequestClient_req *req); -static void req_send_abort (struct NCDRequestClient_req *req); -static void req_qflow_send_iface_handler_done (struct NCDRequestClient_req *req); - -static int uint32_comparator (void *unused, void *vv1, void *vv2) -{ - uint32_t *v1 = vv1; - uint32_t *v2 = vv2; - return B_COMPARE(*v1, *v2); -} - -static void report_error (NCDRequestClient *o) -{ - ASSERT(!o->is_error) - - o->is_error = 1; - DEBUGERROR(&o->d_err, o->handler_error(o->user)) -} - -static void request_report_finished (NCDRequestClientRequest *o, int is_error) -{ - o->req = NULL; - - DEBUGERROR(&o->d_err, o->handler_finished(o->user, is_error)) -} - -static void connector_handler (NCDRequestClient *o, int is_error) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->state == CSTATE_CONNECTING) - - // check error - if (is_error) { - BLog(BLOG_ERROR, "failed to connect to socket"); - goto fail0; - } - - BPendingGroup *pg = BReactor_PendingGroup(o->reactor); - - // init connection - if (!BConnection_Init(&o->con, BConnection_source_connector(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - // init connection interfaces - BConnection_SendAsync_Init(&o->con); - BConnection_RecvAsync_Init(&o->con); - StreamPassInterface *con_send_if = BConnection_SendAsync_GetIf(&o->con); - StreamRecvInterface *con_recv_if = BConnection_RecvAsync_GetIf(&o->con); - - // init receive interface - PacketPassInterface_Init(&o->recv_if, RECV_MTU, (PacketPassInterface_handler_send)recv_if_handler_send, o, pg); - - // init receive decoder - if (!PacketProtoDecoder_Init(&o->recv_decoder, con_recv_if, &o->recv_if, pg, o, (PacketProtoDecoder_handler_error)decoder_handler_error)) { - BLog(BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail1; - } - - // init send sender - PacketStreamSender_Init(&o->send_sender, con_send_if, PACKETPROTO_ENCLEN(SEND_MTU), pg); - - // init send queue - PacketPassFifoQueue_Init(&o->send_queue, PacketStreamSender_GetInput(&o->send_sender), pg); - - // set state connected - o->state = CSTATE_CONNECTED; - - // call connected handler - o->handler_connected(o->user); - return; - -fail1: - PacketPassInterface_Free(&o->recv_if); - BConnection_RecvAsync_Free(&o->con); - BConnection_SendAsync_Free(&o->con); - BConnection_Free(&o->con); -fail0: - report_error(o); -} - -static void connection_handler (NCDRequestClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->state == CSTATE_CONNECTED) - - BLog(BLOG_ERROR, "connection error"); - - report_error(o); -} - -static void decoder_handler_error (NCDRequestClient *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->state == CSTATE_CONNECTED) - - BLog(BLOG_ERROR, "decoder error"); - - report_error(o); -} - -static void recv_if_handler_send (NCDRequestClient *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->state == CSTATE_CONNECTED) - ASSERT(data_len >= 0) - ASSERT(data_len <= RECV_MTU) - - // accept packet - PacketPassInterface_Done(&o->recv_if); - - if (data_len < sizeof(struct requestproto_header)) { - BLog(BLOG_ERROR, "missing requestproto header"); - goto fail; - } - - struct requestproto_header header; - memcpy(&header, data, sizeof(header)); - uint32_t request_id = ltoh32(header.request_id); - uint32_t type = ltoh32(header.type); - - uint8_t *payload = data + sizeof(header); - int payload_len = data_len - sizeof(header); - - // find request - struct NCDRequestClient_req *req = find_req(o, request_id); - if (!req) { - BLog(BLOG_ERROR, "received packet with unknown request ID"); - goto fail; - } - - switch (type) { - case REQUESTPROTO_TYPE_SERVER_REPLY: { - switch (o->state) { - case RSTATE_READY: { - // init memory - NCDValMem mem; - NCDValMem_Init(&mem); - - // parse payload - NCDValRef payload_value; - if (!NCDValParser_Parse((char *)payload, payload_len, &mem, &payload_value)) { - BLog(BLOG_ERROR, "failed to parse reply payload"); - NCDValMem_Free(&mem); - goto fail; - } - - // call reply handler - req->creq->handler_reply(req->creq->user, mem, payload_value); - return; - } break; - - case RSTATE_SENDING_ABORT: - case RSTATE_WAITING_END: - return; - - default: - BLog(BLOG_ERROR, "received unexpected reply"); - goto fail; - } - } break; - - case REQUESTPROTO_TYPE_SERVER_FINISHED: - case REQUESTPROTO_TYPE_SERVER_ERROR: { - if (payload_len != 0) { - BLog(BLOG_ERROR, "finshed/aborted message has non-empty payload"); - goto fail; - } - - NCDRequestClientRequest *creq = req->creq; - req->creq = NULL; - - switch (req->state) { - case RSTATE_SENDING_ABORT: { - // set state dying send - req->state = RSTATE_DEAD_SENDING; - } break; - - case RSTATE_WAITING_END: - case RSTATE_READY: { - // free req - req_free(req); - } break; - - default: - BLog(BLOG_ERROR, "received unexpected finished/aborted"); - goto fail; - } - - // report finished - if (creq) { - request_report_finished(creq, type == REQUESTPROTO_TYPE_SERVER_ERROR); - } - return; - } break; - - default: - BLog(BLOG_ERROR, "received invalid message type"); - goto fail; - } - - ASSERT(0) - -fail: - report_error(o); -} - -static struct NCDRequestClient_req * find_req (NCDRequestClient *o, uint32_t request_id) -{ - BAVLNode *tn = BAVL_LookupExact(&o->reqs_tree, &request_id); - if (!tn) { - return NULL; - } - - struct NCDRequestClient_req *req = UPPER_OBJECT(tn, struct NCDRequestClient_req, reqs_tree_node); - ASSERT(req->request_id == request_id) - - return req; -} - -static int get_free_request_id (NCDRequestClient *o, uint32_t *out) -{ - uint32_t first = o->next_request_id; - - do { - if (!find_req(o, o->next_request_id)) { - *out = o->next_request_id; - return 1; - } - o->next_request_id++; - } while (o->next_request_id != first); - - return 0; -} - -static int build_requestproto_packet (uint32_t request_id, uint32_t type, NCDValRef payload_value, uint8_t **out_data, int *out_len) -{ - ExpString str; - if (!ExpString_Init(&str)) { - BLog(BLOG_ERROR, "ExpString_Init failed"); - goto fail0; - } - - if (!ExpString_AppendZeros(&str, sizeof(struct packetproto_header) + sizeof(struct requestproto_header))) { - BLog(BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail1; - } - - if (!NCDVal_IsInvalid(payload_value) && !NCDValGenerator_AppendGenerate(payload_value, &str)) { - BLog(BLOG_ERROR, "NCDValGenerator_AppendGenerate failed"); - goto fail1; - } - - size_t len = ExpString_Length(&str); - if (len > INT_MAX || len > PACKETPROTO_ENCLEN(SEND_MTU) || len - sizeof(struct packetproto_header) > UINT16_MAX) { - BLog(BLOG_ERROR, "reply is too long"); - goto fail1; - } - - uint8_t *packet = (uint8_t *)ExpString_Get(&str); - - struct packetproto_header pp; - pp.len = htol16(len - sizeof(struct packetproto_header)); - - struct requestproto_header rp; - rp.request_id = htol32(request_id); - rp.type = htol32(type); - - memcpy(packet, &pp, sizeof(pp)); - memcpy(packet + sizeof(pp), &rp, sizeof(rp)); - - *out_data = packet; - *out_len = len; - return 1; - -fail1: - ExpString_Free(&str); -fail0: - return 0; -} - -static void build_nodata_packet (uint32_t request_id, uint32_t type, uint8_t *data, int *out_len) -{ - struct packetproto_header pp; - pp.len = htol16(sizeof(struct requestproto_header)); - - struct requestproto_header rp; - rp.request_id = htol32(request_id); - rp.type = htol32(type); - - memcpy(data, &pp, sizeof(pp)); - memcpy(data + sizeof(pp), &rp, sizeof(rp)); - - *out_len = sizeof(pp) + sizeof(rp); -} - -static int req_is_aborted (struct NCDRequestClient_req *req) -{ - switch (req->state) { - case RSTATE_SENDING_REQUEST: - case RSTATE_READY: - return 0; - default: - return 1; - } -} - -static void req_abort (struct NCDRequestClient_req *req) -{ - ASSERT(!req_is_aborted(req)) - ASSERT(!req->client->is_error) - - switch (req->state) { - case RSTATE_SENDING_REQUEST: { - req->state = RSTATE_SENDING_REQUEST_ABORT; - } break; - - case RSTATE_READY: { - req_send_abort(req); - } break; - - default: ASSERT(0); - } -} - -static void req_free (struct NCDRequestClient_req *req) -{ - NCDRequestClient *client = req->client; - PacketPassFifoQueueFlow_AssertFree(&req->send_qflow); - ASSERT(!req->creq) - - // free queue flow - PacketPassFifoQueueFlow_Free(&req->send_qflow); - - // free request data - free(req->request_data); - - // remove from reqs tree - BAVL_Remove(&client->reqs_tree, &req->reqs_tree_node); - - // free structure - free(req); -} - -static void req_send_abort (struct NCDRequestClient_req *req) -{ - // build packet - build_nodata_packet(req->request_id, REQUESTPROTO_TYPE_CLIENT_ABORT, req->request_data, &req->request_len); - - // start sending - PacketPassInterface_Sender_Send(req->send_qflow_iface, req->request_data, req->request_len); - - // set state sending abort - req->state = RSTATE_SENDING_ABORT; -} - -static void req_qflow_send_iface_handler_done (struct NCDRequestClient_req *req) -{ - switch (req->state) { - case RSTATE_SENDING_REQUEST: { - // set state ready - req->state = RSTATE_READY; - - // call sent handler - req->creq->handler_sent(req->creq->user); - return; - } break; - - case RSTATE_SENDING_REQUEST_ABORT: { - // send abort - req_send_abort(req); - } break; - - case RSTATE_SENDING_ABORT: { - // set state waiting end - req->state = RSTATE_WAITING_END; - } break; - - case RSTATE_DEAD_SENDING: { - // free req - req_free(req); - } break; - - default: ASSERT(0); - } -} - -int NCDRequestClient_Init (NCDRequestClient *o, struct BConnection_addr addr, BReactor *reactor, void *user, - NCDRequestClient_handler_error handler_error, - NCDRequestClient_handler_connected handler_connected) -{ - ASSERT(handler_error) - ASSERT(handler_connected) - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler_error = handler_error; - o->handler_connected = handler_connected; - - // init connector - if (!BConnector_InitGeneric(&o->connector, addr, reactor, o, (BConnector_handler)connector_handler)) { - BLog(BLOG_ERROR, "BConnector_InitGeneric failed"); - goto fail0; - } - - // init reqs tree - BAVL_Init(&o->reqs_tree, OFFSET_DIFF(struct NCDRequestClient_req, request_id, reqs_tree_node), uint32_comparator, NULL); - - // set next request ID - o->next_request_id = 0; - - // set state connecting - o->state = CSTATE_CONNECTING; - - // set is not error - o->is_error = 0; - - DebugCounter_Init(&o->d_reqests_ctr); - DebugError_Init(&o->d_err, BReactor_PendingGroup(reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void NCDRequestClient_Free (NCDRequestClient *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - DebugCounter_Free(&o->d_reqests_ctr); - - if (o->state == CSTATE_CONNECTED) { - // allow freeing queue flow - PacketPassFifoQueue_PrepareFree(&o->send_queue); - - // free remaining reqs - BAVLNode *tn; - while (tn = BAVL_GetFirst(&o->reqs_tree)) { - struct NCDRequestClient_req *req = UPPER_OBJECT(tn, struct NCDRequestClient_req, reqs_tree_node); - ASSERT(!req->creq) - req_free(req); - } - - // free connection stuff - PacketPassFifoQueue_Free(&o->send_queue); - PacketStreamSender_Free(&o->send_sender); - PacketProtoDecoder_Free(&o->recv_decoder); - PacketPassInterface_Free(&o->recv_if); - BConnection_RecvAsync_Free(&o->con); - BConnection_SendAsync_Free(&o->con); - BConnection_Free(&o->con); - } - - // free connector - BConnector_Free(&o->connector); -} - -int NCDRequestClientRequest_Init (NCDRequestClientRequest *o, NCDRequestClient *client, NCDValRef payload_value, void *user, - NCDRequestClientRequest_handler_sent handler_sent, - NCDRequestClientRequest_handler_reply handler_reply, - NCDRequestClientRequest_handler_finished handler_finished) -{ - ASSERT(client->state == CSTATE_CONNECTED) - DebugError_AssertNoError(&client->d_err); - ASSERT(!NCDVal_IsInvalid(payload_value)) - ASSERT(handler_sent) - ASSERT(handler_reply) - ASSERT(handler_finished) - - // init arguments - o->client = client; - o->user = user; - o->handler_sent = handler_sent; - o->handler_reply = handler_reply; - o->handler_finished = handler_finished; - - // allocate req structure - struct NCDRequestClient_req *req = malloc(sizeof(*req)); - if (!req) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // allocate request ID - if (!get_free_request_id(client, &req->request_id)) { - BLog(BLOG_ERROR, "failed to allocate request ID"); - goto fail1; - } - - // insert to reqs tree - int res = BAVL_Insert(&client->reqs_tree, &req->reqs_tree_node, NULL); - ASSERT_EXECUTE(res) - - // set pointers - o->req = req; - req->creq = o; - req->client = client; - - // build request - if (!build_requestproto_packet(req->request_id, REQUESTPROTO_TYPE_CLIENT_REQUEST, payload_value, &req->request_data, &req->request_len)) { - BLog(BLOG_ERROR, "failed to build request"); - goto fail2; - } - - // init queue flow - PacketPassFifoQueueFlow_Init(&req->send_qflow, &client->send_queue); - - // init send interface - req->send_qflow_iface = PacketPassFifoQueueFlow_GetInput(&req->send_qflow); - PacketPassInterface_Sender_Init(req->send_qflow_iface, (PacketPassInterface_handler_done)req_qflow_send_iface_handler_done, req); - - // start sending request - PacketPassInterface_Sender_Send(req->send_qflow_iface, req->request_data, req->request_len); - - // set state sending request - req->state = RSTATE_SENDING_REQUEST; - - DebugCounter_Increment(&client->d_reqests_ctr); - DebugError_Init(&o->d_err, BReactor_PendingGroup(client->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - BAVL_Remove(&client->reqs_tree, &req->reqs_tree_node); -fail1: - free(req); -fail0: - return 0; -} - -void NCDRequestClientRequest_Free (NCDRequestClientRequest *o) -{ - struct NCDRequestClient_req *req = o->req; - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - DebugCounter_Decrement(&o->client->d_reqests_ctr); - - if (req) { - ASSERT(req->creq == o) - - // remove reference to us - req->creq = NULL; - - // abort req if not already - if (!req->client->is_error && !req_is_aborted(req)) { - req_abort(req); - } - } -} - -void NCDRequestClientRequest_Abort (NCDRequestClientRequest *o) -{ - struct NCDRequestClient_req *req = o->req; - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - DebugError_AssertNoError(&o->client->d_err); - ASSERT(req) - ASSERT(req->creq == o) - ASSERT(!req_is_aborted(req)) - - // abort req - req_abort(req); -} diff --git a/external/badvpn_dns/ncd/extra/NCDRequestClient.h b/external/badvpn_dns/ncd/extra/NCDRequestClient.h deleted file mode 100644 index 7e0a6d5..0000000 --- a/external/badvpn_dns/ncd/extra/NCDRequestClient.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file NCDRequestClient.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCDREQUESTCLIENT_H -#define BADVPN_NCDREQUESTCLIENT_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <misc/debugcounter.h> -#include <structure/BAVL.h> -#include <base/DebugObject.h> -#include <system/BConnection.h> -#include <system/BConnectionGeneric.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketPassFifoQueue.h> -#include <ncd/NCDValGenerator.h> -#include <ncd/NCDValParser.h> - -struct NCDRequestClient_req; - -typedef void (*NCDRequestClient_handler_error) (void *user); -typedef void (*NCDRequestClient_handler_connected) (void *user); -typedef void (*NCDRequestClientRequest_handler_sent) (void *user); -typedef void (*NCDRequestClientRequest_handler_reply) (void *user, NCDValMem reply_mem, NCDValRef reply_value); -typedef void (*NCDRequestClientRequest_handler_finished) (void *user, int is_error); - -typedef struct { - BReactor *reactor; - void *user; - NCDRequestClient_handler_error handler_error; - NCDRequestClient_handler_connected handler_connected; - BConnector connector; - BConnection con; - PacketPassFifoQueue send_queue; - PacketStreamSender send_sender; - PacketProtoDecoder recv_decoder; - PacketPassInterface recv_if; - BAVL reqs_tree; - uint32_t next_request_id; - int state; - int is_error; - DebugCounter d_reqests_ctr; - DebugError d_err; - DebugObject d_obj; -} NCDRequestClient; - -typedef struct { - NCDRequestClient *client; - void *user; - NCDRequestClientRequest_handler_sent handler_sent; - NCDRequestClientRequest_handler_reply handler_reply; - NCDRequestClientRequest_handler_finished handler_finished; - struct NCDRequestClient_req *req; - DebugError d_err; - DebugObject d_obj; -} NCDRequestClientRequest; - -struct NCDRequestClient_req { - NCDRequestClientRequest *creq; - NCDRequestClient *client; - BAVLNode reqs_tree_node; - uint32_t request_id; - uint8_t *request_data; - int request_len; - PacketPassInterface *send_qflow_iface; - PacketPassFifoQueueFlow send_qflow; - int state; -}; - -int NCDRequestClient_Init (NCDRequestClient *o, struct BConnection_addr addr, BReactor *reactor, void *user, - NCDRequestClient_handler_error handler_error, - NCDRequestClient_handler_connected handler_connected) WARN_UNUSED; -void NCDRequestClient_Free (NCDRequestClient *o); - -int NCDRequestClientRequest_Init (NCDRequestClientRequest *o, NCDRequestClient *client, NCDValRef payload_value, void *user, - NCDRequestClientRequest_handler_sent handler_sent, - NCDRequestClientRequest_handler_reply handler_reply, - NCDRequestClientRequest_handler_finished handler_finished) WARN_UNUSED; -void NCDRequestClientRequest_Free (NCDRequestClientRequest *o); -void NCDRequestClientRequest_Abort (NCDRequestClientRequest *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.c b/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.c deleted file mode 100644 index cec2a3d..0000000 --- a/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.c +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file NCDRfkillMonitor.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <misc/debug.h> -#include <misc/nonblocking.h> -#include <base/BLog.h> - -#include "NCDRfkillMonitor.h" - -#include <generated/blog_channel_NCDRfkillMonitor.h> - -#define RFKILL_DEVICE_NODE "/dev/rfkill" - -static void rfkill_fd_handler (NCDRfkillMonitor *o, int events); - -void rfkill_fd_handler (NCDRfkillMonitor *o, int events) -{ - DebugObject_Access(&o->d_obj); - - // read from netlink fd - struct rfkill_event event; - int len = read(o->rfkill_fd, &event, sizeof(event)); - if (len < 0) { - BLog(BLOG_ERROR, "read failed"); - return; - } - if (len != sizeof(event)) { - BLog(BLOG_ERROR, "read returned wrong length"); - return; - } - - // call handler - o->handler(o->user, event); - return; -} - -int NCDRfkillMonitor_Init (NCDRfkillMonitor *o, BReactor *reactor, NCDRfkillMonitor_handler handler, void *user) -{ - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // open rfkill - if ((o->rfkill_fd = open(RFKILL_DEVICE_NODE, O_RDONLY)) < 0) { - BLog(BLOG_ERROR, "open failed"); - goto fail0; - } - - // set fd non-blocking - if (!badvpn_set_nonblocking(o->rfkill_fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->rfkill_fd, (BFileDescriptor_handler)rfkill_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (close(o->rfkill_fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail0: - return 0; -} - -void NCDRfkillMonitor_Free (NCDRfkillMonitor *o) -{ - DebugObject_Free(&o->d_obj); - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - // close rfkill - if (close(o->rfkill_fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -} diff --git a/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.h b/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.h deleted file mode 100644 index 00aa265..0000000 --- a/external/badvpn_dns/ncd/extra/NCDRfkillMonitor.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file NCDRfkillMonitor.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_NCDRFKILLMONITOR_H -#define BADVPN_NCD_NCDRFKILLMONITOR_H - -#include <linux/rfkill.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> - -typedef void (*NCDRfkillMonitor_handler) (void *user, struct rfkill_event event); - -typedef struct { - BReactor *reactor; - NCDRfkillMonitor_handler handler; - void *user; - int rfkill_fd; - BFileDescriptor bfd; - DebugObject d_obj; -} NCDRfkillMonitor; - -int NCDRfkillMonitor_Init (NCDRfkillMonitor *o, BReactor *reactor, NCDRfkillMonitor_handler handler, void *user) WARN_UNUSED; -void NCDRfkillMonitor_Free (NCDRfkillMonitor *o); - -#endif diff --git a/external/badvpn_dns/ncd/extra/address_utils.h b/external/badvpn_dns/ncd/extra/address_utils.h deleted file mode 100644 index 24ff79a..0000000 --- a/external/badvpn_dns/ncd/extra/address_utils.h +++ /dev/null @@ -1,280 +0,0 @@ -/** - * @file address_utils.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_ADDRESS_UTILS_H -#define NCD_ADDRESS_UTILS_H - -#include <string.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/ipaddr.h> -#include <misc/ipaddr6.h> -#include <misc/byteorder.h> -#include <system/BAddr.h> -#include <system/BConnectionGeneric.h> -#include <ncd/NCDVal.h> -#include <ncd/extra/value_utils.h> - -static int ncd_read_baddr (NCDValRef val, BAddr *out) WARN_UNUSED; -static NCDValRef ncd_make_baddr (BAddr addr, NCDValMem *mem); -static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *out_addr) WARN_UNUSED; - -static int ncd_read_baddr (NCDValRef val, BAddr *out) -{ - ASSERT(!NCDVal_IsInvalid(val)) - ASSERT(NCDVal_HasOnlyContinuousStrings(val)) - ASSERT(out) - - if (!NCDVal_IsList(val)) { - goto fail; - } - - NCDValRef type_val; - if (!NCDVal_ListReadHead(val, 1, &type_val)) { - goto fail; - } - if (!NCDVal_IsString(type_val)) { - goto fail; - } - - BAddr addr; - - if (NCDVal_StringEquals(type_val, "none")) { - if (!NCDVal_ListRead(val, 1, &type_val)) { - goto fail; - } - - addr.type = BADDR_TYPE_NONE; - } - else if (NCDVal_StringEquals(type_val, "ipv4")) { - NCDValRef ipaddr_val; - NCDValRef port_val; - if (!NCDVal_ListRead(val, 3, &type_val, &ipaddr_val, &port_val)) { - goto fail; - } - if (!NCDVal_IsString(ipaddr_val) || !NCDVal_IsString(port_val)) { - goto fail; - } - - addr.type = BADDR_TYPE_IPV4; - - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(ipaddr_val), NCDVal_StringLength(ipaddr_val), &addr.ipv4.ip)) { - goto fail; - } - - uintmax_t port; - if (!ncd_read_uintmax(port_val, &port) || port > UINT16_MAX) { - goto fail; - } - addr.ipv4.port = hton16(port); - } - else if (NCDVal_StringEquals(type_val, "ipv6")) { - NCDValRef ipaddr_val; - NCDValRef port_val; - if (!NCDVal_ListRead(val, 3, &type_val, &ipaddr_val, &port_val)) { - goto fail; - } - if (!NCDVal_IsString(ipaddr_val) || !NCDVal_IsString(port_val)) { - goto fail; - } - - addr.type = BADDR_TYPE_IPV6; - - struct ipv6_addr i6addr; - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(ipaddr_val), NCDVal_StringLength(ipaddr_val), &i6addr)) { - goto fail; - } - memcpy(addr.ipv6.ip, i6addr.bytes, 16); - - uintmax_t port; - if (!ncd_read_uintmax(port_val, &port) || port > UINT16_MAX) { - goto fail; - } - addr.ipv6.port = hton16(port); - } - else { - goto fail; - } - - *out = addr; - return 1; - -fail: - return 0; -} - -static NCDValRef ncd_make_baddr (BAddr addr, NCDValMem *mem) -{ - BAddr_Assert(&addr); - ASSERT(mem) - - NCDValRef val; - - switch (addr.type) { - default: - case BADDR_TYPE_NONE: { - val = NCDVal_NewList(mem, 1); - if (NCDVal_IsInvalid(val)) { - goto fail; - } - - const char *str = (addr.type == BADDR_TYPE_NONE ? "none" : "unknown"); - NCDValRef type_val = NCDVal_NewString(mem, str); - if (NCDVal_IsInvalid(type_val)) { - goto fail; - } - - if (!NCDVal_ListAppend(val, type_val)) { - goto fail; - } - } break; - - case BADDR_TYPE_IPV4: { - val = NCDVal_NewList(mem, 3); - if (NCDVal_IsInvalid(val)) { - goto fail; - } - - NCDValRef type_val = NCDVal_NewString(mem, "ipv4"); - if (NCDVal_IsInvalid(type_val)) { - goto fail; - } - - char ipaddr_buf[IPADDR_PRINT_MAX]; - ipaddr_print_addr(addr.ipv4.ip, ipaddr_buf); - NCDValRef ipaddr_val = NCDVal_NewString(mem, ipaddr_buf); - if (NCDVal_IsInvalid(ipaddr_val)) { - goto fail; - } - - NCDValRef port_val = ncd_make_uintmax(mem, ntoh16(addr.ipv4.port)); - if (NCDVal_IsInvalid(port_val)) { - goto fail; - } - - if (!NCDVal_ListAppend(val, type_val)) { - goto fail; - } - if (!NCDVal_ListAppend(val, ipaddr_val)) { - goto fail; - } - if (!NCDVal_ListAppend(val, port_val)) { - goto fail; - } - } break; - - case BADDR_TYPE_IPV6: { - val = NCDVal_NewList(mem, 3); - if (NCDVal_IsInvalid(val)) { - goto fail; - } - - NCDValRef type_val = NCDVal_NewString(mem, "ipv6"); - if (NCDVal_IsInvalid(type_val)) { - goto fail; - } - - char ipaddr_buf[IPADDR6_PRINT_MAX]; - struct ipv6_addr i6addr; - memcpy(i6addr.bytes, addr.ipv6.ip, 16); - ipaddr6_print_addr(i6addr, ipaddr_buf); - NCDValRef ipaddr_val = NCDVal_NewString(mem, ipaddr_buf); - if (NCDVal_IsInvalid(ipaddr_val)) { - goto fail; - } - - NCDValRef port_val = ncd_make_uintmax(mem, ntoh16(addr.ipv6.port)); - if (NCDVal_IsInvalid(port_val)) { - goto fail; - } - - if (!NCDVal_ListAppend(val, type_val)) { - goto fail; - } - if (!NCDVal_ListAppend(val, ipaddr_val)) { - goto fail; - } - if (!NCDVal_ListAppend(val, port_val)) { - goto fail; - } - } break; - } - - return val; - -fail: - return NCDVal_NewInvalid(); -} - -static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *out_addr) -{ - ASSERT(!NCDVal_IsInvalid(val)) - ASSERT(NCDVal_HasOnlyContinuousStrings(val)) - - if (!NCDVal_IsList(val)) { - goto fail; - } - - NCDValRef protocol_arg; - NCDValRef data_arg; - if (!NCDVal_ListRead(val, 2, &protocol_arg, &data_arg)) { - goto fail; - } - - if (!NCDVal_IsString(protocol_arg)) { - goto fail; - } - - if (NCDVal_StringEquals(protocol_arg, "unix")) { - if (!NCDVal_IsStringNoNulls(data_arg)) { - goto fail; - } - - *out_addr = BConnection_addr_unix(NCDVal_StringData(data_arg), NCDVal_StringLength(data_arg)); - } - else if (NCDVal_StringEquals(protocol_arg, "tcp")) { - BAddr baddr; - if (!ncd_read_baddr(data_arg, &baddr)) { - goto fail; - } - - *out_addr = BConnection_addr_baddr(baddr); - } - else { - goto fail; - } - - return 1; - -fail: - return 0; -} - -#endif diff --git a/external/badvpn_dns/ncd/extra/build_cmdline.c b/external/badvpn_dns/ncd/extra/build_cmdline.c deleted file mode 100644 index ea96b0f..0000000 --- a/external/badvpn_dns/ncd/extra/build_cmdline.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file build_cmdline.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/debug.h> -#include <ncd/extra/value_utils.h> - -#include "build_cmdline.h" - -int ncd_build_cmdline (NCDModuleInst *i, int log_channel, NCDValRef cmd_arg, char **out_exec, CmdLine *out_cl) -{ - ASSERT(!NCDVal_IsInvalid(cmd_arg)) - ASSERT(out_exec) - ASSERT(out_cl) - - if (!NCDVal_IsList(cmd_arg)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "wrong type"); - goto fail0; - } - - size_t count = NCDVal_ListCount(cmd_arg); - - // read exec - if (count == 0) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "missing executable name"); - goto fail0; - } - NCDValRef exec_arg = NCDVal_ListGet(cmd_arg, 0); - if (!NCDVal_IsStringNoNulls(exec_arg)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "wrong type"); - goto fail0; - } - char *exec = ncd_strdup(exec_arg); - if (!exec) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "ncd_strdup failed"); - goto fail0; - } - - // start cmdline - CmdLine cl; - if (!CmdLine_Init(&cl)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add header - if (!CmdLine_Append(&cl, exec)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // add additional arguments - for (size_t j = 1; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(cmd_arg, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "wrong type"); - goto fail2; - } - - b_cstring cstr = NCDVal_StringCstring(arg); - if (!CmdLine_AppendCstring(&cl, cstr, 0, cstr.length)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "CmdLine_AppendCstring failed"); - goto fail2; - } - } - - // finish - if (!CmdLine_Finish(&cl)) { - NCDModuleInst_Backend_Log(i, log_channel, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - *out_exec = exec; - *out_cl = cl; - return 1; - -fail2: - CmdLine_Free(&cl); -fail1: - free(exec); -fail0: - return 0; -} diff --git a/external/badvpn_dns/ncd/extra/build_cmdline.h b/external/badvpn_dns/ncd/extra/build_cmdline.h deleted file mode 100644 index 27abf18..0000000 --- a/external/badvpn_dns/ncd/extra/build_cmdline.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file build_cmdline.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_BUILD_CMDLINE_H -#define NCD_BUILD_CMDLINE_H - -#include <ncd/NCDModule.h> -#include <misc/cmdline.h> - -int ncd_build_cmdline (NCDModuleInst *i, int log_channel, NCDValRef cmd_arg, char **exec, CmdLine *cl); - -#endif diff --git a/external/badvpn_dns/ncd/extra/make_fast_names.h b/external/badvpn_dns/ncd/extra/make_fast_names.h deleted file mode 100644 index 3b7d72a..0000000 --- a/external/badvpn_dns/ncd/extra/make_fast_names.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file make_fast_names.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/merge.h> -#include <misc/balloc.h> -#include <ncd/NCDStringIndex.h> - -// Input parameters: -// #define NAMES_PARAM_NAME -// #define NAMES_PARAM_TYPE struct instance -// #define NAMES_PARAM_MEMBER_DYNAMIC_NAMES dynamic_names -// #define NAMES_PARAM_MEMBER_STATIC_NAMES static_names -// #define NAMES_PARAM_MEMBER_NUM_NAMES num_names -// #define NAMES_PARAM_NUM_STATIC_NAMES 10 - -#define MakeFastNames_count_names MERGE(NAMES_PARAM_NAME, _count_names) -#define MakeFastNames_add_name MERGE(NAMES_PARAM_NAME, _add_name) -#define MakeFastNames_InitNames MERGE(NAMES_PARAM_NAME, _InitNames) -#define MakeFastNames_FreeNames MERGE(NAMES_PARAM_NAME, _FreeNames) -#define MakeFastNames_GetNames MERGE(NAMES_PARAM_NAME, _GetNames) - -static size_t MakeFastNames_count_names (const char *str, size_t str_len) -{ - size_t count = 1; - - while (str_len > 0) { - if (*str == '.') { - count++; - } - str++; - str_len--; - } - - return count; -} - -static int MakeFastNames_add_name (NAMES_PARAM_TYPE *o, NCDStringIndex *string_index, const char *str, size_t str_len, const char *remain, size_t remain_len) -{ - ASSERT(str) - ASSERT(!!o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES == (o->NAMES_PARAM_MEMBER_NUM_NAMES > NAMES_PARAM_NUM_STATIC_NAMES)) - - NCD_string_id_t id = NCDStringIndex_GetBin(string_index, str, str_len); - if (id < 0) { - return 0; - } - - if (o->NAMES_PARAM_MEMBER_NUM_NAMES < NAMES_PARAM_NUM_STATIC_NAMES) { - o->NAMES_PARAM_MEMBER_STATIC_NAMES[o->NAMES_PARAM_MEMBER_NUM_NAMES++] = id; - return 1; - } - - if (o->NAMES_PARAM_MEMBER_NUM_NAMES == NAMES_PARAM_NUM_STATIC_NAMES) { - size_t num_more = (!remain ? 0 : MakeFastNames_count_names(remain, remain_len)); - size_t num_all = o->NAMES_PARAM_MEMBER_NUM_NAMES + 1 + num_more; - - if (!(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES = BAllocArray(num_all, sizeof(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES[0])))) { - return 0; - } - - memcpy(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES, o->NAMES_PARAM_MEMBER_STATIC_NAMES, NAMES_PARAM_NUM_STATIC_NAMES * sizeof(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES[0])); - } - - o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES[o->NAMES_PARAM_MEMBER_NUM_NAMES++] = id; - - return 1; -} - -static int MakeFastNames_InitNames (NAMES_PARAM_TYPE *o, NCDStringIndex *string_index, const char *str, size_t str_len) -{ - ASSERT(str) - - o->NAMES_PARAM_MEMBER_NUM_NAMES = 0; - o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES = NULL; - - size_t i = 0; - while (i < str_len) { - if (str[i] == '.') { - if (!MakeFastNames_add_name(o, string_index, str, i, str + (i + 1), str_len - (i + 1))) { - goto fail; - } - str += i + 1; - str_len -= i + 1; - i = 0; - continue; - } - i++; - } - - if (!MakeFastNames_add_name(o, string_index, str, i, NULL, 0)) { - goto fail; - } - - return 1; - -fail: - BFree(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES); - return 0; -} - -static void MakeFastNames_FreeNames (NAMES_PARAM_TYPE *o) -{ - if (o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES) { - BFree(o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES); - } -} - -static NCD_string_id_t * MakeFastNames_GetNames (NAMES_PARAM_TYPE *o) -{ - ASSERT(o->NAMES_PARAM_MEMBER_NUM_NAMES > 0) - - return (o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES ? o->NAMES_PARAM_MEMBER_DYNAMIC_NAMES : o->NAMES_PARAM_MEMBER_STATIC_NAMES); -} - -#undef MakeFastNames_count_names -#undef MakeFastNames_add_name -#undef MakeFastNames_InitNames -#undef MakeFastNames_FreeNames -#undef MakeFastNames_GetNames - -#undef NAMES_PARAM_NAME -#undef NAMES_PARAM_TYPE -#undef NAMES_PARAM_MEMBER_DYNAMIC_NAMES -#undef NAMES_PARAM_MEMBER_STATIC_NAMES -#undef NAMES_PARAM_MEMBER_NUM_NAMES -#undef NAMES_PARAM_NUM_STATIC_NAMES diff --git a/external/badvpn_dns/ncd/extra/value_utils.h b/external/badvpn_dns/ncd/extra/value_utils.h deleted file mode 100644 index 2d01148..0000000 --- a/external/badvpn_dns/ncd/extra/value_utils.h +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @file value_utils.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCD_VALUE_UTILS_H -#define NCD_VALUE_UTILS_H - -#include <stdint.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/parse_number.h> -#include <misc/strdup.h> -#include <misc/balloc.h> -#include <system/BTime.h> -#include <ncd/NCDVal.h> -#include <ncd/NCDStringIndex.h> -#include <ncd/static_strings.h> - -static int ncd_is_none (NCDValRef val); -static NCDValRef ncd_make_boolean (NCDValMem *mem, int value, NCDStringIndex *string_index); -static int ncd_read_boolean (NCDValRef val); -static int ncd_read_uintmax (NCDValRef string, uintmax_t *out) WARN_UNUSED; -static int ncd_read_time (NCDValRef string, btime_t *out) WARN_UNUSED; -static NCD_string_id_t ncd_get_string_id (NCDValRef string, NCDStringIndex *string_index); -static NCDValRef ncd_make_uintmax (NCDValMem *mem, uintmax_t value); -static char * ncd_strdup (NCDValRef stringnonulls); - -static int ncd_is_none (NCDValRef string) -{ - ASSERT(NCDVal_IsString(string)) - - if (NCDVal_IsIdString(string)) { - return NCDVal_IdStringId(string) == NCD_STRING_NONE; - } else { - return NCDVal_StringEquals(string, "<none>"); - } -} - -static NCDValRef ncd_make_boolean (NCDValMem *mem, int value, NCDStringIndex *string_index) -{ - ASSERT(mem) - ASSERT(string_index) - - NCD_string_id_t str_id = (value ? NCD_STRING_TRUE : NCD_STRING_FALSE); - return NCDVal_NewIdString(mem, str_id, string_index); -} - -static int ncd_read_boolean (NCDValRef string) -{ - ASSERT(NCDVal_IsString(string)) - - if (NCDVal_IsIdString(string)) { - return NCDVal_IdStringId(string) == NCD_STRING_TRUE; - } else { - return NCDVal_StringEquals(string, "true"); - } -} - -static int ncd_read_uintmax (NCDValRef string, uintmax_t *out) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(out) - - size_t length = NCDVal_StringLength(string); - - if (NCDVal_IsContinuousString(string)) { - return parse_unsigned_integer_bin(NCDVal_StringData(string), length, out); - } - - b_cstring cstr = NCDVal_StringCstring(string); - - return parse_unsigned_integer_cstr(cstr, 0, cstr.length, out); -} - -static int ncd_read_time (NCDValRef string, btime_t *out) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(out) - - uintmax_t n; - if (!ncd_read_uintmax(string, &n)) { - return 0; - } - - if (n > INT64_MAX) { - return 0; - } - - *out = n; - return 1; -} - -static NCD_string_id_t ncd_get_string_id (NCDValRef string, NCDStringIndex *string_index) -{ - ASSERT(NCDVal_IsString(string)) - ASSERT(string_index) - - if (NCDVal_IsIdString(string)) { - return NCDVal_IdStringId(string); - } else if (NCDVal_IsContinuousString(string)) { - return NCDStringIndex_GetBin(string_index, NCDVal_StringData(string), NCDVal_StringLength(string)); - } - - b_cstring cstr = NCDVal_StringCstring(string); - - char *temp = b_cstring_strdup(cstr, 0, cstr.length); - if (!temp) { - return -1; - } - - NCD_string_id_t res = NCDStringIndex_GetBin(string_index, temp, cstr.length); - BFree(temp); - - return res; -} - -static NCDValRef ncd_make_uintmax (NCDValMem *mem, uintmax_t value) -{ - ASSERT(mem) - - int size = compute_decimal_repr_size(value); - - NCDValRef val = NCDVal_NewStringUninitialized(mem, size); - - if (!NCDVal_IsInvalid(val)) { - char *data = (char *)NCDVal_StringData(val); - generate_decimal_repr(value, data, size); - } - - return val; -} - -static char * ncd_strdup (NCDValRef stringnonulls) -{ - ASSERT(NCDVal_IsStringNoNulls(stringnonulls)) - - size_t length = NCDVal_StringLength(stringnonulls); - - if (NCDVal_IsContinuousString(stringnonulls)) { - return b_strdup_bin(NCDVal_StringData(stringnonulls), length); - } - - b_cstring cstr = NCDVal_StringCstring(stringnonulls); - - return b_cstring_strdup(cstr, 0, cstr.length); -} - -#endif diff --git a/external/badvpn_dns/ncd/include_linux_input.c b/external/badvpn_dns/ncd/include_linux_input.c deleted file mode 100644 index 8eb6c02..0000000 --- a/external/badvpn_dns/ncd/include_linux_input.c +++ /dev/null @@ -1 +0,0 @@ -#include <linux/input.h> diff --git a/external/badvpn_dns/ncd/make_name_indices.h b/external/badvpn_dns/ncd/make_name_indices.h deleted file mode 100644 index b5c7c8e..0000000 --- a/external/badvpn_dns/ncd/make_name_indices.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file make_name_indices.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_MAKE_NAME_INDICES_H -#define BADVPN_MAKE_NAME_INDICES_H - -#include <stdlib.h> -#include <stddef.h> - -#include <misc/strdup.h> -#include <misc/balloc.h> -#include <misc/debug.h> -#include <ncd/NCDStringIndex.h> - -static int ncd_make_name_indices (NCDStringIndex *string_index, const char *name, NCD_string_id_t **out_varnames, size_t *out_num_names) WARN_UNUSED; - -static size_t split_string_inplace2__indices (char *str, char del) -{ - ASSERT(str) - - size_t num_extra_parts = 0; - - while (*str) { - if (*str == del) { - *str = '\0'; - num_extra_parts++; - } - str++; - } - - return num_extra_parts; -} - -static int ncd_make_name_indices (NCDStringIndex *string_index, const char *name, NCD_string_id_t **out_varnames, size_t *out_num_names) -{ - ASSERT(string_index) - ASSERT(name) - ASSERT(out_varnames) - ASSERT(out_num_names) - - char *data = b_strdup(name); - if (!data) { - goto fail0; - } - - size_t num_names = split_string_inplace2__indices(data, '.') + 1; - - NCD_string_id_t *varnames = BAllocArray(num_names, sizeof(varnames[0])); - if (!varnames) { - goto fail1; - } - - char *cur = data; - for (size_t i = 0; i < num_names; i++) { - NCD_string_id_t id = NCDStringIndex_Get(string_index, cur); - if (id < 0) { - goto fail2; - } - - varnames[i] = id; - cur += strlen(cur) + 1; - } - - free(data); - - *out_varnames = varnames; - *out_num_names = num_names; - return 1; - -fail2: - BFree(varnames); -fail1: - free(data); -fail0: - return 0; -} - -#endif diff --git a/external/badvpn_dns/ncd/modules/alias.c b/external/badvpn_dns/ncd/modules/alias.c deleted file mode 100644 index f6bb7ec..0000000 --- a/external/badvpn_dns/ncd/modules/alias.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file alias.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * alias(string target) - * - * Variables and objects: - * - empty name - resolves target - * - nonempty name N - resolves target.N - */ - -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balloc.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_alias.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define NUM_STATIC_NAMES 4 - -struct instance { - NCDModuleInst *i; - NCD_string_id_t *dynamic_names; - size_t num_names; - NCD_string_id_t static_names[NUM_STATIC_NAMES]; -}; - -#define NAMES_PARAM_NAME AliasNames -#define NAMES_PARAM_TYPE struct instance -#define NAMES_PARAM_MEMBER_DYNAMIC_NAMES dynamic_names -#define NAMES_PARAM_MEMBER_STATIC_NAMES static_names -#define NAMES_PARAM_MEMBER_NUM_NAMES num_names -#define NAMES_PARAM_NUM_STATIC_NAMES NUM_STATIC_NAMES -#include <ncd/extra/make_fast_names.h> - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef target_arg; - if (!NCDVal_ListRead(params->args, 1, &target_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(target_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse name string - if (!AliasNames_InitNames(o, i->params->iparams->string_index, NCDVal_StringData(target_arg), NCDVal_StringLength(target_arg))) { - ModuleLog(i, BLOG_ERROR, "make_names failed"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - AliasNames_FreeNames(o); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getobj (void *vo, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = vo; - ASSERT(o->num_names > 0) - - NCD_string_id_t *names = AliasNames_GetNames(o); - - NCDObject object; - if (!NCDModuleInst_Backend_GetObj(o->i, names[0], &object)) { - return 0; - } - - NCDObject obj2; - if (!NCDObject_ResolveObjExprCompact(&object, names + 1, o->num_names - 1, &obj2)) { - return 0; - } - - if (name == NCD_STRING_EMPTY) { - *out_object = obj2; - return 1; - } - - return NCDObject_GetObj(&obj2, name, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "alias", - .func_new2 = func_new, - .func_die = func_die, - .func_getobj = func_getobj, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_alias = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/arithmetic.c b/external/badvpn_dns/ncd/modules/arithmetic.c deleted file mode 100644 index 288a637..0000000 --- a/external/badvpn_dns/ncd/modules/arithmetic.c +++ /dev/null @@ -1,404 +0,0 @@ -/** - * @file arithmetic.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Arithmetic functions for unsigned integers. - * - * Synopsis: - * num_lesser(string n1, string n2) - * num_greater(string n1, string n2) - * num_lesser_equal(string n1, string n2) - * num_greater_equal(string n1, string n2) - * num_equal(string n1, string n2) - * num_different(string n1, string n2) - * - * Variables: - * (empty) - "true" or "false", reflecting the value of the relation in question - * - * Description: - * These statements perform arithmetic comparisons. The operands passed must be - * non-negative decimal integers representable in a uintmax_t. Otherwise, an error - * is triggered. - * - * Synopsis: - * num_add(string n1, string n2) - * num_subtract(string n1, string n2) - * num_multiply(string n1, string n2) - * num_divide(string n1, string n2) - * num_modulo(string n1, string n2) - * - * Description: - * These statements perform arithmetic operations. The operands passed must be - * non-negative decimal integers representable in a uintmax_t, and the result must - * also be representable and non-negative. For divide and modulo, n2 must be non-zero. - * If any of these restrictions is violated, an error is triggered. - * - * Variables: - * (empty) - the result of the operation as a string representing a decimal number - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <limits.h> - -#include <misc/parse_number.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_arithmetic.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct boolean_instance { - NCDModuleInst *i; - int value; -}; - -typedef int (*boolean_compute_func) (uintmax_t n1, uintmax_t n2); - -struct number_instance { - NCDModuleInst *i; - uintmax_t value; -}; - -typedef int (*number_compute_func) (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out); - -static int compute_lesser (uintmax_t n1, uintmax_t n2) -{ - return n1 < n2; -} - -static int compute_greater (uintmax_t n1, uintmax_t n2) -{ - return n1 > n2; -} - -static int compute_lesser_equal (uintmax_t n1, uintmax_t n2) -{ - return n1 <= n2; -} - -static int compute_greater_equal (uintmax_t n1, uintmax_t n2) -{ - return n1 >= n2; -} - -static int compute_equal (uintmax_t n1, uintmax_t n2) -{ - return n1 == n2; -} - -static int compute_different (uintmax_t n1, uintmax_t n2) -{ - return n1 != n2; -} - -static int compute_add (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out) -{ - if (n1 > UINTMAX_MAX - n2) { - ModuleLog(i, BLOG_ERROR, "addition overflow"); - return 0; - } - *out = n1 + n2; - return 1; -} - -static int compute_subtract (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out) -{ - if (n1 < n2) { - ModuleLog(i, BLOG_ERROR, "subtraction underflow"); - return 0; - } - *out = n1 - n2; - return 1; -} - -static int compute_multiply (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out) -{ - if (n1 > UINTMAX_MAX / n2) { - ModuleLog(i, BLOG_ERROR, "multiplication overflow"); - return 0; - } - *out = n1 * n2; - return 1; -} - -static int compute_divide (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out) -{ - if (n2 == 0) { - ModuleLog(i, BLOG_ERROR, "division quotient is zero"); - return 0; - } - *out = n1 / n2; - return 1; -} - -static int compute_modulo (NCDModuleInst *i, uintmax_t n1, uintmax_t n2, uintmax_t *out) -{ - if (n2 == 0) { - ModuleLog(i, BLOG_ERROR, "modulo modulus is zero"); - return 0; - } - *out = n1 % n2; - return 1; -} - -static void new_boolean_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, boolean_compute_func cfunc) -{ - struct boolean_instance *o = vo; - o->i = i; - - NCDValRef n1_arg; - NCDValRef n2_arg; - if (!NCDVal_ListRead(params->args, 2, &n1_arg, &n2_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(n1_arg) || !NCDVal_IsString(n2_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - uintmax_t n1; - if (!ncd_read_uintmax(n1_arg, &n1)) { - ModuleLog(o->i, BLOG_ERROR, "wrong first argument"); - goto fail0; - } - - uintmax_t n2; - if (!ncd_read_uintmax(n2_arg, &n2)) { - ModuleLog(o->i, BLOG_ERROR, "wrong second argument"); - goto fail0; - } - - o->value = cfunc(n1, n2); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int boolean_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct boolean_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = ncd_make_boolean(mem, o->value, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void new_number_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, number_compute_func cfunc) -{ - struct number_instance *o = vo; - o->i = i; - - NCDValRef n1_arg; - NCDValRef n2_arg; - if (!NCDVal_ListRead(params->args, 2, &n1_arg, &n2_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(n1_arg) || !NCDVal_IsString(n2_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - uintmax_t n1; - if (!ncd_read_uintmax(n1_arg, &n1)) { - ModuleLog(o->i, BLOG_ERROR, "wrong first argument"); - goto fail0; - } - - uintmax_t n2; - if (!ncd_read_uintmax(n2_arg, &n2)) { - ModuleLog(o->i, BLOG_ERROR, "wrong second argument"); - goto fail0; - } - - if (!cfunc(i, n1, n2, &o->value)) { - goto fail0; - } - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int number_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct number_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = ncd_make_uintmax(mem, o->value); - return 1; - } - - return 0; -} - -static void func_new_lesser (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_lesser); -} - -static void func_new_greater (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_greater); -} - -static void func_new_lesser_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_lesser_equal); -} - -static void func_new_greater_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_greater_equal); -} - -static void func_new_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_equal); -} - -static void func_new_different (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_boolean_templ(vo, i, params, compute_different); -} - -static void func_new_add (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_number_templ(vo, i, params, compute_add); -} - -static void func_new_subtract (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_number_templ(vo, i, params, compute_subtract); -} - -static void func_new_multiply (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_number_templ(vo, i, params, compute_multiply); -} - -static void func_new_divide (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_number_templ(vo, i, params, compute_divide); -} - -static void func_new_modulo (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_number_templ(vo, i, params, compute_modulo); -} - -static struct NCDModule modules[] = { - { - .type = "num_lesser", - .func_new2 = func_new_lesser, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_greater", - .func_new2 = func_new_greater, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_lesser_equal", - .func_new2 = func_new_lesser_equal, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_greater_equal", - .func_new2 = func_new_greater_equal, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_equal", - .func_new2 = func_new_equal, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_different", - .func_new2 = func_new_different, - .func_getvar2 = boolean_func_getvar2, - .alloc_size = sizeof(struct boolean_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_add", - .func_new2 = func_new_add, - .func_getvar2 = number_func_getvar2, - .alloc_size = sizeof(struct number_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_subtract", - .func_new2 = func_new_subtract, - .func_getvar2 = number_func_getvar2, - .alloc_size = sizeof(struct number_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_multiply", - .func_new2 = func_new_multiply, - .func_getvar2 = number_func_getvar2, - .alloc_size = sizeof(struct number_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_divide", - .func_new2 = func_new_divide, - .func_getvar2 = number_func_getvar2, - .alloc_size = sizeof(struct number_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "num_modulo", - .func_new2 = func_new_modulo, - .func_getvar2 = number_func_getvar2, - .alloc_size = sizeof(struct number_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_arithmetic = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/assert.c b/external/badvpn_dns/ncd/modules/assert.c deleted file mode 100644 index 75205c5..0000000 --- a/external/badvpn_dns/ncd/modules/assert.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file assert.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * assert(string cond) - * assert_false(string cond) - * - * Description: - * If 'cond' is equal to the string "true" (assert) or "false" (assert_false), - * does nothing. Otherwise, logs an error and initiates interpreter termination - * with exit code 1, i.e. it is equivalent to calling exit("1"). - * Note that "assert_false(cond);" is not completely equivalent to - * "not(cond) a; assert(a);", in case 'cond' is something other than "true" - * or "false". - */ - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_assert.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void func_new_common (NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_false) -{ - // check arguments - NCDValRef cond_arg; - if (!NCDVal_ListRead(params->args, 1, &cond_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(cond_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - - // if failed, initiate exit (before up!) - if ((!is_false && !NCDVal_StringEqualsId(cond_arg, NCD_STRING_TRUE, i->params->iparams->string_index)) || - (is_false && !NCDVal_StringEqualsId(cond_arg, NCD_STRING_FALSE, i->params->iparams->string_index)) - ) { - ModuleLog(i, BLOG_ERROR, "assertion failed"); - NCDModuleInst_Backend_InterpExit(i, 1); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(i, params, 0); -} - -static void func_new_false (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(i, params, 1); -} - -static struct NCDModule modules[] = { - { - .type = "assert", - .func_new2 = func_new - }, { - .type = "assert_false", - .func_new2 = func_new_false - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_assert = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/backtrack.c b/external/badvpn_dns/ncd/modules/backtrack.c deleted file mode 100644 index ec9c5d7..0000000 --- a/external/badvpn_dns/ncd/modules/backtrack.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file backtrack.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * backtrack_point() - * backtrack_point::go() - * - * Description: - * The backtrack_point() statement creates a backtrack point, going up immedietely. - * The go() method triggers backtracking to the backtrack point, i.e. makes the - * backtrack_point() statement go down and back up at atomically. The go() method - * itself goes up immedietely, but side effects of triggering backtracking have - * priority. - */ - -#include <stddef.h> - -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_backtrack.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void go_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get backtrack point - NCDModuleInst *backtrack_point_inst = params->method_user; - - // go up (after toggling) - NCDModuleInst_Backend_Up(i); - - // toggle backtrack point - NCDModuleInst_Backend_DownUp(backtrack_point_inst); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "backtrack_point", - .func_new2 = func_new - }, { - .type = "backtrack_point::go", - .func_new2 = go_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_backtrack = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/blocker.c b/external/badvpn_dns/ncd/modules/blocker.c deleted file mode 100644 index b742d72..0000000 --- a/external/badvpn_dns/ncd/modules/blocker.c +++ /dev/null @@ -1,353 +0,0 @@ -/** - * @file blocker.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Blocker module. Provides a statement that blocks when initialized, and which can be blocked - * and unblocked from outside. - * - * Synopsis: blocker() - * Description: provides blocking operations. Initially the blocking state is down (but this statement - * does not block). On deinitialization, waits for all corresponding use() statements - * to die before dying itself. - * - * Synopsis: blocker::up() - * Description: sets the blocking state to up. - * The immediate effects of corresponding use() statements going up are processed before - * this statement goes up; but this statement statement still goes up immediately, - * assuming the effects mentioned haven't resulted in the intepreter scheduling this - * very statement for destruction. - * - * Synopsis: blocker::down() - * Description: sets the blocking state to down. - * The immediate effects of corresponding use() statements going up are processed before - * this statement goes up; but this statement statement still goes up immediately, - * assuming the effects mentioned haven't resulted in the intepreter scheduling this - * very statement for destruction. - * - * Synopsis: blocker::downup() - * Description: atomically sets the blocker to down state (if it was up), then (back) to up state. - * Note that this is not equivalent to calling down() and immediately up(); in that case, - * the interpreter will first handle the immediate effects of any use() statements - * going down as a result of having called down() and will only later execute the up() - * statement. In fact, it is possible that the effects of down() will prevent up() from - * executing, which may leave the program in an undesirable state. - * - * Synopsis: blocker::rdownup() - * Description: on deinitialization, atomically sets the blocker to down state (if it was up), then - * (back) to up state. - * The immediate effects of corresponding use() statements changing state are processed - * *after* the immediate effects of this statement dying (in contrast to downup()). - * - * Synopsis: blocker::use() - * Description: blocks on the blocker. This module is in up state if and only if the blocking state of - * the blocker is up. Multiple use statements may be used with the same blocker. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <structure/LinkedList0.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_blocker.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - LinkedList1 users; - LinkedList0 rdownups_list; - int up; - int dying; -}; - -struct rdownup_instance { - NCDModuleInst *i; - struct instance *blocker; - LinkedList0Node rdownups_list_node; -}; - -struct use_instance { - NCDModuleInst *i; - struct instance *blocker; - LinkedList1Node blocker_node; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init users list - LinkedList1_Init(&o->users); - - // init rdownups list - LinkedList0_Init(&o->rdownups_list); - - // set not up - o->up = 0; - - // set not dying - o->dying = 0; - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - ASSERT(LinkedList1_IsEmpty(&o->users)) - - // break any rdownups - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&o->rdownups_list)) { - struct rdownup_instance *rdu = UPPER_OBJECT(ln, struct rdownup_instance, rdownups_list_node); - ASSERT(rdu->blocker == o) - LinkedList0_Remove(&o->rdownups_list, &rdu->rdownups_list_node); - rdu->blocker = NULL; - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // if we have no users, die right away, else wait for users - if (LinkedList1_IsEmpty(&o->users)) { - instance_free(o); - return; - } - - // set dying - o->dying = 1; -} - -static void updown_func_new_templ (NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int up, int first_down) -{ - ASSERT(!first_down || up) - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - if (first_down || mo->up != up) { - // signal users - for (LinkedList1Node *node = LinkedList1_GetFirst(&mo->users); node; node = LinkedList1Node_Next(node)) { - struct use_instance *user = UPPER_OBJECT(node, struct use_instance, blocker_node); - ASSERT(user->blocker == mo) - if (first_down && mo->up) { - NCDModuleInst_Backend_Down(user->i); - } - if (up) { - NCDModuleInst_Backend_Up(user->i); - } else { - NCDModuleInst_Backend_Down(user->i); - } - } - - // change up state - mo->up = up; - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void up_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - updown_func_new_templ(i, params, 1, 0); -} - -static void down_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - updown_func_new_templ(i, params, 0, 0); -} - -static void downup_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - updown_func_new_templ(i, params, 1, 1); -} - -static void rdownup_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct rdownup_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get blocker - struct instance *blk = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // set blocker - o->blocker = blk; - - // insert to rdownups list - LinkedList0_Prepend(&blk->rdownups_list, &o->rdownups_list_node); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void rdownup_func_die (void *vo) -{ - struct rdownup_instance *o = vo; - - struct instance *blk = o->blocker; - - if (blk) { - // remove from rdownups list - LinkedList0_Remove(&blk->rdownups_list, &o->rdownups_list_node); - - // downup users - for (LinkedList1Node *ln = LinkedList1_GetFirst(&blk->users); ln; ln = LinkedList1Node_Next(ln)) { - struct use_instance *user = UPPER_OBJECT(ln, struct use_instance, blocker_node); - ASSERT(user->blocker == blk) - if (blk->up) { - NCDModuleInst_Backend_Down(user->i); - } - NCDModuleInst_Backend_Up(user->i); - } - - // set up - blk->up = 1; - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void use_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct use_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // set blocker - o->blocker = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // add to blocker's list - LinkedList1_Append(&o->blocker->users, &o->blocker_node); - - // signal up if needed - if (o->blocker->up) { - NCDModuleInst_Backend_Up(o->i); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void use_func_die (void *vo) -{ - struct use_instance *o = vo; - - // remove from blocker's list - LinkedList1_Remove(&o->blocker->users, &o->blocker_node); - - // make the blocker die if needed - if (o->blocker->dying && LinkedList1_IsEmpty(&o->blocker->users)) { - instance_free(o->blocker); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "blocker", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "blocker::up", - .func_new2 = up_func_new - }, { - .type = "blocker::down", - .func_new2 = down_func_new - }, { - .type = "blocker::downup", - .func_new2 = downup_func_new - }, { - .type = "blocker::rdownup", - .func_new2 = rdownup_func_new, - .func_die = rdownup_func_die, - .alloc_size = sizeof(struct rdownup_instance) - }, { - .type = "blocker::use", - .func_new2 = use_func_new, - .func_die = use_func_die, - .alloc_size = sizeof(struct use_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_blocker = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/buffer.c b/external/badvpn_dns/ncd/modules/buffer.c deleted file mode 100644 index eeb3715..0000000 --- a/external/badvpn_dns/ncd/modules/buffer.c +++ /dev/null @@ -1,619 +0,0 @@ -/** - * @file buffer.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * buffer([string data]) - * - * Variables: - * string (empty) - data in the buffer - * string length - number of bytes in the buffer - * - * Description: - * Implements an array of bytes which supports appending bytes and removing - * bytes from the beginning. The buffer is implemented using chunks; - * the time complexity of operations depends on the number of chunks affected, - * and not on the actual number of bytes. Each append operation produces a single - * chunk. In particular: - * - * Complexity of append and construction: - * log(total number of chunks) + (time for copying data). - * Complexity of consume: - * log(total number of chunks) * (1 + (number of chunks in consumed range)) - * Complexity of referencing and unreferencing a range: - * log(total number of chunks) * (1 + (number of chunks in referenced range)) - * - * Synopsis: - * buffer::append(string data) - * - * Description: - * Appends the given data to the end of the buffer. - * - * Synopsis: - * buffer::consume(string amount) - * - * Description: - * Removes the specified number of bytes from the beginning of the buffer. - * 'amount' must not be larger than the current length of the buffer. - */ - -#include <stddef.h> -#include <string.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <misc/offset.h> -#include <structure/SAvl.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_buffer.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct chunk; - -#include "buffer_chunks_tree.h" -#include <structure/SAvl_decl.h> - -struct buffer { - struct instance *inst; - ChunksTree chunks_tree; - int refcnt; -}; - -struct chunk { - struct buffer *buf; - size_t offset; - size_t length; - ChunksTreeNode chunks_tree_node; - int refcnt; - char data[]; -}; - -struct reference { - struct chunk *first_chunk; - size_t first_offset; - size_t length; - BRefTarget ref_target; -}; - -struct instance { - NCDModuleInst *i; - size_t offset; - size_t total_length; - struct buffer *buf; -}; - -#include "buffer_chunks_tree.h" -#include <structure/SAvl_impl.h> - -static void instance_assert (struct instance *inst); -static int instance_append (struct instance *inst, NCDValRef string); -static void instance_consume (struct instance *inst, size_t amount); -static struct buffer * buffer_init (struct instance *inst, NCDModuleInst *i); -static void buffer_free (struct buffer *buf); -static void buffer_detach (struct buffer *buf); -static struct chunk * buffer_get_existing_chunk (struct buffer *buf, size_t offset); -static struct chunk * chunk_init (struct instance *inst, size_t length); -static void chunk_unref (struct chunk *c); -static void chunk_assert (struct chunk *c); -static struct reference * reference_init (struct instance *inst, size_t offset, size_t length, NCDValComposedStringResource *out_resource); -static void reference_ref_target_func_release (BRefTarget *ref_target); -static void reference_assert (struct reference *ref); -static void reference_resource_func_getptr (void *user, size_t offset, const char **out_data, size_t *out_length); - -static void instance_assert (struct instance *inst) -{ - ASSERT(inst->buf->inst == inst) -} - -static int instance_append (struct instance *inst, NCDValRef string) -{ - instance_assert(inst); - ASSERT(NCDVal_IsString(string)) - - size_t length = NCDVal_StringLength(string); - - // if string is empty do nothing, we can't make an empty chunk - if (length == 0) { - return 1; - } - - // init chunk - struct chunk *c = chunk_init(inst, length); - if (!c) { - return 0; - } - - // copy data to chunk - NCDVal_StringCopyOut(string, 0, length, c->data); - - return 1; -} - -static void instance_consume (struct instance *inst, size_t amount) -{ - instance_assert(inst); - ASSERT(amount <= inst->total_length - inst->offset) - - // nothing do to if amount is zero - if (amount == 0) { - return; - } - - // find chunk where the byte in the buffer resides - struct chunk *c = buffer_get_existing_chunk(inst->buf, inst->offset); - - // increment buffer offset - inst->offset += amount; - - // unreference chunks which no longer contain buffer contents - while (c && c->offset + c->length <= inst->offset) { - struct chunk *next_c = ChunksTree_GetNext(&inst->buf->chunks_tree, 0, c); - chunk_unref(c); - c = next_c; - } -} - -static struct buffer * buffer_init (struct instance *inst, NCDModuleInst *i) -{ - ASSERT(inst) - - // allocate structure - struct buffer *buf = BAlloc(sizeof(*buf)); - if (!buf) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - return NULL; - } - - // set instance pointer - buf->inst = inst; - - // init chunks tree - ChunksTree_Init(&buf->chunks_tree); - - // set refcnt to 0 (number of reference objects) - buf->refcnt = 0; - - return buf; -} - -static void buffer_free (struct buffer *buf) -{ - ASSERT(!buf->inst) - ASSERT(ChunksTree_IsEmpty(&buf->chunks_tree)) - ASSERT(buf->refcnt == 0) - - // free structure - BFree(buf); -} - -static void buffer_detach (struct buffer *buf) -{ - ASSERT(buf->inst) - struct instance *inst = buf->inst; - - // consume entire buffer to free any chunks that aren't referenced - instance_consume(inst, inst->total_length - inst->offset); - - // clear instance pointer - buf->inst = NULL; - - // free buffer if there are no more chunks - if (ChunksTree_IsEmpty(&buf->chunks_tree)) { - buffer_free(buf); - } -} - -static struct chunk * buffer_get_existing_chunk (struct buffer *buf, size_t offset) -{ - struct chunk *c = ChunksTree_GetLastLesserEqual(&buf->chunks_tree, 0, offset); - - ASSERT(c) - chunk_assert(c); - ASSERT(offset >= c->offset) - ASSERT(offset < c->offset + c->length) - - return c; -} - -static struct chunk * chunk_init (struct instance *inst, size_t length) -{ - instance_assert(inst); - ASSERT(length > 0) - struct buffer *buf = inst->buf; - - // make sure length is not too large - if (length >= SIZE_MAX - inst->total_length) { - ModuleLog(inst->i, BLOG_ERROR, "length overflow"); - return NULL; - } - - // allocate structure - bsize_t size = bsize_add(bsize_fromsize(sizeof(struct chunk)), bsize_fromsize(length)); - struct chunk *c = BAllocSize(size); - if (!c) { - ModuleLog(inst->i, BLOG_ERROR, "BAllocSize failed"); - return NULL; - } - - // set some members - c->buf = buf; - c->offset = inst->total_length; - c->length = length; - - // insert into chunks tree - int res = ChunksTree_Insert(&buf->chunks_tree, 0, c, NULL); - B_ASSERT_USE(res) - - // set reference count to 1 (referenced by buffer contents) - c->refcnt = 1; - - // increment buffer length - inst->total_length += length; - - chunk_assert(c); - return c; -} - -static void chunk_unref (struct chunk *c) -{ - chunk_assert(c); - - // decrement reference count - c->refcnt--; - - // if reference count is not yet zero, do nothing else - if (c->refcnt > 0) { - return; - } - - // remove from chunks tree - ChunksTree_Remove(&c->buf->chunks_tree, 0, c); - - // free structure - BFree(c); -} - -static void chunk_assert (struct chunk *c) -{ - ASSERT(c->buf) - ASSERT(c->length > 0) - ASSERT(!c->buf->inst || c->offset <= c->buf->inst->total_length) - ASSERT(!c->buf->inst || c->length <= c->buf->inst->total_length - c->offset) - ASSERT(c->refcnt > 0) -} - -static struct reference * reference_init (struct instance *inst, size_t offset, size_t length, NCDValComposedStringResource *out_resource) -{ - instance_assert(inst); - struct buffer *buf = inst->buf; - ASSERT(offset >= inst->offset) - ASSERT(offset <= inst->total_length) - ASSERT(length <= inst->total_length - offset) - ASSERT(length > 0) - ASSERT(out_resource) - - // check buffer reference count. This ensures we can always increment the - // chunk reference counts, below. We use (INT_MAX - 1) here because the buffer - // itself can also own references to chunks. - if (buf->refcnt == INT_MAX - 1) { - ModuleLog(inst->i, BLOG_ERROR, "too many references"); - return NULL; - } - - // allocate structure - struct reference *ref = BAlloc(sizeof(*ref)); - if (!ref) { - ModuleLog(inst->i, BLOG_ERROR, "BAlloc failed"); - return NULL; - } - - // find chunk where the first byte of the interval resides - struct chunk *c = buffer_get_existing_chunk(buf, offset); - - // set some members - ref->first_chunk = c; - ref->first_offset = offset - c->offset; - ref->length = length; - - // increment buffer reference count - buf->refcnt++; - - // reference chunks - do { - struct chunk *next_c = ChunksTree_GetNext(&buf->chunks_tree, 0, c); - ASSERT(c->refcnt < INT_MAX) - c->refcnt++; - c = next_c; - } while (c && c->offset < offset + length); - - // init reference target - BRefTarget_Init(&ref->ref_target, reference_ref_target_func_release); - - // write resource - out_resource->func_getptr = reference_resource_func_getptr; - out_resource->user = ref; - out_resource->ref_target = &ref->ref_target; - - reference_assert(ref); - return ref; -} - -static void reference_ref_target_func_release (BRefTarget *ref_target) -{ - struct reference *ref = UPPER_OBJECT(ref_target, struct reference, ref_target); - reference_assert(ref); - struct buffer *buf = ref->first_chunk->buf; - - // compute offset - size_t offset = ref->first_chunk->offset + ref->first_offset; - - // unreference chunks - struct chunk *c = ref->first_chunk; - do { - struct chunk *next_c = ChunksTree_GetNext(&buf->chunks_tree, 0, c); - chunk_unref(c); - c = next_c; - } while (c && c->offset < offset + ref->length); - - // decrement buffer reference count - ASSERT(buf->refcnt > 0) - buf->refcnt--; - - // free structure - BFree(ref); - - // if the instance has died and there are no more chunks, free buffer - if (!buf->inst && ChunksTree_IsEmpty(&buf->chunks_tree)) { - buffer_free(buf); - } -} - -static void reference_assert (struct reference *ref) -{ - ASSERT(ref->first_chunk) - ASSERT(ref->first_offset < ref->first_chunk->length) - ASSERT(ref->length > 0) - chunk_assert(ref->first_chunk); -} - -static void reference_resource_func_getptr (void *user, size_t offset, const char **out_data, size_t *out_length) -{ - struct reference *ref = user; - reference_assert(ref); - ASSERT(offset < ref->length) - ASSERT(out_data) - ASSERT(out_length) - - // compute absolute offset of request - size_t abs_offset = ref->first_chunk->offset + ref->first_offset + offset; - - // find chunk where the byte at the requested offset resides - struct chunk *c = buffer_get_existing_chunk(ref->first_chunk->buf, abs_offset); - - // compute offset of this byte within the chunk - size_t chunk_offset = abs_offset - c->offset; - - // return the data from this byte to the end of the chunk - *out_data = c->data + chunk_offset; - *out_length = c->length - chunk_offset; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // pass instance pointer to methods - NCDModuleInst_Backend_PassMemToMethods(i); - - // read arguments - NCDValRef data_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 0) && - !NCDVal_ListRead(params->args, 1, &data_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsInvalid(data_arg) && !NCDVal_IsString(data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // set offset and total length - o->offset = 0; - o->total_length = 0; - - // allocate buffer - o->buf = buffer_init(o, i); - if (!o->buf) { - goto fail0; - } - - // append initial data - if (!NCDVal_IsInvalid(data_arg)) { - if (!instance_append(o, data_arg)) { - goto fail1; - } - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - o->buf->inst = NULL; - buffer_free(o->buf); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - instance_assert(o); - - // detach buffer from instance - buffer_detach(o->buf); - - // die - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - instance_assert(o); - - if (name == NCD_STRING_EMPTY) { - if (o->total_length - o->offset == 0) { - *out = NCDVal_NewStringUninitialized(mem, 0); - } else { - NCDValComposedStringResource resource; - struct reference *ref = reference_init(o, o->offset, o->total_length - o->offset, &resource); - if (!ref) { - goto fail; - } - *out = NCDVal_NewComposedString(mem, resource, 0, ref->length); - BRefTarget_Deref(resource.ref_target); - } - return 1; - } - - if (name == NCD_STRING_LENGTH) { - *out = ncd_make_uintmax(mem, o->total_length - o->offset); - return 1; - } - - return 0; - -fail: - *out = NCDVal_NewInvalid(); - return 1; -} - -static void append_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef data_arg; - if (!NCDVal_ListRead(params->args, 1, &data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get instance - struct instance *inst = params->method_user; - - // append - if (!instance_append(inst, data_arg)) { - ModuleLog(i, BLOG_ERROR, "instance_append failed"); - goto fail0; - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void consume_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef amount_arg; - if (!NCDVal_ListRead(params->args, 1, &amount_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(amount_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse amount - uintmax_t amount; - if (!ncd_read_uintmax(amount_arg, &amount)) { - ModuleLog(i, BLOG_ERROR, "wrong amount"); - goto fail0; - } - - // get instance - struct instance *inst = params->method_user; - - // check amount - if (amount > inst->total_length - inst->offset) { - ModuleLog(i, BLOG_ERROR, "amount is more than buffer length"); - goto fail0; - } - - // consume - instance_consume(inst, amount); - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "buffer", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "buffer::append", - .func_new2 = append_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "buffer::consume", - .func_new2 = consume_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_buffer = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/buffer_chunks_tree.h b/external/badvpn_dns/ncd/modules/buffer_chunks_tree.h deleted file mode 100644 index c299d7c..0000000 --- a/external/badvpn_dns/ncd/modules/buffer_chunks_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME ChunksTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct chunk -#define SAVL_PARAM_TYPE_KEY size_t -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->offset, (entry2)->offset) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->offset) -#define SAVL_PARAM_MEMBER_NODE chunks_tree_node diff --git a/external/badvpn_dns/ncd/modules/call2.c b/external/badvpn_dns/ncd/modules/call2.c deleted file mode 100644 index f3e65ba..0000000 --- a/external/badvpn_dns/ncd/modules/call2.c +++ /dev/null @@ -1,498 +0,0 @@ -/** - * @file call2.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * call(string template, list args) - * - * Description: - * Calls a process template. The 'template' argument is the name of the process - * template to call, and the 'list' argument is a list of arguments for the - * process template. Calling a process template is roughly equivalent to placing - * the statements within that template into the place of call(), except for the - * points presented next. The 'template' argument can be a special value "<none>", - * which makes call() a no-op. - * - * The process created from the called template will be able to access the arguments - * that were given in the 'args' argument to call() via the '_argN' predefined\ - * objects (e.g. _arg0 for the first argumens), and also via '_args' for the entire - * argument list. - * - * The called process also will be able to access objects within the calling - * process as seen by the call() statement. However such any access needs to happen - * via a special '_caller' predefined object. For example, if there is a statement - * 'var("a") x;' somewhere above the call() statement, the called process can access - * it as '_caller.x'. - * - * Note that call() preserves backtracking semantics, i.e. when a statement within - * the called process goes down after having gone up, the behaviour really is as - * if the call() statement was replaced with the statements in the called template, - * (disregarding variable resolution). - * - * Because the template name is an argument, call() can be used for branching. - * For example, if we have an object 'x' with the value "true" or "false", a - * branch can be performed by defining two process templates, 'branch_true' - * and 'branch_false', and branching with the following code: - * - * concat("branch_", x) name; - * call(name, {}); - * - * Synopsis: - * call_with_caller_target(string template, list args, string caller_target) - * - * Description: - * Like call(), except that the target of the '_caller' predefined object is - * specified by the 'caller_target' argument. This is indented to be used from - * generic code for user-specified callbacks, allowing the user to easily refer to - * his own objects from inside the callback. - * - * The 'caller_target' must be a non-empty string referring to an actual object; - * there is no choice of 'caller_target' that would make call_with_caller_target() - * equivalent to call(). - * - * Synopsis: - * embcall2_multif(string cond1, string template1, ..., [string else_template]) - * - * Description: - * This is an internal command used to implement the 'If' clause. The arguments - * are pairs of (cond, template), where 'cond' is a condition in form of a string, - * and 'template' is the name of the process template for this condition. The - * template corresponding to the first condition equal to "true" is called; if - * there is no true condition, either the template 'else_template' is called, - * if it is provided, or nothing is performed, if 'else_template' is not provided. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_call2.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_WORKING 1 -#define STATE_UP 2 -#define STATE_WAITING 3 -#define STATE_TERMINATING 4 -#define STATE_NONE 5 - -#define NUM_STATIC_NAMES 4 - -struct instance { - NCDModuleInst *i; - NCDModuleProcess process; - int state; -}; - -struct instance_with_caller_target { - struct instance base; - NCD_string_id_t *dynamic_names; - size_t num_names; - NCD_string_id_t static_names[NUM_STATIC_NAMES]; -}; - -#define NAMES_PARAM_NAME CallNames -#define NAMES_PARAM_TYPE struct instance_with_caller_target -#define NAMES_PARAM_MEMBER_DYNAMIC_NAMES dynamic_names -#define NAMES_PARAM_MEMBER_STATIC_NAMES static_names -#define NAMES_PARAM_MEMBER_NUM_NAMES num_names -#define NAMES_PARAM_NUM_STATIC_NAMES NUM_STATIC_NAMES -#include <ncd/extra/make_fast_names.h> - -static void process_handler_event (NCDModuleProcess *process, int event); -static int process_func_getspecialobj_embed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int process_func_getspecialobj_noembed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int process_func_getspecialobj_with_caller_target (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static int caller_obj_func_getobj_with_caller_target (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static void func_new_templ (void *vo, NCDModuleInst *i, NCDValRef template_name, NCDValRef args, int embed); -static void instance_free (struct instance *o); - -static void process_handler_event (NCDModuleProcess *process, int event) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == STATE_WORKING) - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state up - o->state = STATE_UP; - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(o->state == STATE_UP) - - // signal down - NCDModuleInst_Backend_Down(o->i); - - // set state waiting - o->state = STATE_WAITING; - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == STATE_TERMINATING) - - // die finally - instance_free(o); - return; - } break; - - default: ASSERT(0); - } -} - -static int process_func_getspecialobj_embed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static int process_func_getspecialobj_noembed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj); - return 1; - } - - return 0; -} - -static int process_func_getspecialobj_with_caller_target (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj_with_caller_target); - return 1; - } - - return 0; -} - -static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = NCDObject_DataPtr(obj); - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static int caller_obj_func_getobj_with_caller_target (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance_with_caller_target *o_ch = NCDObject_DataPtr(obj); - ASSERT(o_ch->num_names > 0) - - NCD_string_id_t *names = CallNames_GetNames(o_ch); - - NCDObject object; - if (!NCDModuleInst_Backend_GetObj(o_ch->base.i, names[0], &object)) { - return 0; - } - - NCDObject obj2; - if (!NCDObject_ResolveObjExprCompact(&object, names + 1, o_ch->num_names - 1, &obj2)) { - return 0; - } - - if (name == NCD_STRING_EMPTY) { - *out_object = obj2; - return 1; - } - - return NCDObject_GetObj(&obj2, name, out_object); -} - -static void func_new_templ (void *vo, NCDModuleInst *i, NCDValRef template_name, NCDValRef args, int embed) -{ - ASSERT(NCDVal_IsInvalid(template_name) || NCDVal_IsString(template_name)) - ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args)) - ASSERT(embed == !!embed) - - struct instance *o = vo; - o->i = i; - - if (NCDVal_IsInvalid(template_name) || ncd_is_none(template_name)) { - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state none - o->state = STATE_NONE; - } else { - // create process - if (!NCDModuleProcess_InitValue(&o->process, o->i, template_name, args, process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set special functions - if (embed) { - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj_embed); - } else { - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj_noembed); - } - - // set state working - o->state = STATE_WORKING; - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - // free process - if (o->state != STATE_NONE) { - NCDModuleProcess_Free(&o->process); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_new_call (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef template_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 2, &template_arg, &args_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(template_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - func_new_templ(vo, i, template_arg, args_arg, 0); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_call_with_caller_target (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - struct instance_with_caller_target *o_ct = vo; - o->i = i; - - NCDValRef template_arg; - NCDValRef args_arg; - NCDValRef caller_target_arg; - if (!NCDVal_ListRead(params->args, 3, &template_arg, &args_arg, &caller_target_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(template_arg) || !NCDVal_IsList(args_arg) || !NCDVal_IsString(caller_target_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - NCDValContString cts; - if (!NCDVal_StringContinuize(caller_target_arg, &cts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringContinuize failed"); - goto fail0; - } - - int res = CallNames_InitNames(o_ct, i->params->iparams->string_index, cts.data, NCDVal_StringLength(caller_target_arg)); - NCDValContString_Free(&cts); - if (!res) { - ModuleLog(i, BLOG_ERROR, "CallerNames_InitNames failed"); - goto fail0; - } - - if (ncd_is_none(template_arg)) { - // signal up - NCDModuleInst_Backend_Up(i); - - // set state none - o->state = STATE_NONE; - } else { - // create process - if (!NCDModuleProcess_InitValue(&o->process, i, template_arg, args_arg, process_handler_event)) { - ModuleLog(i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail1; - } - - // set special functions - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj_with_caller_target); - - // set state working - o->state = STATE_WORKING; - } - - return; - -fail1: - CallNames_FreeNames(o_ct); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_embcall_multif (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef args = params->args; - - NCDValRef template_value = NCDVal_NewInvalid(); - - size_t count = NCDVal_ListCount(args); - size_t j = 0; - - while (j < count) { - NCDValRef arg = NCDVal_ListGet(args, j); - - if (j == count - 1) { - if (!NCDVal_IsString(arg)) { - ModuleLog(i, BLOG_ERROR, "bad arguments"); - goto fail0; - } - - template_value = arg; - break; - } - - NCDValRef arg2 = NCDVal_ListGet(args, j + 1); - - if (!NCDVal_IsString(arg) || !NCDVal_IsString(arg2)) { - ModuleLog(i, BLOG_ERROR, "bad arguments"); - goto fail0; - } - - if (ncd_read_boolean(arg)) { - template_value = arg2; - break; - } - - j += 2; - } - - func_new_templ(vo, i, template_value, NCDVal_NewInvalid(), 1); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(o->state != STATE_TERMINATING) - - // if none, die now - if (o->state == STATE_NONE) { - instance_free(o); - return; - } - - // request process to terminate - NCDModuleProcess_Terminate(&o->process); - - // set state terminating - o->state = STATE_TERMINATING; -} - -static void func_die_with_caller_target (void *vo) -{ - struct instance_with_caller_target *o_ct = vo; - - CallNames_FreeNames(o_ct); - - func_die(vo); -} - -static void func_clean (void *vo) -{ - struct instance *o = vo; - if (o->state != STATE_WAITING) { - return; - } - - // allow process to continue - NCDModuleProcess_Continue(&o->process); - - // set state working - o->state = STATE_WORKING; -} - -static int func_getobj (void *vo, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = vo; - - if (o->state == STATE_NONE) { - return 0; - } - - return NCDModuleProcess_GetObj(&o->process, name, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "call", - .func_new2 = func_new_call, - .func_die = func_die, - .func_clean = func_clean, - .func_getobj = func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS, - .alloc_size = sizeof(struct instance) - }, { - .type = "call_with_caller_target", - .func_new2 = func_new_call_with_caller_target, - .func_die = func_die_with_caller_target, - .func_clean = func_clean, - .func_getobj = func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS, - .alloc_size = sizeof(struct instance_with_caller_target) - }, { - .type = "embcall2_multif", - .func_new2 = func_new_embcall_multif, - .func_die = func_die, - .func_clean = func_clean, - .func_getobj = func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN|NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_call2 = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/choose.c b/external/badvpn_dns/ncd/modules/choose.c deleted file mode 100644 index 23f8bbe..0000000 --- a/external/badvpn_dns/ncd/modules/choose.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file choose.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Multiple value selection based on boolean conditions. - * - * Synopsis: - * choose({{string cond1, result1}, ..., {string condN, resultN}}, default_result) - * - * Variables: - * (empty) - If cond1="true" then result1, - * else if cond2="true" then result2, - * ..., - * else default_result. - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_choose.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValRef result; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef arg_choices; - NCDValRef arg_default_result; - if (!NCDVal_ListRead(params->args, 2, &arg_choices, &arg_default_result)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(arg_choices)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // iterate choices - int have_result = 0; - size_t count = NCDVal_ListCount(arg_choices); - for (size_t j = 0; j < count; j++) { - NCDValRef c = NCDVal_ListGet(arg_choices, j); - - // check choice type - if (!NCDVal_IsList(c)) { - ModuleLog(i, BLOG_ERROR, "wrong choice type"); - goto fail0; - } - - // read choice - NCDValRef c_cond; - NCDValRef c_result; - if (!NCDVal_ListRead(c, 2, &c_cond, &c_result)) { - ModuleLog(i, BLOG_ERROR, "wrong choice contents arity"); - goto fail0; - } - if (!NCDVal_IsString(c_cond)) { - ModuleLog(i, BLOG_ERROR, "wrong choice condition type"); - goto fail0; - } - - // update result - if (!have_result && ncd_read_boolean(c_cond)) { - o->result = c_result; - have_result = 1; - } - } - - // default? - if (!have_result) { - o->result = arg_default_result; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewCopy(mem, o->result); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "choose", - .func_new2 = func_new, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_choose = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/command_template.c b/external/badvpn_dns/ncd/modules/command_template.c deleted file mode 100644 index 6eb92f6..0000000 --- a/external/badvpn_dns/ncd/modules/command_template.c +++ /dev/null @@ -1,218 +0,0 @@ -/** - * @file command_template.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> - -#include <ncd/modules/command_template.h> - -#define STATE_ADDING_LOCK 1 -#define STATE_ADDING 2 -#define STATE_ADDING_NEED_DELETE 3 -#define STATE_DONE 4 -#define STATE_DELETING_LOCK 5 -#define STATE_DELETING 6 - -static void lock_handler (command_template_instance *o); -static void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status); -static void free_template (command_template_instance *o, int is_error); - -static void lock_handler (command_template_instance *o) -{ - ASSERT(o->state == STATE_ADDING_LOCK || o->state == STATE_DELETING_LOCK) - ASSERT(!(o->state == STATE_ADDING_LOCK) || o->do_exec) - ASSERT(!(o->state == STATE_DELETING_LOCK) || o->undo_exec) - - if (o->state == STATE_ADDING_LOCK) { - // start process - if (!BProcess_Init(&o->process, o->i->params->iparams->manager, (BProcess_handler)process_handler, o, o->do_exec, CmdLine_Get(&o->do_cmdline), NULL)) { - NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "BProcess_Init failed"); - free_template(o, 1); - return; - } - - // set state - o->state = STATE_ADDING; - } else { - // start process - if (!BProcess_Init(&o->process, o->i->params->iparams->manager, (BProcess_handler)process_handler, o, o->undo_exec, CmdLine_Get(&o->undo_cmdline), NULL)) { - NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "BProcess_Init failed"); - free_template(o, 1); - return; - } - - // set state - o->state = STATE_DELETING; - } -} - -static void process_handler (command_template_instance *o, int normally, uint8_t normally_exit_status) -{ - ASSERT(o->state == STATE_ADDING || o->state == STATE_ADDING_NEED_DELETE || o->state == STATE_DELETING) - - // release lock - BEventLockJob_Release(&o->elock_job); - - // free process - BProcess_Free(&o->process); - - if (!normally || normally_exit_status != 0) { - NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "command failed"); - - free_template(o, 1); - return; - } - - switch (o->state) { - case STATE_ADDING: { - // set state - o->state = STATE_DONE; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } break; - - case STATE_ADDING_NEED_DELETE: { - if (o->undo_exec) { - // wait for lock - BEventLockJob_Wait(&o->elock_job); - - // set state - o->state = STATE_DELETING_LOCK; - } else { - free_template(o, 0); - return; - } - } break; - - case STATE_DELETING: { - // finish - free_template(o, 0); - return; - } break; - } -} - -void command_template_new (command_template_instance *o, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, command_template_build_cmdline build_cmdline, command_template_free_func free_func, void *user, int blog_channel, BEventLock *elock) -{ - // init arguments - o->i = i; - o->free_func = free_func; - o->user = user; - o->blog_channel = blog_channel; - - // build do command - if (!build_cmdline(o->i, params->args, 0, &o->do_exec, &o->do_cmdline)) { - NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "build_cmdline do callback failed"); - goto fail0; - } - - // build undo command - if (!build_cmdline(o->i, params->args, 1, &o->undo_exec, &o->undo_cmdline)) { - NCDModuleInst_Backend_Log(o->i, o->blog_channel, BLOG_ERROR, "build_cmdline undo callback failed"); - goto fail1; - } - - // init lock job - BEventLockJob_Init(&o->elock_job, elock, (BEventLock_handler)lock_handler, o); - - if (o->do_exec) { - // wait for lock - BEventLockJob_Wait(&o->elock_job); - - // set state - o->state = STATE_ADDING_LOCK; - } else { - // set state - o->state = STATE_DONE; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } - - return; - -fail1: - if (o->do_exec) { - free(o->do_exec); - CmdLine_Free(&o->do_cmdline); - } -fail0: - o->free_func(o->user, 1); -} - -static void free_template (command_template_instance *o, int is_error) -{ - // free lock job - BEventLockJob_Free(&o->elock_job); - - // free undo command - if (o->undo_exec) { - free(o->undo_exec); - CmdLine_Free(&o->undo_cmdline); - } - - // free do command - if (o->do_exec) { - free(o->do_exec); - CmdLine_Free(&o->do_cmdline); - } - - // call free function - o->free_func(o->user, is_error); -} - -void command_template_die (command_template_instance *o) -{ - ASSERT(o->state == STATE_ADDING_LOCK || o->state == STATE_ADDING || o->state == STATE_DONE) - - switch (o->state) { - case STATE_ADDING_LOCK: { - free_template(o, 0); - return; - } break; - - case STATE_ADDING: { - // set state - o->state = STATE_ADDING_NEED_DELETE; - } break; - - case STATE_DONE: { - if (o->undo_exec) { - // wait for lock - BEventLockJob_Wait(&o->elock_job); - - // set state - o->state = STATE_DELETING_LOCK; - } else { - free_template(o, 0); - return; - } - } break; - } -} diff --git a/external/badvpn_dns/ncd/modules/command_template.h b/external/badvpn_dns/ncd/modules/command_template.h deleted file mode 100644 index e1228ae..0000000 --- a/external/badvpn_dns/ncd/modules/command_template.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file command_template.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Template for a module which executes a command to start and stop. - * The command is executed asynchronously. - */ - -#ifndef BADVPN_NCD_MODULES_COMMAND_TEMPLATE_H -#define BADVPN_NCD_MODULES_COMMAND_TEMPLATE_H - -#include <misc/cmdline.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/BEventLock.h> - -typedef int (*command_template_build_cmdline) (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl); -typedef void (*command_template_free_func) (void *user, int is_error); - -typedef struct { - NCDModuleInst *i; - command_template_free_func free_func; - void *user; - int blog_channel; - char *do_exec; - CmdLine do_cmdline; - char *undo_exec; - CmdLine undo_cmdline; - BEventLockJob elock_job; - int state; - BProcess process; -} command_template_instance; - -void command_template_new (command_template_instance *o, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, command_template_build_cmdline build_cmdline, command_template_free_func free_func, void *user, int blog_channel, BEventLock *elock); -void command_template_die (command_template_instance *o); - -#endif diff --git a/external/badvpn_dns/ncd/modules/concat.c b/external/badvpn_dns/ncd/modules/concat.c deleted file mode 100644 index e71e69e..0000000 --- a/external/badvpn_dns/ncd/modules/concat.c +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @file concat.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * concat([string elem ...]) - * concatv(list strings) - * - * Description: - * Concatenates zero or more strings. The result is available as the empty - * string variable. For concatv(), the strings are provided as a single - * list argument. For concat(), the strings are provided as arguments - * themselves. - */ - -#include <stddef.h> -#include <string.h> - -#include <misc/balloc.h> -#include <misc/offset.h> -#include <misc/BRefTarget.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_concat.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct result { - BRefTarget ref_target; - size_t length; - char data[]; -}; - -struct instance { - NCDModuleInst *i; - struct result *result; -}; - -static void result_ref_target_func_release (BRefTarget *ref_target) -{ - struct result *result = UPPER_OBJECT(ref_target, struct result, ref_target); - - BFree(result); -} - -static void new_concat_common (void *vo, NCDModuleInst *i, NCDValRef list) -{ - ASSERT(NCDVal_IsList(list)) - struct instance *o = vo; - o->i = i; - - size_t count = NCDVal_ListCount(list); - bsize_t result_size = bsize_fromsize(sizeof(struct result)); - - // check arguments and compute result size - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(list, j); - - if (!NCDVal_IsString(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - result_size = bsize_add(result_size, bsize_fromsize(NCDVal_StringLength(arg))); - } - - // allocate result - o->result = BAllocSize(result_size); - if (!o->result) { - ModuleLog(i, BLOG_ERROR, "BAllocSize failed"); - goto fail0; - } - - // init ref target - BRefTarget_Init(&o->result->ref_target, result_ref_target_func_release); - - // copy data to result - o->result->length = 0; - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(list, j); - b_cstring cstr = NCDVal_StringCstring(arg); - b_cstring_copy_to_buf(cstr, 0, cstr.length, o->result->data + o->result->length); - o->result->length += cstr.length; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_concat (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_concat_common(vo, i, params->args); -} - -static void func_new_concatv (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef list_arg; - if (!NCDVal_ListRead(params->args, 1, &list_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(list_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - new_concat_common(vo, i, list_arg); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // release result reference - BRefTarget_Deref(&o->result->ref_target); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewExternalString(mem, o->result->data, o->result->length, &o->result->ref_target); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "concat", - .func_new2 = func_new_concat, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "concatv", - .func_new2 = func_new_concatv, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_concat = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/daemon.c b/external/badvpn_dns/ncd/modules/daemon.c deleted file mode 100644 index 3dac4c5..0000000 --- a/external/badvpn_dns/ncd/modules/daemon.c +++ /dev/null @@ -1,296 +0,0 @@ -/** - * @file daemon.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Runs a program in the background, restarting it if it crashes. - * On deinitialization, sends SIGTERM to the daemon and waits for it to terminate - * (unless it's crashed at the time). - * - * Synopsis: - * daemon(list(string) cmd [, map options]) - * - * Arguments: - * cmd - Command for the daemon. The first element is the full path - * to the executable, other elements are command line arguments (excluding - * the zeroth argument). - * options - Map of options: - * "keep_stdout":"true" - Start the program with the same stdout as the NCD process. - * "keep_stderr":true" - Start the program with the same stderr as the NCD process. - * "do_setsid":"true" - Call setsid() in the child before exec. This is needed to - * start the 'agetty' program. - * "username":username_string - Start the process under the permissions of the - * specified user. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <misc/cmdline.h> -#include <misc/strdup.h> -#include <system/BProcess.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/NCDBProcessOpts.h> - -#include <generated/blog_channel_ncd_daemon.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define RETRY_TIME 10000 - -#define STATE_RETRYING 1 -#define STATE_RUNNING 2 -#define STATE_RUNNING_DIE 3 - -struct instance { - NCDModuleInst *i; - NCDValRef cmd_arg; - NCDBProcessOpts opts; - BTimer timer; - BProcess process; - int state; -}; - -static int build_cmdline (NCDModuleInst *i, NCDValRef cmd_arg, char **exec, CmdLine *cl); -static void start_process (struct instance *o); -static void timer_handler (struct instance *o); -static void process_handler (struct instance *o, int normally, uint8_t normally_exit_status); -static void instance_free (struct instance *o); - -static int build_cmdline (NCDModuleInst *i, NCDValRef cmd_arg, char **exec, CmdLine *cl) -{ - ASSERT(!NCDVal_IsInvalid(cmd_arg)) - - if (!NCDVal_IsList(cmd_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - size_t count = NCDVal_ListCount(cmd_arg); - - // read exec - if (count == 0) { - ModuleLog(i, BLOG_ERROR, "missing executable name"); - goto fail0; - } - NCDValRef exec_arg = NCDVal_ListGet(cmd_arg, 0); - if (!NCDVal_IsStringNoNulls(exec_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - if (!(*exec = ncd_strdup(exec_arg))) { - ModuleLog(i, BLOG_ERROR, "ncd_strdup failed"); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add header - if (!CmdLine_Append(cl, *exec)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // add additional arguments - for (size_t j = 1; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(cmd_arg, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail2; - } - - b_cstring cstr = NCDVal_StringCstring(arg); - if (!CmdLine_AppendCstring(cl, cstr, 0, cstr.length)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_AppendCstring failed"); - goto fail2; - } - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static void start_process (struct instance *o) -{ - // build cmdline - char *exec; - CmdLine cl; - if (!build_cmdline(o->i, o->cmd_arg, &exec, &cl)) { - goto fail; - } - - // start process - struct BProcess_params p_params = NCDBProcessOpts_GetParams(&o->opts); - int res = BProcess_Init2(&o->process, o->i->params->iparams->manager, (BProcess_handler)process_handler, o, exec, CmdLine_Get(&cl), p_params); - CmdLine_Free(&cl); - free(exec); - - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "BProcess_Init2 failed"); - goto fail; - } - - // set state running - o->state = STATE_RUNNING; - return; - -fail: - // start timer - BReactor_SetTimer(o->i->params->iparams->reactor, &o->timer); - - // set state retrying - o->state = STATE_RETRYING; -} - -static void timer_handler (struct instance *o) -{ - ASSERT(o->state == STATE_RETRYING) - - ModuleLog(o->i, BLOG_INFO, "restarting after crash"); - - start_process(o); -} - -static void process_handler (struct instance *o, int normally, uint8_t normally_exit_status) -{ - ASSERT(o->state == STATE_RUNNING || o->state == STATE_RUNNING_DIE) - - // free process - BProcess_Free(&o->process); - - // if we were requested to die, die now - if (o->state == STATE_RUNNING_DIE) { - instance_free(o); - return; - } - - BLog(BLOG_ERROR, "daemon crashed"); - - // start timer - BReactor_SetTimer(o->i->params->iparams->reactor, &o->timer); - - // set state retrying - o->state = STATE_RETRYING; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef opts_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &o->cmd_arg) && - !NCDVal_ListRead(params->args, 2, &o->cmd_arg, &opts_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init options - if (!NCDBProcessOpts_Init(&o->opts, opts_arg, NULL, NULL, i, BLOG_CURRENT_CHANNEL)) { - goto fail0; - } - - // init timer - BTimer_Init(&o->timer, RETRY_TIME, (BTimer_handler)timer_handler, o); - - // signal up - NCDModuleInst_Backend_Up(i); - - // try starting process - start_process(o); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - // free timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - // free options - NCDBProcessOpts_Free(&o->opts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(o->state != STATE_RUNNING_DIE) - - // if not running, die immediately - if (o->state == STATE_RETRYING) { - instance_free(o); - return; - } - - // request termination - BProcess_Terminate(&o->process); - - // set state running die - o->state = STATE_RUNNING_DIE; -} - -static struct NCDModule modules[] = { - { - .type = "daemon", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_daemon = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/depend.c b/external/badvpn_dns/ncd/modules/depend.c deleted file mode 100644 index 5019cf4..0000000 --- a/external/badvpn_dns/ncd/modules/depend.c +++ /dev/null @@ -1,452 +0,0 @@ -/** - * @file depend.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Dependencies module. - * - * Synopsis: provide(string name) - * Description: Provides a resource. On initialization, transitions any depend()-s - * waiting for this resource to UP state. On deinitialization, transitions - * depend()-s using this resource to DOWN state, and waits for all of them to - * receive the clean signal (i.e. wait for all of the statements following them in - * their processes to terminate). Initialization fails if a provide() already - * exists for this resource (including if it is being deinitialized). - * - * Synopsis: provide_event(string name) - * Description: Like provide(), but if another provide() already exists for this - * resource, initialization does not fail, and the request is queued to the active - * provide() for this resource. When an active provide() disappears that has - * queued provide()-s, one of them is promoted to be the active provide() for this - * resource, and the remaining queue is transferred to it. - * (mentions of provide() in this text also apply to provide_event()) - * - * Synopsis: depend(string name) - * Description: Depends on a resource. Is in UP state when a provide() - * for this resource is available, and in DOWN state when it is not (either - * it does not exist or is being terminated). - * Variables: Provides variables available from the corresponding provide, - * ("modname.varname" or "modname"). - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <structure/LinkedList1.h> -#include <structure/LinkedList3.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_depend.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -struct provide { - NCDModuleInst *i; - const char *name; - size_t name_len; - int is_queued; - union { - struct { - LinkedList3Node queued_node; // node in list which begins with provide.queued_provides_firstnode - }; - struct { - LinkedList1Node provides_node; // node in provides - LinkedList1 depends; - LinkedList3Node queued_provides_firstnode; - int dying; - }; - }; -}; - -struct depend { - NCDModuleInst *i; - const char *name; - size_t name_len; - struct provide *p; - LinkedList1Node node; -}; - -struct global { - LinkedList1 provides; - LinkedList1 free_depends; -}; - -static struct provide * find_provide (struct global *g, const char *name, size_t name_len) -{ - for (LinkedList1Node *n = LinkedList1_GetFirst(&g->provides); n; n = LinkedList1Node_Next(n)) { - struct provide *p = UPPER_OBJECT(n, struct provide, provides_node); - ASSERT(!p->is_queued) - - if (p->name_len == name_len && !memcmp(p->name, name, name_len)) { - return p; - } - } - - return NULL; -} - -static void provide_promote (struct provide *o) -{ - struct global *g = ModuleGlobal(o->i); - ASSERT(!find_provide(g, o->name, o->name_len)) - - // set not queued - o->is_queued = 0; - - // insert to provides list - LinkedList1_Append(&g->provides, &o->provides_node); - - // init depends list - LinkedList1_Init(&o->depends); - - // set not dying - o->dying = 0; - - // attach free depends with this name - LinkedList1Node *n = LinkedList1_GetFirst(&g->free_depends); - while (n) { - LinkedList1Node *next = LinkedList1Node_Next(n); - struct depend *d = UPPER_OBJECT(n, struct depend, node); - ASSERT(!d->p) - - if (d->name_len != o->name_len || memcmp(d->name, o->name, d->name_len)) { - n = next; - continue; - } - - // remove from free depends list - LinkedList1_Remove(&g->free_depends, &d->node); - - // insert to provide's list - LinkedList1_Append(&o->depends, &d->node); - - // set provide - d->p = o; - - // signal up - NCDModuleInst_Backend_Up(d->i); - - n = next; - } -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - // allocate global state structure - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - // set group state pointer - group->group_state = g; - - // init provides list - LinkedList1_Init(&g->provides); - - // init free depends list - LinkedList1_Init(&g->free_depends); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - ASSERT(LinkedList1_IsEmpty(&g->free_depends)) - ASSERT(LinkedList1_IsEmpty(&g->provides)) - - // free global state structure - BFree(g); -} - -static void provide_func_new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int event) -{ - struct global *g = ModuleGlobal(i); - struct provide *o = vo; - o->i = i; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->name = NCDVal_StringData(name_arg); - o->name_len = NCDVal_StringLength(name_arg); - - // signal up. - // This comes above provide_promote(), so that effects on related depend statements are - // computed before this process advances, avoiding problems like failed variable resolutions. - NCDModuleInst_Backend_Up(o->i); - - // check for existing provide with this name - struct provide *ep = find_provide(g, o->name, o->name_len); - if (ep) { - ASSERT(!ep->is_queued) - - if (!event) { - ModuleLog(o->i, BLOG_ERROR, "a provide with this name already exists"); - goto fail0; - } - - // set queued - o->is_queued = 1; - - // insert to existing provide's queued provides list - LinkedList3Node_InitAfter(&o->queued_node, &ep->queued_provides_firstnode); - } else { - // init first node for queued provides list - LinkedList3Node_InitLonely(&o->queued_provides_firstnode); - - // promote provide - provide_promote(o); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - provide_func_new_templ(vo, i, params, 0); -} - -static void provide_event_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - provide_func_new_templ(vo, i, params, 1); -} - -static void provide_free (struct provide *o) -{ - struct global *g = ModuleGlobal(o->i); - ASSERT(o->is_queued || LinkedList1_IsEmpty(&o->depends)) - - if (o->is_queued) { - // remove from existing provide's queued provides list - LinkedList3Node_Free(&o->queued_node); - } else { - // remove from provides list - LinkedList1_Remove(&g->provides, &o->provides_node); - - // if we have provides queued, promote the first one - if (LinkedList3Node_Next(&o->queued_provides_firstnode)) { - // get first queued provide - struct provide *qp = UPPER_OBJECT(LinkedList3Node_Next(&o->queued_provides_firstnode), struct provide, queued_node); - ASSERT(qp->is_queued) - - // make it the head of the queued provides list - LinkedList3Node_Free(&qp->queued_node); - LinkedList3Node_InitAfter(&qp->queued_provides_firstnode, &o->queued_provides_firstnode); - LinkedList3Node_Free(&o->queued_provides_firstnode); - - // promote provide - provide_promote(qp); - } - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void provide_func_die (void *vo) -{ - struct provide *o = vo; - ASSERT(o->is_queued || !o->dying) - - // if we are queued or have no depends, die immediately - if (o->is_queued || LinkedList1_IsEmpty(&o->depends)) { - provide_free(o); - return; - } - - // set dying - o->dying = 1; - - // signal our depends down - for (LinkedList1Node *n = LinkedList1_GetFirst(&o->depends); n; n = LinkedList1Node_Next(n)) { - struct depend *d = UPPER_OBJECT(n, struct depend, node); - ASSERT(d->p == o) - - // signal down - NCDModuleInst_Backend_Down(d->i); - } -} - -static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct depend *o = vo; - o->i = i; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->name = NCDVal_StringData(name_arg); - o->name_len = NCDVal_StringLength(name_arg); - - // find a provide with our name - struct provide *p = find_provide(g, o->name, o->name_len); - ASSERT(!p || !p->is_queued) - - if (p && !p->dying) { - // insert to provide's list - LinkedList1_Append(&p->depends, &o->node); - - // set provide - o->p = p; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } else { - // insert to free depends list - LinkedList1_Append(&g->free_depends, &o->node); - - // set no provide - o->p = NULL; - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void depend_free (struct depend *o) -{ - struct global *g = ModuleGlobal(o->i); - ASSERT(!o->p || !o->p->is_queued) - - if (o->p) { - // remove from provide's list - LinkedList1_Remove(&o->p->depends, &o->node); - - // if provide is dying and is empty, let it die - if (o->p->dying && LinkedList1_IsEmpty(&o->p->depends)) { - provide_free(o->p); - } - } else { - // remove free depends list - LinkedList1_Remove(&g->free_depends, &o->node); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void depend_func_die (void *vo) -{ - struct depend *o = vo; - - depend_free(o); -} - -static void depend_func_clean (void *vo) -{ - struct depend *o = vo; - struct global *g = ModuleGlobal(o->i); - ASSERT(!o->p || !o->p->is_queued) - - if (!(o->p && o->p->dying)) { - return; - } - - struct provide *p = o->p; - - // remove from provide's list - LinkedList1_Remove(&p->depends, &o->node); - - // insert to free depends list - LinkedList1_Append(&g->free_depends, &o->node); - - // set no provide - o->p = NULL; - - // if provide is empty, let it die - if (LinkedList1_IsEmpty(&p->depends)) { - provide_free(p); - } -} - -static int depend_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct depend *o = vo; - ASSERT(!o->p || !o->p->is_queued) - - if (!o->p) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(o->p->i, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "provide", - .func_new2 = provide_func_new, - .func_die = provide_func_die, - .alloc_size = sizeof(struct provide) - }, { - .type = "provide_event", - .func_new2 = provide_event_func_new, - .func_die = provide_func_die, - .alloc_size = sizeof(struct provide) - }, { - .type = "depend", - .func_new2 = depend_func_new, - .func_die = depend_func_die, - .func_clean = depend_func_clean, - .func_getobj = depend_func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, - .alloc_size = sizeof(struct depend) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_depend = { - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree, - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/depend_scope.c b/external/badvpn_dns/ncd/modules/depend_scope.c deleted file mode 100644 index 1a814a0..0000000 --- a/external/badvpn_dns/ncd/modules/depend_scope.c +++ /dev/null @@ -1,466 +0,0 @@ -/** - * @file depend_scope.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Multiple-option dependencies module. - * - * Synopsis: - * depend_scope() - * - * Description: - * A scope for dependency names. Any dependency names used in provide() and depend() - * methods on this object are local to this object. Contrast to the multidepend module, - * which provides the same functionality as this module, but with a single global - * dependency name scope. - * - * Synopsis: - * depend_scope::provide(name) - * - * Arguments: - * name - provider identifier - * - * Description: - * Satisfies a dependency. - * If any depend()'s get immediately bound to this provide(), - * the side effects of those first happen, and only then can the process of this - * provide() continue. - * When provide() is requested to deinitialize, if there are any depend()'s bound, - * provide() will not finish deinitializing until all the processes containing the - * bound depend()'s have backtracked to the point of the corresponding depend(). - * More specifically, when backtracking has finished for the last bound depend(), - * first the immediate effects of the provide() finshing deinitialization will happen, - * and only then will the depend() attempt to rebind. (If the converse was true, the - * depend() could rebind, but when deinitialization of the provide()'s process - * continues, lose this binding. See ncd/tests/depend_scope.ncd .) - * - * Synopsis: - * depend_scope::depend(list names) - * - * Arguments: - * names - list of provider identifiers. Names more to the beginning are considered - * more desirable. - * - * Description: - * Binds to the provide() providing one of the specified dependency names which is most - * desirable. If there is no provide() providing any of the given dependency names, - * waits and binds when one becomes available. - * If the depend() is bound to a provide(), and the bound provide() is requested to - * deinitize, or a more desirable provide() becomes available, the depend() statement - * will go down (triggering backtracking), wait for backtracking to finish, and then - * try to bind to a provide() again, as if it was just initialized. - * When depend() is requested to deinitialize, it deinitializes immediately. - * - * Attributes: - * Exposes objects as seen from the corresponding provide. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/BRefTarget.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_depend_scope.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct scope { - BRefTarget ref_target; - LinkedList1 provides_list; - LinkedList1 depends_list; -}; - -struct scope_instance { - NCDModuleInst *i; - struct scope *scope; -}; - -struct provide { - NCDModuleInst *i; - struct scope *scope; - NCDValRef name; - LinkedList1Node provides_list_node; - LinkedList1 depends_list; - int dying; -}; - -struct depend { - NCDModuleInst *i; - struct scope *scope; - NCDValRef names; - LinkedList1Node depends_list_node; - struct provide *provide; - LinkedList1Node provide_depends_list_node; - int provide_collapsing; -}; - -static struct provide * find_provide (struct scope *o, NCDValRef name) -{ - for (LinkedList1Node *ln = LinkedList1_GetFirst(&o->provides_list); ln; ln = LinkedList1Node_Next(ln)) { - struct provide *provide = UPPER_OBJECT(ln, struct provide, provides_list_node); - ASSERT(provide->scope == o) - if (NCDVal_Compare(provide->name, name) == 0) { - return provide; - } - } - - return NULL; -} - -static struct provide * depend_find_best_provide (struct depend *o) -{ - size_t count = NCDVal_ListCount(o->names); - - for (size_t j = 0; j < count; j++) { - NCDValRef name = NCDVal_ListGet(o->names, j); - struct provide *provide = find_provide(o->scope, name); - if (provide && !provide->dying) { - return provide; - } - } - - return NULL; -} - -static void depend_update (struct depend *o) -{ - // if we're collapsing, do nothing - if (o->provide && o->provide_collapsing) { - return; - } - - // find best provide - struct provide *best_provide = depend_find_best_provide(o); - ASSERT(!best_provide || !best_provide->dying) - - // has anything changed? - if (best_provide == o->provide) { - return; - } - - if (o->provide) { - // set collapsing - o->provide_collapsing = 1; - - // signal down - NCDModuleInst_Backend_Down(o->i); - } else { - // insert to provide's list - LinkedList1_Append(&best_provide->depends_list, &o->provide_depends_list_node); - - // set not collapsing - o->provide_collapsing = 0; - - // set provide - o->provide = best_provide; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } -} - -static void scope_ref_target_func_release (BRefTarget *ref_target) -{ - struct scope *o = UPPER_OBJECT(ref_target, struct scope, ref_target); - ASSERT(LinkedList1_IsEmpty(&o->provides_list)) - ASSERT(LinkedList1_IsEmpty(&o->depends_list)) - - BFree(o); -} - -static void scope_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct scope_instance *o = vo; - o->i = i; - - // pass scope instance pointer to methods not NCDModuleInst pointer - NCDModuleInst_Backend_PassMemToMethods(i); - - // read arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // allocate scope - o->scope = BAlloc(sizeof(*o->scope)); - if (!o->scope) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - goto fail0; - } - - // init reference target - BRefTarget_Init(&o->scope->ref_target, scope_ref_target_func_release); - - // init provide and depend lists - LinkedList1_Init(&o->scope->provides_list); - LinkedList1_Init(&o->scope->depends_list); - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void scope_func_die (void *vo) -{ - struct scope_instance *o = vo; - - // release scope reference - BRefTarget_Deref(&o->scope->ref_target); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct provide *o = vo; - o->i = i; - o->scope = ((struct scope_instance *)params->method_user)->scope; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // remember name - o->name = name_arg; - - // check for existing provide with this name - if (find_provide(o->scope, o->name)) { - ModuleLog(o->i, BLOG_ERROR, "a provide with this name already exists"); - goto fail0; - } - - // grab scope reference - if (!BRefTarget_Ref(&o->scope->ref_target)) { - ModuleLog(o->i, BLOG_ERROR, "BRefTarget_Ref failed"); - goto fail0; - } - - // insert to provides list - LinkedList1_Append(&o->scope->provides_list, &o->provides_list_node); - - // init depends list - LinkedList1_Init(&o->depends_list); - - // set not dying - o->dying = 0; - - // signal up. - // This comes above the loop which follows, so that effects on related depend statements are - // computed before this process advances, avoiding problems like failed variable resolutions. - NCDModuleInst_Backend_Up(o->i); - - // update depends - for (LinkedList1Node *ln = LinkedList1_GetFirst(&o->scope->depends_list); ln; ln = LinkedList1Node_Next(ln)) { - struct depend *depend = UPPER_OBJECT(ln, struct depend, depends_list_node); - depend_update(depend); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void provide_free (struct provide *o) -{ - ASSERT(LinkedList1_IsEmpty(&o->depends_list)) - - // remove from provides list - LinkedList1_Remove(&o->scope->provides_list, &o->provides_list_node); - - // release scope reference - BRefTarget_Deref(&o->scope->ref_target); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void provide_func_die (void *vo) -{ - struct provide *o = vo; - ASSERT(!o->dying) - - // if we have no depends, die immediately - if (LinkedList1_IsEmpty(&o->depends_list)) { - provide_free(o); - return; - } - - // set dying - o->dying = 1; - - // start collapsing our depends - for (LinkedList1Node *ln = LinkedList1_GetFirst(&o->depends_list); ln; ln = LinkedList1Node_Next(ln)) { - struct depend *depend = UPPER_OBJECT(ln, struct depend, provide_depends_list_node); - ASSERT(depend->provide == o) - - // update depend to make sure it is collapsing - depend_update(depend); - } -} - -static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct depend *o = vo; - o->i = i; - o->scope = ((struct scope_instance *)params->method_user)->scope; - - // read arguments - NCDValRef names_arg; - if (!NCDVal_ListRead(params->args, 1, &names_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(names_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // remember names - o->names = names_arg; - - // grab scope reference - if (!BRefTarget_Ref(&o->scope->ref_target)) { - ModuleLog(o->i, BLOG_ERROR, "BRefTarget_Ref failed"); - goto fail0; - } - - // insert to depends list - LinkedList1_Append(&o->scope->depends_list, &o->depends_list_node); - - // set no provide - o->provide = NULL; - - // update - depend_update(o); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void depend_func_die (void *vo) -{ - struct depend *o = vo; - - if (o->provide) { - // remove from provide's list - LinkedList1_Remove(&o->provide->depends_list, &o->provide_depends_list_node); - - // if provide is dying and is empty, let it die - if (o->provide->dying && LinkedList1_IsEmpty(&o->provide->depends_list)) { - provide_free(o->provide); - } - } - - // remove from depends list - LinkedList1_Remove(&o->scope->depends_list, &o->depends_list_node); - - // release scope reference - BRefTarget_Deref(&o->scope->ref_target); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void depend_func_clean (void *vo) -{ - struct depend *o = vo; - - if (!(o->provide && o->provide_collapsing)) { - return; - } - - // save provide - struct provide *provide = o->provide; - - // remove from provide's list - LinkedList1_Remove(&provide->depends_list, &o->provide_depends_list_node); - - // set no provide - o->provide = NULL; - - // update - depend_update(o); - - // if provide is dying and is empty, let it die. - // This comes after depend_update so that the side effects of the - // provide dying have priority over rebinding the depend. - if (provide->dying && LinkedList1_IsEmpty(&provide->depends_list)) { - provide_free(provide); - } -} - -static int depend_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct depend *o = vo; - - if (!o->provide) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(o->provide->i, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "depend_scope", - .func_new2 = scope_func_new, - .func_die = scope_func_die, - .alloc_size = sizeof(struct scope_instance) - }, { - .type = "depend_scope::provide", - .func_new2 = provide_func_new, - .func_die = provide_func_die, - .alloc_size = sizeof(struct provide) - }, { - .type = "depend_scope::depend", - .func_new2 = depend_func_new, - .func_die = depend_func_die, - .func_clean = depend_func_clean, - .func_getobj = depend_func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, - .alloc_size = sizeof(struct depend) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_depend_scope = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/dynamic_depend.c b/external/badvpn_dns/ncd/modules/dynamic_depend.c deleted file mode 100644 index 1fc747a..0000000 --- a/external/badvpn_dns/ncd/modules/dynamic_depend.c +++ /dev/null @@ -1,548 +0,0 @@ -/** - * @file dynamic_depend.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Dynamic dependencies module. - * - * Synopsis: dynamic_provide(string name, order_value) - * Synopsis: dynamic_depend(string name) - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/compare.h> -#include <misc/strdup.h> -#include <misc/balloc.h> -#include <structure/LinkedList0.h> -#include <structure/BAVL.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_dynamic_depend.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -struct provide; - -struct name_string { - char *data; - size_t len; -}; - -struct name { - struct global *g; - struct name_string name; - BAVLNode names_tree_node; - BAVL provides_tree; - LinkedList0 waiting_depends_list; - struct provide *cur_p; - LinkedList0 cur_bound_depends_list; - int cur_resetting; -}; - -struct provide { - NCDModuleInst *i; - struct name *n; - NCDValRef order_value; - BAVLNode provides_tree_node; - int dying; -}; - -struct depend { - NCDModuleInst *i; - struct name *n; - int is_bound; - LinkedList0Node depends_list_node; -}; - -struct global { - BAVL names_tree; -}; - -static void provide_free (struct provide *o); -static void depend_free (struct depend *o); - -static int name_string_comparator (void *user, void *vv1, void *vv2) -{ - struct name_string *v1 = vv1; - struct name_string *v2 = vv2; - - size_t min_len = (v1->len < v2->len ? v1->len : v2->len); - - int cmp = memcmp(v1->data, v2->data, min_len); - if (cmp) { - return B_COMPARE(cmp, 0); - } - - return B_COMPARE(v1->len, v2->len); -} - -static int val_comparator (void *user, NCDValRef *v1, NCDValRef *v2) -{ - return NCDVal_Compare(*v1, *v2); -} - -static struct name * find_name (struct global *g, const char *name, size_t name_len) -{ - struct name_string ns = {(char *)name, name_len}; - BAVLNode *tn = BAVL_LookupExact(&g->names_tree, &ns); - if (!tn) { - return NULL; - } - - struct name *n = UPPER_OBJECT(tn, struct name, names_tree_node); - ASSERT(n->name.len == name_len) - ASSERT(!memcmp(n->name.data, name, name_len)) - - return n; -} - -static struct name * name_init (NCDModuleInst *i, struct global *g, const char *name, size_t name_len) -{ - ASSERT(!find_name(g, name, name_len)) - - // allocate structure - struct name *o = malloc(sizeof(*o)); - if (!o) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set global state - o->g = g; - - // copy name - if (!(o->name.data = b_strdup_bin(name, name_len))) { - ModuleLog(i, BLOG_ERROR, "strdup failed"); - goto fail1; - } - o->name.len = name_len; - - // insert to names tree - ASSERT_EXECUTE(BAVL_Insert(&g->names_tree, &o->names_tree_node, NULL)) - - // init provides tree - BAVL_Init(&o->provides_tree, OFFSET_DIFF(struct provide, order_value, provides_tree_node), (BAVL_comparator)val_comparator, NULL); - - // init waiting depends list - LinkedList0_Init(&o->waiting_depends_list); - - // set no current provide - o->cur_p = NULL; - - return o; - -fail1: - free(o); -fail0: - return NULL; -} - -static void name_free (struct name *o) -{ - ASSERT(BAVL_IsEmpty(&o->provides_tree)) - ASSERT(LinkedList0_IsEmpty(&o->waiting_depends_list)) - ASSERT(!o->cur_p) - - // remove from names tree - BAVL_Remove(&o->g->names_tree, &o->names_tree_node); - - // free name - free(o->name.data); - - // free structure - free(o); -} - -static struct provide * name_get_first_provide (struct name *o) -{ - BAVLNode *tn = BAVL_GetFirst(&o->provides_tree); - if (!tn) { - return NULL; - } - - struct provide *p = UPPER_OBJECT(tn, struct provide, provides_tree_node); - ASSERT(p->n == o) - - return p; -} - -static void name_new_current (struct name *o) -{ - ASSERT(!o->cur_p) - ASSERT(!BAVL_IsEmpty(&o->provides_tree)) - - // set current provide - o->cur_p = name_get_first_provide(o); - - // init bound depends list - LinkedList0_Init(&o->cur_bound_depends_list); - - // set not resetting - o->cur_resetting = 0; - - // bind waiting depends - while (!LinkedList0_IsEmpty(&o->waiting_depends_list)) { - struct depend *d = UPPER_OBJECT(LinkedList0_GetFirst(&o->waiting_depends_list), struct depend, depends_list_node); - ASSERT(d->n == o) - ASSERT(!d->is_bound) - - // remove from waiting depends list - LinkedList0_Remove(&o->waiting_depends_list, &d->depends_list_node); - - // set bound - d->is_bound = 1; - - // add to bound depends list - LinkedList0_Prepend(&o->cur_bound_depends_list, &d->depends_list_node); - - // signal up - NCDModuleInst_Backend_Up(d->i); - } -} - -static void name_free_if_unused (struct name *o) -{ - if (BAVL_IsEmpty(&o->provides_tree) && LinkedList0_IsEmpty(&o->waiting_depends_list)) { - name_free(o); - } -} - -static void name_continue_resetting (struct name *o) -{ - ASSERT(o->cur_p) - ASSERT(o->cur_resetting) - - // still have bound depends? - if (!LinkedList0_IsEmpty(&o->cur_bound_depends_list)) { - return; - } - - struct provide *old_p = o->cur_p; - - // set no current provide - o->cur_p = NULL; - - // free old current provide if it's dying - if (old_p->dying) { - provide_free(old_p); - } - - if (!BAVL_IsEmpty(&o->provides_tree)) { - // get new current provide - name_new_current(o); - } else { - // free name if unused - name_free_if_unused(o); - } -} - -static void name_start_resetting (struct name *o) -{ - ASSERT(o->cur_p) - ASSERT(!o->cur_resetting) - - // set resetting - o->cur_resetting = 1; - - // signal bound depends down - for (LinkedList0Node *ln = LinkedList0_GetFirst(&o->cur_bound_depends_list); ln; ln = LinkedList0Node_Next(ln)) { - struct depend *d = UPPER_OBJECT(ln, struct depend, depends_list_node); - ASSERT(d->n == o) - ASSERT(d->is_bound) - NCDModuleInst_Backend_Down(d->i); - } - - // if there were no bound depends, continue right away - name_continue_resetting(o); -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - // allocate global state structure - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - // set group state pointer - group->group_state = g; - - // init names tree - BAVL_Init(&g->names_tree, OFFSET_DIFF(struct name, name, names_tree_node), name_string_comparator, NULL); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - ASSERT(BAVL_IsEmpty(&g->names_tree)) - - // free global state structure - BFree(g); -} - -static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct provide *o = vo; - o->i = i; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 2, &name_arg, &o->order_value)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - const char *name_str = NCDVal_StringData(name_arg); - size_t name_len = NCDVal_StringLength(name_arg); - - // find name, create new if needed - struct name *n = find_name(g, name_str, name_len); - if (!n && !(n = name_init(i, g, name_str, name_len))) { - goto fail0; - } - - // set name - o->n = n; - - // check for order value conflict - if (BAVL_LookupExact(&n->provides_tree, &o->order_value)) { - ModuleLog(i, BLOG_ERROR, "order value already exists"); - goto fail0; - } - - // add to name's provides tree - ASSERT_EXECUTE(BAVL_Insert(&n->provides_tree, &o->provides_tree_node, NULL)) - - // set not dying - o->dying = 0; - - // signal up - NCDModuleInst_Backend_Up(i); - - // should this be the current provide? - if (o == name_get_first_provide(n)) { - if (!n->cur_p) { - name_new_current(n); - } - else if (!n->cur_resetting) { - name_start_resetting(n); - } - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void provide_free (struct provide *o) -{ - struct name *n = o->n; - ASSERT(o->dying) - ASSERT(o != n->cur_p) - - // remove from name's provides tree - BAVL_Remove(&n->provides_tree, &o->provides_tree_node); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void provide_func_die (void *vo) -{ - struct provide *o = vo; - struct name *n = o->n; - ASSERT(!o->dying) - - // set dying - o->dying = 1; - - // if this is not the current provide, die right away - if (o != n->cur_p) { - // free provide - provide_free(o); - - // free name if unused - name_free_if_unused(n); - return; - } - - ASSERT(!n->cur_resetting) - - // start resetting - name_start_resetting(n); -} - -static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct depend *o = vo; - o->i = i; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - const char *name_str = NCDVal_StringData(name_arg); - size_t name_len = NCDVal_StringLength(name_arg); - - // find name, create new if needed - struct name *n = find_name(g, name_str, name_len); - if (!n && !(n = name_init(i, g, name_str, name_len))) { - goto fail0; - } - - // set name - o->n = n; - - if (n->cur_p && !n->cur_resetting) { - // set bound - o->is_bound = 1; - - // add to bound depends list - LinkedList0_Prepend(&n->cur_bound_depends_list, &o->depends_list_node); - - // signal up - NCDModuleInst_Backend_Up(i); - } else { - // set not bound - o->is_bound = 0; - - // add to waiting depends list - LinkedList0_Prepend(&n->waiting_depends_list, &o->depends_list_node); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void depend_func_die (void *vo) -{ - struct depend *o = vo; - struct name *n = o->n; - - if (o->is_bound) { - ASSERT(n->cur_p) - - // remove from bound depends list - LinkedList0_Remove(&n->cur_bound_depends_list, &o->depends_list_node); - - // continue resetting - if (n->cur_resetting) { - name_continue_resetting(n); - } - } else { - // remove from waiting depends list - LinkedList0_Remove(&n->waiting_depends_list, &o->depends_list_node); - - // free name if unused - name_free_if_unused(n); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void depend_func_clean (void *vo) -{ - struct depend *o = vo; - struct name *n = o->n; - ASSERT(!o->is_bound || n->cur_p) - - if (!(o->is_bound && n->cur_resetting)) { - return; - } - - // remove from bound depends list - LinkedList0_Remove(&n->cur_bound_depends_list, &o->depends_list_node); - - // set not bound - o->is_bound = 0; - - // add to waiting depends list - LinkedList0_Prepend(&n->waiting_depends_list, &o->depends_list_node); - - // continue resetting - name_continue_resetting(n); -} - -static int depend_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct depend *o = vo; - struct name *n = o->n; - ASSERT(!o->is_bound || n->cur_p) - - if (!o->is_bound) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(n->cur_p->i, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "dynamic_provide", - .func_new2 = provide_func_new, - .func_die = provide_func_die, - .alloc_size = sizeof(struct provide) - }, { - .type = "dynamic_depend", - .func_new2 = depend_func_new, - .func_die = depend_func_die, - .func_clean = depend_func_clean, - .func_getobj = depend_func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, - .alloc_size = sizeof(struct depend) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_dynamic_depend = { - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree, - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/event_template.c b/external/badvpn_dns/ncd/modules/event_template.c deleted file mode 100644 index 2fcab9e..0000000 --- a/external/badvpn_dns/ncd/modules/event_template.c +++ /dev/null @@ -1,184 +0,0 @@ -/** - * @file event_template.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> - -#include <ncd/modules/event_template.h> - -#define TemplateLog(o, ...) NCDModuleInst_Backend_Log((o)->i, (o)->blog_channel, __VA_ARGS__) - -static void enable_event (event_template *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->events_list)) - ASSERT(!o->enabled) - - // get event - struct event_template_event *e = UPPER_OBJECT(LinkedList1_GetFirst(&o->events_list), struct event_template_event, events_list_node); - - // remove from events list - LinkedList1_Remove(&o->events_list, &e->events_list_node); - - // grab enabled map - o->enabled_map = e->map; - - // append to free list - LinkedList1_Append(&o->free_list, &e->events_list_node); - - // set enabled - o->enabled = 1; - - // signal up - NCDModuleInst_Backend_Up(o->i); -} - -void event_template_new (event_template *o, NCDModuleInst *i, int blog_channel, int maxevents, void *user, - event_template_func_free func_free) -{ - ASSERT(maxevents > 0) - - // init arguments - o->i = i; - o->blog_channel = blog_channel; - o->user = user; - o->func_free = func_free; - - // allocate events array - if (!(o->events = BAllocArray(maxevents, sizeof(o->events[0])))) { - TemplateLog(o, BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - // init events lists - LinkedList1_Init(&o->events_list); - LinkedList1_Init(&o->free_list); - for (int i = 0; i < maxevents; i++) { - LinkedList1_Append(&o->free_list, &o->events[i].events_list_node); - } - - // set not enabled - o->enabled = 0; - - return; - -fail0: - o->func_free(o->user, 1); - return; -} - -void event_template_die (event_template *o) -{ - // free enabled map - if (o->enabled) { - BStringMap_Free(&o->enabled_map); - } - - // free event maps - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->events_list); - while (list_node) { - struct event_template_event *e = UPPER_OBJECT(list_node, struct event_template_event, events_list_node); - BStringMap_Free(&e->map); - list_node = LinkedList1Node_Next(list_node); - } - - // free events array - BFree(o->events); - - o->func_free(o->user, 0); - return; -} - -int event_template_getvar (event_template *o, const char *name, NCDValMem *mem, NCDValRef *out) -{ - ASSERT(o->enabled) - ASSERT(name) - - const char *val = BStringMap_Get(&o->enabled_map, name); - if (!val) { - return 0; - } - - *out = NCDVal_NewString(mem, val); - return 1; -} - -void event_template_queue (event_template *o, BStringMap map, int *out_was_empty) -{ - ASSERT(!LinkedList1_IsEmpty(&o->free_list)) - - // get event - struct event_template_event *e = UPPER_OBJECT(LinkedList1_GetFirst(&o->free_list), struct event_template_event, events_list_node); - - // remove from free list - LinkedList1_Remove(&o->free_list, &e->events_list_node); - - // set map - e->map = map; - - // insert to events list - LinkedList1_Append(&o->events_list, &e->events_list_node); - - // enable if not already - if (!o->enabled) { - enable_event(o); - *out_was_empty = 1; - } else { - *out_was_empty = 0; - } -} - -void event_template_dequeue (event_template *o, int *out_is_empty) -{ - ASSERT(o->enabled) - - // free enabled map - BStringMap_Free(&o->enabled_map); - - // set not enabled - o->enabled = 0; - - // signal down - NCDModuleInst_Backend_Down(o->i); - - // enable if there are more events - if (!LinkedList1_IsEmpty(&o->events_list)) { - enable_event(o); - *out_is_empty = 0; - } else { - *out_is_empty = 1; - } -} - -int event_template_is_enabled (event_template *o) -{ - return o->enabled; -} diff --git a/external/badvpn_dns/ncd/modules/event_template.h b/external/badvpn_dns/ncd/modules/event_template.h deleted file mode 100644 index a3a5ea8..0000000 --- a/external/badvpn_dns/ncd/modules/event_template.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file event_template.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_MODULES_EVENT_TEMPLATE_H -#define BADVPN_NCD_MODULES_EVENT_TEMPLATE_H - -#include <structure/LinkedList1.h> -#include <stringmap/BStringMap.h> -#include <ncd/NCDModule.h> - -typedef void (*event_template_func_free) (void *user, int is_error); - -typedef struct { - NCDModuleInst *i; - int blog_channel; - void *user; - event_template_func_free func_free; - struct event_template_event *events; - LinkedList1 events_list; - LinkedList1 free_list; - int enabled; - BStringMap enabled_map; -} event_template; - -struct event_template_event { - BStringMap map; - LinkedList1Node events_list_node; -}; - -void event_template_new (event_template *o, NCDModuleInst *i, int blog_channel, int maxevents, void *user, - event_template_func_free func_free); -void event_template_die (event_template *o); -int event_template_getvar (event_template *o, const char *name, NCDValMem *mem, NCDValRef *out); -void event_template_queue (event_template *o, BStringMap map, int *out_was_empty); -void event_template_dequeue (event_template *o, int *out_is_empty); -int event_template_is_enabled (event_template *o); - -#endif diff --git a/external/badvpn_dns/ncd/modules/exit.c b/external/badvpn_dns/ncd/modules/exit.c deleted file mode 100644 index d611e2e..0000000 --- a/external/badvpn_dns/ncd/modules/exit.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file exit.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * exit(string exit_code) - * - * Description: - * Initiates termination of the interpreter. Calling exit() multiple times will override - * the previously set exit code. When the interpreter receives a signal, it reacts - * equivalently to calling exit(1) (possibly overriding your error code). - */ - -#include <limits.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_exit.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef exit_code_arg; - if (!NCDVal_ListRead(params->args, 1, &exit_code_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(exit_code_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse exit code - uintmax_t exit_code; - if (!ncd_read_uintmax(exit_code_arg, &exit_code) || exit_code >= INT_MAX) { - ModuleLog(i, BLOG_ERROR, "wrong exit code value"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - - // initiate exit (before up!) - NCDModuleInst_Backend_InterpExit(i, exit_code); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "exit", - .func_new2 = func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_exit = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/explode.c b/external/badvpn_dns/ncd/modules/explode.c deleted file mode 100644 index 08425d5..0000000 --- a/external/badvpn_dns/ncd/modules/explode.c +++ /dev/null @@ -1,232 +0,0 @@ -/** - * @file explode.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * explode(string delimiter, string input [, string limit]) - * - * Description: - * Splits the string 'input' into a list of components. The first component - * is the part of 'input' until the first occurence of 'delimiter', if any. - * If 'delimiter' was found, the remaining components are defined recursively - * via the same procedure, starting with the part of 'input' after the first - * substring. - * 'delimiter' must be nonempty. - * - * Variables: - * list (empty) - the components of 'input', determined based on 'delimiter' - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <misc/exparray.h> -#include <misc/string_begins_with.h> -#include <misc/substring.h> -#include <misc/balloc.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_explode.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - struct ExpArray arr; - size_t num; -}; - -struct substring { - char *data; - size_t len; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef delimiter_arg; - NCDValRef input_arg; - NCDValRef limit_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &delimiter_arg, &input_arg) && !NCDVal_ListRead(params->args, 3, &delimiter_arg, &input_arg, &limit_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(delimiter_arg) || !NCDVal_IsString(input_arg) || (!NCDVal_IsInvalid(limit_arg) && !NCDVal_IsString(limit_arg))) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - size_t limit = SIZE_MAX; - if (!NCDVal_IsInvalid(limit_arg)) { - uintmax_t n; - if (!ncd_read_uintmax(limit_arg, &n) || n == 0) { - ModuleLog(i, BLOG_ERROR, "bad limit argument"); - goto fail0; - } - n--; - limit = (n <= SIZE_MAX ? n : SIZE_MAX); - } - - const char *del_data = NCDVal_StringData(delimiter_arg); - size_t del_len = NCDVal_StringLength(delimiter_arg); - - if (del_len == 0) { - ModuleLog(i, BLOG_ERROR, "delimiter must be nonempty"); - goto fail0; - } - - size_t *table = BAllocArray(del_len, sizeof(table[0])); - if (!table) { - ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); - goto fail0; - } - - build_substring_backtrack_table(del_data, del_len, table); - - if (!ExpArray_init(&o->arr, sizeof(struct substring), 8)) { - ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); - goto fail1; - } - o->num = 0; - - const char *data = NCDVal_StringData(input_arg); - size_t len = NCDVal_StringLength(input_arg); - - while (1) { - size_t start; - int is_end = 0; - if (limit == 0 || !find_substring(data, len, del_data, del_len, table, &start)) { - start = len; - is_end = 1; - } - - if (!ExpArray_resize(&o->arr, o->num + 1)) { - ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); - goto fail2; - } - - struct substring *elem = &((struct substring *)o->arr.v)[o->num]; - - if (!(elem->data = BAlloc(start))) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - goto fail2; - } - - memcpy(elem->data, data, start); - elem->len = start; - o->num++; - - if (is_end) { - break; - } - - data += start + del_len; - len -= start + del_len; - limit--; - } - - BFree(table); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail2: - while (o->num-- > 0) { - BFree(((struct substring *)o->arr.v)[o->num].data); - } - free(o->arr.v); -fail1: - BFree(table); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - while (o->num-- > 0) { - BFree(((struct substring *)o->arr.v)[o->num].data); - } - free(o->arr.v); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewList(mem, o->num); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - for (size_t j = 0; j < o->num; j++) { - struct substring *elem = &((struct substring *)o->arr.v)[j]; - NCDValRef str = NCDVal_NewStringBin(mem, (uint8_t *)elem->data, elem->len); - if (NCDVal_IsInvalid(str)) { - goto fail; - } - if (!NCDVal_ListAppend(*out, str)) { - goto fail; - } - } - return 1; - } - - return 0; - -fail: - *out = NCDVal_NewInvalid(); - return 1; -} - -static struct NCDModule modules[] = { - { - .type = "explode", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_explode = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/file.c b/external/badvpn_dns/ncd/modules/file.c deleted file mode 100644 index bda93ea..0000000 --- a/external/badvpn_dns/ncd/modules/file.c +++ /dev/null @@ -1,350 +0,0 @@ -/** - * @file file.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * File I/O module. - * - * Synopsis: - * file_read(string filename) - * - * Variables: - * string (empty) - file contents - * - * Description: - * Reads the contents of a file. Reports an error if something goes wrong. - * WARNING: this uses fopen/fread/fclose, blocking the entire interpreter while - * the file is being read. For this reason, you should only use this - * to read small local files which will be read quickly, and especially - * not files on network mounts. - * - * Synopsis: - * file_write(string filename, string contents) - * - * Description: - * Writes a file, possibly overwriting an existing one. Reports an error if something - * goes wrong. - * WARNING: this is not an atomic operation; other programs may see the file in an - * inconsistent state while it is being written. Similarly, if writing - * fails, the file may remain in an inconsistent state indefinitely. - * If this is a problem, you should write the new contents to a temporary - * file and rename this temporary file to the live file. - * WARNING: this uses fopen/fwrite/fclose, blocking the entire interpreter while - * the file is being written. For this reason, you should only use this - * to write small local files which will be written quickly, and especially - * not files on network mounts. - * - * Synopsis: - * file_stat(string filename) - * file_lstat(string filename) - * - * Description: - * Retrieves information about a file. - * file_stat() follows symlinks; file_lstat() does not and allows retrieving information - * about a symlink. - * WARNING: this blocks the interpreter - * - * Variables: - * succeeded - whether the stat operation succeeded (true/false). If false, all other - * variables obtain the value "failed". - * type - file, dir, chr, blk, fifo, link, socket, other, failed - * size - size of the file, or failed - */ - -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <misc/read_file.h> -#include <misc/write_file.h> -#include <misc/parse_number.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_file.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct read_instance { - NCDModuleInst *i; - uint8_t *file_data; - size_t file_len; -}; - -struct stat_instance { - NCDModuleInst *i; - int succeeded; - struct stat result; -}; - -static void read_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct read_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef filename_arg; - if (!NCDVal_ListRead(params->args, 1, &filename_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(filename_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get null terminated name - NCDValNullTermString filename_nts; - if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // read file - int res = read_file(filename_nts.data, &o->file_data, &o->file_len); - NCDValNullTermString_Free(&filename_nts); - if (!res) { - ModuleLog(i, BLOG_ERROR, "failed to read file"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void read_func_die (void *vo) -{ - struct read_instance *o = vo; - - // free data - free(o->file_data); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int read_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct read_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewStringBin(mem, o->file_data, o->file_len); - return 1; - } - - return 0; -} - -static void write_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef filename_arg; - NCDValRef contents_arg; - if (!NCDVal_ListRead(params->args, 2, &filename_arg, &contents_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(filename_arg) || !NCDVal_IsString(contents_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get null terminated name - NCDValNullTermString filename_nts; - if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // write file - b_cstring contents_cstr = NCDVal_StringCstring(contents_arg); - int res = write_file_cstring(filename_nts.data, contents_cstr, 0, contents_cstr.length); - NCDValNullTermString_Free(&filename_nts); - if (!res) { - ModuleLog(i, BLOG_ERROR, "failed to write file"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void stat_func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_lstat) -{ - struct stat_instance *o = vo; - o->i = i; - - NCDValRef filename_arg; - if (!NCDVal_ListRead(params->args, 1, &filename_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(filename_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->succeeded = 0; - - if (!NCDVal_IsStringNoNulls(filename_arg)) { - goto out; - } - - // null terminate filename - NCDValNullTermString filename_nts; - if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - int res; - if (is_lstat) { - res = lstat(filename_nts.data, &o->result); - } else { - res = stat(filename_nts.data, &o->result); - } - NCDValNullTermString_Free(&filename_nts); - - if (res < 0) { - goto out; - } - - o->succeeded = 1; - -out: - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void stat_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - stat_func_new_common(vo, i, params, 0); -} - -static void lstat_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - stat_func_new_common(vo, i, params, 1); -} - -static int stat_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct stat_instance *o = vo; - - if (name == NCD_STRING_SUCCEEDED) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - if (name == NCD_STRING_TYPE) { - const char *str; - - if (!o->succeeded) { - str = "failed"; - } else if (S_ISREG(o->result.st_mode)) { - str = "file"; - } else if (S_ISDIR(o->result.st_mode)) { - str = "dir"; - } else if (S_ISCHR(o->result.st_mode)) { - str = "chr"; - } else if (S_ISBLK(o->result.st_mode)) { - str = "blk"; - } else if (S_ISFIFO(o->result.st_mode)) { - str = "fifo"; - } else if (S_ISLNK(o->result.st_mode)) { - str = "link"; - } else if (S_ISSOCK(o->result.st_mode)) { - str = "socket"; - } else { - str = "other"; - } - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (name == NCD_STRING_SIZE) { - char str[50]; - if (!o->succeeded) { - strcpy(str, "failed"); - } else { - generate_decimal_repr_string((uintmax_t)o->result.st_size, str); - } - - *out = NCDVal_NewString(mem, str); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "file_read", - .func_new2 = read_func_new, - .func_die = read_func_die, - .func_getvar2 = read_func_getvar2, - .alloc_size = sizeof(struct read_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_write", - .func_new2 = write_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_stat", - .func_new2 = stat_func_new, - .func_getvar2 = stat_func_getvar2, - .alloc_size = sizeof(struct stat_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_lstat", - .func_new2 = lstat_func_new, - .func_getvar2 = stat_func_getvar2, - .alloc_size = sizeof(struct stat_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_file = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/file_open.c b/external/badvpn_dns/ncd/modules/file_open.c deleted file mode 100644 index d0a14c3..0000000 --- a/external/badvpn_dns/ncd/modules/file_open.c +++ /dev/null @@ -1,585 +0,0 @@ -/** - * @file file_open.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * file_open(string filename, string mode [, map options]) - * - * Variables: - * string is_error - "true" if the file_open object is in error state, "false" - * otherwise - * - * Options: - * "read_size" - the maximum number of bytes that can be read by a single - * read() call. Must be greater than zero. Greater values may improve - * performance, but will increase memory usage. Default: 8192. - * - * Description: - * Opens a file for subsequent reading or writing. The 'mode' argument must - * be one of: "r", "w", "a", "r+", "w+", "a+"; it corresponds to the mode string - * that will be passed to the fopen() function. - * When the file_open() statement goes up, the error state is set depending on - * whether opening succeeded or failed. The 'is_error' variable should be used - * to check the error state. - * If an error occurs afterward within read(), write() or seek(), the error state - * is set, and the file_open() statement is toggled down and back up. This way, - * the same piece of user code can handle all file errors. - * - * Synopsis: - * file_open::read() - * - * Variables: - * string (empty) - the data which was read, or an empty string if EOF was reached - * string not_eof - "false" if EOF was reached, "true" if not - * - * Description: - * Reads data from an opened file. The file must not be in error state. - * If reading fails, this statement will never go up, the error state of the - * file_open() statement will be set, and the file_open() statement will trigger - * backtracking (go down and up). - * - * Synopsis: - * file_open::write(string data) - * - * Description: - * Writes data to an opened file. The file must not be in error state. - * If writing fails, this statement will never go up, the error state of the - * file_open() statement will be set, and the file_open() statement will trigger - * backtracking (go down and up). - * - * Synopsis: - * file_open::seek(string position, string whence) - * - * Description: - * Sets the file position indicator. The 'position' argument must be a possibly - * negative decimal number, and is interpreted relative to 'whence'. Here, 'whence' - * may be one of: - * - "set", meaning beginning of file, - * - "cur", meaning the current position, and - * - "end", meaning the end of file. - * Errors are handled as in read() and write(). Note that if the position argument - * is too small or too large to convert to off_t, this is not a seek error, and only - * the seek command will fail. - * - * Synopsis: - * file_open::close() - * - * Description: - * Closes the file. The file must not be in error state. - * Errors are handled as handled as in read() and write(), i.e. the process is - * backtracked to file_open() with the error state set. - * On success, the error state of the file is set (but without backtracking), and - * the close() statement goes up . - */ - -#include <stddef.h> -#include <stdio.h> -#include <stdint.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balloc.h> -#include <misc/parse_number.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/NCDBuf.h> - -#include <generated/blog_channel_ncd_file_open.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define READ_BUF_SIZE 8192 - -struct open_instance { - NCDModuleInst *i; - FILE *fh; - NCDBufStore store; -}; - -struct read_instance { - NCDModuleInst *i; - NCDBuf *buf; - size_t length; -}; - -static int parse_mode (b_cstring cstr, char *out) -{ - size_t pos = 0; - size_t left = cstr.length; - - if (left == 0) { - return 0; - } - switch (b_cstring_at(cstr, pos)) { - case 'r': - case 'w': - case 'a': - *out++ = b_cstring_at(cstr, pos); - pos++; - left--; - break; - default: - return 0; - } - - if (left == 0) { - goto finish; - } - switch (b_cstring_at(cstr, pos)) { - case '+': - *out++ = b_cstring_at(cstr, pos); - pos++; - left--; - break; - default: - return 0; - } - - if (left == 0) { - goto finish; - } - - return 0; - -finish: - *out = '\0'; - return 1; -} - -static void trigger_error (struct open_instance *o) -{ - if (o->fh) { - // close file - if (fclose(o->fh) != 0) { - ModuleLog(o->i, BLOG_ERROR, "fclose failed"); - } - - // set no file, indicating error - o->fh = NULL; - } - - // go down and up - NCDModuleInst_Backend_Down(o->i); - NCDModuleInst_Backend_Up(o->i); -} - -static void open_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct open_instance *o = vo; - o->i = i; - - // check arguments - NCDValRef filename_arg; - NCDValRef mode_arg; - NCDValRef options_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &filename_arg, &mode_arg) && - !NCDVal_ListRead(params->args, 3, &filename_arg, &mode_arg, &options_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(filename_arg) || !NCDVal_IsString(mode_arg) || - (!NCDVal_IsInvalid(options_arg) && !NCDVal_IsMap(options_arg)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // check mode - char mode[5]; - if (!parse_mode(NCDVal_StringCstring(mode_arg), mode)) { - ModuleLog(o->i, BLOG_ERROR, "wrong mode"); - goto fail0; - } - - size_t read_size_opt = READ_BUF_SIZE; - - // parse options - if (!NCDVal_IsInvalid(options_arg)) { - int num_recognized = 0; - NCDValRef value; - - if (!NCDVal_IsInvalid(value = NCDVal_MapGetValue(options_arg, "read_size"))) { - uintmax_t read_size; - if (!NCDVal_IsString(value) || !ncd_read_uintmax(value, &read_size) || read_size > SIZE_MAX || read_size == 0) { - ModuleLog(o->i, BLOG_ERROR, "wrong read_size"); - goto fail0; - } - num_recognized++; - read_size_opt = read_size; - } - - if (NCDVal_MapCount(options_arg) > num_recognized) { - ModuleLog(o->i, BLOG_ERROR, "unrecognized options present"); - goto fail0; - } - } - - // init store - NCDBufStore_Init(&o->store, read_size_opt); - - // null terminate filename - NCDValNullTermString filename_nts; - if (!NCDVal_StringNullTerminate(filename_arg, &filename_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail1; - } - - // open file - o->fh = fopen(filename_nts.data, mode); - NCDValNullTermString_Free(&filename_nts); - if (!o->fh) { - ModuleLog(o->i, BLOG_ERROR, "fopen failed"); - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - NCDBufStore_Free(&o->store); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void open_func_die (void *vo) -{ - struct open_instance *o = vo; - - // close file - if (o->fh) { - if (fclose(o->fh) != 0) { - ModuleLog(o->i, BLOG_ERROR, "fclose failed"); - } - } - - // free store - NCDBufStore_Free(&o->store); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int open_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct open_instance *o = vo; - - if (name == NCD_STRING_IS_ERROR) { - *out = ncd_make_boolean(mem, !o->fh, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void read_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct read_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get open instance - struct open_instance *open_inst = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure it's not in error - if (!open_inst->fh) { - ModuleLog(o->i, BLOG_ERROR, "open instance is in error"); - goto fail0; - } - - // get buffer - o->buf = NCDBufStore_GetBuf(&open_inst->store); - if (!o->buf) { - ModuleLog(o->i, BLOG_ERROR, "NCDBufStore_GetBuf failed"); - goto fail0; - } - - // starting with empty buffer - char *data = NCDBuf_Data(o->buf); - size_t buf_size = NCDBufStore_BufSize(&open_inst->store); - o->length = 0; - - while (o->length < buf_size) { - // read - size_t readed = fread(data + o->length, 1, buf_size - o->length, open_inst->fh); - if (readed == 0) { - break; - } - ASSERT(readed <= buf_size - o->length) - - // increment length - o->length += readed; - } - - // if we couldn't read anything due to an error, trigger - // error in the open instance, and don't go up - if (o->length == 0 && !feof(open_inst->fh)) { - ModuleLog(o->i, BLOG_ERROR, "fread failed"); - trigger_error(open_inst); - return; - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void read_func_die (void *vo) -{ - struct read_instance *o = vo; - - // release buffer - BRefTarget_Deref(NCDBuf_RefTarget(o->buf)); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int read_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct read_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewExternalString(mem, NCDBuf_Data(o->buf), o->length, NCDBuf_RefTarget(o->buf)); - return 1; - } - - if (name == NCD_STRING_NOT_EOF) { - *out = ncd_make_boolean(mem, (o->length != 0), o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void write_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef data_arg; - if (!NCDVal_ListRead(params->args, 1, &data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get open instance - struct open_instance *open_inst = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure it's not in error - if (!open_inst->fh) { - ModuleLog(i, BLOG_ERROR, "open instance is in error"); - goto fail0; - } - - // write all the data - b_cstring data_cstr = NCDVal_StringCstring(data_arg); - B_CSTRING_LOOP(data_cstr, pos, chunk_data, chunk_length, { - size_t chunk_pos = 0; - while (chunk_pos < chunk_length) { - size_t written = fwrite(chunk_data + chunk_pos, 1, chunk_length - chunk_pos, open_inst->fh); - if (written == 0) { - ModuleLog(i, BLOG_ERROR, "fwrite failed"); - trigger_error(open_inst); - return; - } - ASSERT(written <= chunk_length - chunk_pos) - chunk_pos += written; - } - }) - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void seek_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef position_arg; - NCDValRef whence_arg; - if (!NCDVal_ListRead(params->args, 2, &position_arg, &whence_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(position_arg) || !NCDVal_IsString(whence_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse position - int position_sign; - uintmax_t position_mag; - b_cstring position_cstr = NCDVal_StringCstring(position_arg); - if (!parse_signmag_integer_cstr(position_cstr, 0, position_cstr.length, &position_sign, &position_mag)) { - ModuleLog(i, BLOG_ERROR, "wrong position"); - goto fail0; - } - - // parse whence - int whence; - if (NCDVal_StringEquals(whence_arg, "set")) { - whence = SEEK_SET; - } - else if (NCDVal_StringEquals(whence_arg, "cur")) { - whence = SEEK_CUR; - } - else if (NCDVal_StringEquals(whence_arg, "end")) { - whence = SEEK_END; - } - else { - ModuleLog(i, BLOG_ERROR, "wrong whence"); - goto fail0; - } - - // determine min/max values of off_t (non-portable hack) - off_t off_t_min = (sizeof(off_t) == 8 ? INT64_MIN : INT32_MIN); - off_t off_t_max = (sizeof(off_t) == 8 ? INT64_MAX : INT32_MAX); - - // compute position as off_t - off_t position; - if (position_sign < 0 && position_mag > 0) { - if (position_mag - 1 > -(off_t_min + 1)) { - ModuleLog(i, BLOG_ERROR, "position underflow"); - goto fail0; - } - position = -(off_t)(position_mag - 1) - 1; - } else { - if (position_mag > off_t_max) { - ModuleLog(i, BLOG_ERROR, "position overflow"); - goto fail0; - } - position = position_mag; - } - - // get open instance - struct open_instance *open_inst = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure it's not in error - if (!open_inst->fh) { - ModuleLog(i, BLOG_ERROR, "open instance is in error"); - goto fail0; - } - - // seek - if (fseeko(open_inst->fh, position, whence) < 0) { - ModuleLog(i, BLOG_ERROR, "fseeko failed"); - trigger_error(open_inst); - return; - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void close_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get open instance - struct open_instance *open_inst = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure it's not in error - if (!open_inst->fh) { - ModuleLog(i, BLOG_ERROR, "open instance is in error"); - goto fail0; - } - - // close - int res = fclose(open_inst->fh); - open_inst->fh = NULL; - if (res != 0) { - ModuleLog(i, BLOG_ERROR, "fclose failed"); - trigger_error(open_inst); - return; - } - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "file_open", - .func_new2 = open_func_new, - .func_die = open_func_die, - .func_getvar2 = open_func_getvar, - .alloc_size = sizeof(struct open_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_open::read", - .func_new2 = read_func_new, - .func_die = read_func_die, - .func_getvar2 = read_func_getvar, - .alloc_size = sizeof(struct read_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_open::write", - .func_new2 = write_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_open::seek", - .func_new2 = seek_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "file_open::close", - .func_new2 = close_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_file_open = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/foreach.c b/external/badvpn_dns/ncd/modules/foreach.c deleted file mode 100644 index f0b3eff..0000000 --- a/external/badvpn_dns/ncd/modules/foreach.c +++ /dev/null @@ -1,715 +0,0 @@ -/** - * @file foreach.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * foreach(list/map collection, string template, list args) - * - * Description: - * Initializes a template process for each element of list, sequentially, - * obeying to the usual execution model of NCD. - * It's equivalent to (except for special variables): - * - * call(template, args); - * ... - * call(template, args); # one call() for every element of list - * - * Template process specials: - * - * _index - (lists only) index of the list element corresponding to the template, - * process, as a decimal string, starting from zero - * _elem - (lists only) element of list corresponding to the template process - * _key - (maps only) key of the current map entry - * _val - (maps only) value of the current map entry - * _caller.X - X as seen from the foreach() statement - * - * Synopsis: - * foreach_emb(list/map collection, string template, string name1 [, string name2]) - * - * Description: - * Foreach for embedded templates; the desugaring process converts Foreach - * clauses into this statement. The called templates have direct access to - * objects as seen from this statement, and also some kind of access to the - * current element of the iteration, depending on the type of collection - * being iterated, and whether 'name2' is provided: - * List and one name: current element is named 'name1'. - * List and both names: current index is named 'name1', current element 'name2'. - * Map and one name: current key is named 'name1'. - * Map and both names: current key is named 'name1', current value 'name2'. - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <misc/balloc.h> -#include <misc/string_begins_with.h> -#include <misc/debug.h> -#include <misc/offset.h> -#include <system/BReactor.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_foreach.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -#define ISTATE_WORKING 1 -#define ISTATE_UP 2 -#define ISTATE_WAITING 3 -#define ISTATE_TERMINATING 4 - -#define ESTATE_FORGOTTEN 1 -#define ESTATE_DOWN 2 -#define ESTATE_UP 3 -#define ESTATE_WAITING 4 -#define ESTATE_TERMINATING 5 - -struct element; - -struct instance { - NCDModuleInst *i; - NCDValRef template_name; - NCDValRef args; - NCD_string_id_t name1; - NCD_string_id_t name2; - BTimer timer; - struct element *elems; - int type; - int num_elems; - int gp; // good pointer - int ip; // initialized pointer - int state; -}; - -struct element { - struct instance *inst; - union { - struct { - NCDValRef list_elem; - }; - struct { - NCDValRef map_key; - NCDValRef map_val; - }; - }; - NCDModuleProcess process; - int i; - int state; -}; - -static void assert_state (struct instance *o); -static void work (struct instance *o); -static void advance (struct instance *o); -static void timer_handler (struct instance *o); -static void element_process_handler_event (NCDModuleProcess *process, int event); -static int element_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int element_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static int element_list_index_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); -static int element_list_elem_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); -static int element_map_key_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); -static int element_map_val_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); -static void instance_free (struct instance *o); - -enum {STRING_INDEX, STRING_ELEM, STRING_KEY, STRING_VAL}; - -static const char *strings[] = { - "_index", "_elem", "_key", "_val", NULL -}; - -static void assert_state (struct instance *o) -{ - ASSERT(o->num_elems >= 0) - ASSERT(o->gp >= 0) - ASSERT(o->ip >= 0) - ASSERT(o->gp <= o->num_elems) - ASSERT(o->ip <= o->num_elems) - ASSERT(o->gp <= o->ip) - -#ifndef NDEBUG - // check GP - for (int i = 0; i < o->gp; i++) { - if (i == o->gp - 1) { - ASSERT(o->elems[i].state == ESTATE_UP || o->elems[i].state == ESTATE_DOWN || - o->elems[i].state == ESTATE_WAITING) - } else { - ASSERT(o->elems[i].state == ESTATE_UP) - } - } - - // check IP - int ip = o->num_elems; - while (ip > 0 && o->elems[ip - 1].state == ESTATE_FORGOTTEN) { - ip--; - } - ASSERT(o->ip == ip) - - // check gap - for (int i = o->gp; i < o->ip; i++) { - if (i == o->ip - 1) { - ASSERT(o->elems[i].state == ESTATE_UP || o->elems[i].state == ESTATE_DOWN || - o->elems[i].state == ESTATE_WAITING || o->elems[i].state == ESTATE_TERMINATING) - } else { - ASSERT(o->elems[i].state == ESTATE_UP || o->elems[i].state == ESTATE_DOWN || - o->elems[i].state == ESTATE_WAITING) - } - } -#endif -} - -static void work (struct instance *o) -{ - assert_state(o); - - // stop timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - if (o->state == ISTATE_WAITING) { - return; - } - - if (o->state == ISTATE_UP && !(o->gp == o->ip && o->gp == o->num_elems && (o->gp == 0 || o->elems[o->gp - 1].state == ESTATE_UP))) { - // signal down - NCDModuleInst_Backend_Down(o->i); - - // set state waiting - o->state = ISTATE_WAITING; - return; - } - - if (o->gp < o->ip) { - // get last element - struct element *le = &o->elems[o->ip - 1]; - ASSERT(le->state != ESTATE_FORGOTTEN) - - // start terminating if not already - if (le->state != ESTATE_TERMINATING) { - // request termination - NCDModuleProcess_Terminate(&le->process); - - // set element state terminating - le->state = ESTATE_TERMINATING; - } - - return; - } - - if (o->state == ISTATE_TERMINATING) { - // finally die - instance_free(o); - return; - } - - if (o->gp == o->num_elems && (o->gp == 0 || o->elems[o->gp - 1].state == ESTATE_UP)) { - if (o->state == ISTATE_WORKING) { - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state up - o->state = ISTATE_UP; - } - - return; - } - - if (o->gp > 0 && o->elems[o->gp - 1].state == ESTATE_WAITING) { - // get last element - struct element *le = &o->elems[o->gp - 1]; - - // continue process - NCDModuleProcess_Continue(&le->process); - - // set state down - le->state = ESTATE_DOWN; - return; - } - - if (o->gp > 0 && o->elems[o->gp - 1].state == ESTATE_DOWN) { - return; - } - - ASSERT(o->gp == 0 || o->elems[o->gp - 1].state == ESTATE_UP) - - advance(o); - return; -} - -static void advance (struct instance *o) -{ - assert_state(o); - ASSERT(o->gp == o->ip) - ASSERT(o->gp < o->num_elems) - ASSERT(o->gp == 0 || o->elems[o->gp - 1].state == ESTATE_UP) - ASSERT(o->elems[o->gp].state == ESTATE_FORGOTTEN) - - // get next element - struct element *e = &o->elems[o->gp]; - - // init process - if (!NCDModuleProcess_InitValue(&e->process, o->i, o->template_name, o->args, element_process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail; - } - - // set special functions - NCDModuleProcess_SetSpecialFuncs(&e->process, element_process_func_getspecialobj); - - // set element state down - e->state = ESTATE_DOWN; - - // increment GP and IP - o->gp++; - o->ip++; - return; - -fail: - // set timer - BReactor_SetTimer(o->i->params->iparams->reactor, &o->timer); -} - -static void timer_handler (struct instance *o) -{ - assert_state(o); - ASSERT(o->gp == o->ip) - ASSERT(o->gp < o->num_elems) - ASSERT(o->gp == 0 || o->elems[o->gp - 1].state == ESTATE_UP) - ASSERT(o->elems[o->gp].state == ESTATE_FORGOTTEN) - - advance(o); - return; -} - -static void element_process_handler_event (NCDModuleProcess *process, int event) -{ - struct element *e = UPPER_OBJECT(process, struct element, process); - struct instance *o = e->inst; - assert_state(o); - ASSERT(e->i < o->ip) - ASSERT(e->state != ESTATE_FORGOTTEN) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(e->state == ESTATE_DOWN) - ASSERT(o->gp == o->ip) - ASSERT(o->gp == e->i + 1) - - // set element state up - e->state = ESTATE_UP; - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(e->state == ESTATE_UP) - - // set element state waiting - e->state = ESTATE_WAITING; - - // bump down GP - if (o->gp > e->i + 1) { - o->gp = e->i + 1; - } - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(e->state == ESTATE_TERMINATING) - ASSERT(o->gp < o->ip) - ASSERT(o->ip == e->i + 1) - - // free process - NCDModuleProcess_Free(&e->process); - - // set element state forgotten - e->state = ESTATE_FORGOTTEN; - - // decrement IP - o->ip--; - } break; - - default: ASSERT(0); - } - - work(o); - return; -} - -static int element_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct element *e = UPPER_OBJECT(process, struct element, process); - struct instance *o = e->inst; - ASSERT(e->state != ESTATE_FORGOTTEN) - - switch (o->type) { - case NCDVAL_LIST: { - NCD_string_id_t index_name = (o->name2 >= 0 ? o->name1 : -1); - NCD_string_id_t elem_name = (o->name2 >= 0 ? o->name2 : o->name1); - - if (index_name >= 0 && name == index_name) { - *out_object = NCDObject_Build(-1, e, element_list_index_object_func_getvar, NCDObject_no_getobj); - return 1; - } - - if (name == elem_name) { - *out_object = NCDObject_Build(-1, e, element_list_elem_object_func_getvar, NCDObject_no_getobj); - return 1; - } - } break; - case NCDVAL_MAP: { - NCD_string_id_t key_name = o->name1; - NCD_string_id_t val_name = o->name2; - - if (name == key_name) { - *out_object = NCDObject_Build(-1, e, element_map_key_object_func_getvar, NCDObject_no_getobj); - return 1; - } - - if (val_name >= 0 && name == val_name) { - *out_object = NCDObject_Build(-1, e, element_map_val_object_func_getvar, NCDObject_no_getobj); - return 1; - } - } break; - } - - if (NCDVal_IsInvalid(o->args)) { - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); - } - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, e, NCDObject_no_getvar, element_caller_object_func_getobj); - return 1; - } - - return 0; -} - -static int element_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct element *e = NCDObject_DataPtr(obj); - struct instance *o = e->inst; - ASSERT(e->state != ESTATE_FORGOTTEN) - ASSERT(!NCDVal_IsInvalid(o->args)) - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static int element_list_index_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct element *e = NCDObject_DataPtr(obj); - struct instance *o = e->inst; - B_USE(o) - ASSERT(e->state != ESTATE_FORGOTTEN) - ASSERT(o->type == NCDVAL_LIST) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out = ncd_make_uintmax(mem, e->i); - return 1; -} - -static int element_list_elem_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct element *e = NCDObject_DataPtr(obj); - struct instance *o = e->inst; - B_USE(o) - ASSERT(e->state != ESTATE_FORGOTTEN) - ASSERT(o->type == NCDVAL_LIST) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out = NCDVal_NewCopy(mem, e->list_elem); - return 1; -} - -static int element_map_key_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct element *e = NCDObject_DataPtr(obj); - struct instance *o = e->inst; - B_USE(o) - ASSERT(e->state != ESTATE_FORGOTTEN) - ASSERT(o->type == NCDVAL_MAP) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out = NCDVal_NewCopy(mem, e->map_key); - return 1; -} - -static int element_map_val_object_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct element *e = NCDObject_DataPtr(obj); - struct instance *o = e->inst; - B_USE(o) - ASSERT(e->state != ESTATE_FORGOTTEN) - ASSERT(o->type == NCDVAL_MAP) - - if (name != NCD_STRING_EMPTY) { - return 0; - } - - *out = NCDVal_NewCopy(mem, e->map_val); - return 1; -} - -static void func_new_common (void *vo, NCDModuleInst *i, NCDValRef collection, NCDValRef template_name, NCDValRef args, NCD_string_id_t name1, NCD_string_id_t name2) -{ - ASSERT(!NCDVal_IsInvalid(collection)) - ASSERT(NCDVal_IsString(template_name)) - ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args)) - ASSERT(name1 >= 0) - - struct instance *o = vo; - o->i = i; - - o->type = NCDVal_Type(collection); - o->template_name = template_name; - o->args = args; - o->name1 = name1; - o->name2 = name2; - - // init timer - btime_t retry_time = NCDModuleInst_Backend_InterpGetRetryTime(i); - BTimer_Init(&o->timer, retry_time, (BTimer_handler)timer_handler, o); - - size_t num_elems; - NCDValMapElem cur_map_elem; - - switch (o->type) { - case NCDVAL_LIST: { - num_elems = NCDVal_ListCount(collection); - } break; - case NCDVAL_MAP: { - num_elems = NCDVal_MapCount(collection); - cur_map_elem = NCDVal_MapOrderedFirst(collection); - } break; - default: - ModuleLog(i, BLOG_ERROR, "invalid collection type"); - goto fail0; - } - - if (num_elems > INT_MAX) { - ModuleLog(i, BLOG_ERROR, "too many elements"); - goto fail0; - } - o->num_elems = num_elems; - - // allocate elements - if (!(o->elems = BAllocArray(o->num_elems, sizeof(o->elems[0])))) { - ModuleLog(i, BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - for (int j = 0; j < o->num_elems; j++) { - struct element *e = &o->elems[j]; - - // set instance - e->inst = o; - - // set index - e->i = j; - - // set state forgotten - e->state = ESTATE_FORGOTTEN; - - // set values - switch (o->type) { - case NCDVAL_LIST: { - e->list_elem = NCDVal_ListGet(collection, j); - } break; - case NCDVAL_MAP: { - e->map_key = NCDVal_MapElemKey(collection, cur_map_elem); - e->map_val = NCDVal_MapElemVal(collection, cur_map_elem); - cur_map_elem = NCDVal_MapOrderedNext(collection, cur_map_elem); - } break; - } - } - - // set GP and IP zero - o->gp = 0; - o->ip = 0; - - // set state working - o->state = ISTATE_WORKING; - - work(o); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_foreach (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef arg_collection; - NCDValRef arg_template; - NCDValRef arg_args; - if (!NCDVal_ListRead(params->args, 3, &arg_collection, &arg_template, &arg_args)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_template) || !NCDVal_IsList(arg_args)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - NCD_string_id_t name1; - NCD_string_id_t name2; - - switch (NCDVal_Type(arg_collection)) { - case NCDVAL_LIST: { - name1 = ModuleString(i, STRING_INDEX); - name2 = ModuleString(i, STRING_ELEM); - } break; - case NCDVAL_MAP: { - name1 = ModuleString(i, STRING_KEY); - name2 = ModuleString(i, STRING_VAL); - } break; - default: - ModuleLog(i, BLOG_ERROR, "invalid collection type"); - goto fail0; - } - - func_new_common(vo, i, arg_collection, arg_template, arg_args, name1, name2); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_foreach_emb (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef arg_collection; - NCDValRef arg_template; - NCDValRef arg_name1; - NCDValRef arg_name2 = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 3, &arg_collection, &arg_template, &arg_name1) && !NCDVal_ListRead(params->args, 4, &arg_collection, &arg_template, &arg_name1, &arg_name2)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_template) || !NCDVal_IsString(arg_name1) || (!NCDVal_IsInvalid(arg_name2) && !NCDVal_IsString(arg_name2))) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - NCD_string_id_t name1 = ncd_get_string_id(arg_name1, i->params->iparams->string_index); - if (name1 < 0) { - ModuleLog(i, BLOG_ERROR, "ncd_get_string_id failed"); - goto fail0; - } - - NCD_string_id_t name2 = -1; - if (!NCDVal_IsInvalid(arg_name2)) { - name2 = ncd_get_string_id(arg_name2, i->params->iparams->string_index); - if (name2 < 0) { - ModuleLog(i, BLOG_ERROR, "ncd_get_string_id failed"); - goto fail0; - } - } - - func_new_common(vo, i, arg_collection, arg_template, NCDVal_NewInvalid(), name1, name2); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - ASSERT(o->gp == 0) - ASSERT(o->ip == 0) - - // free elements - BFree(o->elems); - - // free timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - assert_state(o); - ASSERT(o->state != ISTATE_TERMINATING) - - // set GP zero - o->gp = 0; - - // set state terminating - o->state = ISTATE_TERMINATING; - - work(o); - return; -} - -static void func_clean (void *vo) -{ - struct instance *o = vo; - - if (o->state != ISTATE_WAITING) { - return; - } - - // set state working - o->state = ISTATE_WORKING; - - work(o); - return; -} - -static struct NCDModule modules[] = { - { - .type = "foreach", - .func_new2 = func_new_foreach, - .func_die = func_die, - .func_clean = func_clean, - .alloc_size = sizeof(struct instance) - }, { - .type = "foreach_emb", - .func_new2 = func_new_foreach_emb, - .func_die = func_die, - .func_clean = func_clean, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_foreach = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/from_string.c b/external/badvpn_dns/ncd/modules/from_string.c deleted file mode 100644 index 3bc446b..0000000 --- a/external/badvpn_dns/ncd/modules/from_string.c +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file from_string.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * from_string(string str) - * Variables: - * (empty) - str, parsed as a value - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/NCDValParser.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_from_string.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValMem mem; - NCDValRef val; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef str_arg; - if (!NCDVal_ListRead(params->args, 1, &str_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // init mem - NCDValMem_Init(&o->mem); - - // parse value string - if (!NCDValParser_Parse(NCDVal_StringData(str_arg), NCDVal_StringLength(str_arg), &o->mem, &o->val)) { - ModuleLog(i, BLOG_ERROR, "failed to parse"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - NCDValMem_Free(&o->mem); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free mem - NCDValMem_Free(&o->mem); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewCopy(mem, o->val); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "from_string", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_from_string = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/getargs.c b/external/badvpn_dns/ncd/modules/getargs.c deleted file mode 100644 index f620a65..0000000 --- a/external/badvpn_dns/ncd/modules/getargs.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file getargs.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * getargs() - * - * Variables: - * (empty) - list of extra command line arguments that were passed to the intrepreter - */ - -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_getargs.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - if (!NCDModuleInst_Backend_InterpGetArgs(o->i, mem, out)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleInst_Backend_InterpGetArgs failed"); - return 0; - } - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "getargs", - .func_new2 = func_new, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_getargs = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/getenv.c b/external/badvpn_dns/ncd/modules/getenv.c deleted file mode 100644 index 2cb3e91..0000000 --- a/external/badvpn_dns/ncd/modules/getenv.c +++ /dev/null @@ -1,153 +0,0 @@ -/** - * @file getenv.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * getenv(string name) - * - * Variables: - * string (empty) - if the environment value exists, its value - * string exists - "true" if the variable exists, "false" if not - */ - -#include <stdlib.h> - -#include <misc/strdup.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_getenv.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -struct instance { - NCDModuleInst *i; - char *value; -}; - -enum {STRING_EXISTS}; - -static const char *strings[] = {"exists", NULL}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->value = NULL; - - if (NCDVal_StringHasNulls(name_arg)) { - goto out; - } - - NCDValNullTermString nts; - if (!NCDVal_StringNullTerminate(name_arg, &nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - char *result = getenv(nts.data); - NCDValNullTermString_Free(&nts); - if (!result) { - goto out; - } - - o->value = b_strdup(result); - if (!o->value) { - ModuleLog(i, BLOG_ERROR, "b_strdup failed"); - goto fail0; - } - -out: - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free value - if (o->value) { - BFree(o->value); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY && o->value) { - *out = NCDVal_NewString(mem, o->value); - return 1; - } - - if (name == ModuleString(o->i, STRING_EXISTS)) { - *out = ncd_make_boolean(mem, !!o->value, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "getenv", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_getenv = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/if.c b/external/badvpn_dns/ncd/modules/if.c deleted file mode 100644 index 3bbd362..0000000 --- a/external/badvpn_dns/ncd/modules/if.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file if.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Conditional module. - * - * Synopsis: if(string cond) - * Description: on initialization, transitions to UP state if cond equals "true", else - * remains in the DOWN state indefinitely. - * - * Synopsis: ifnot(string cond) - * Description: on initialization, transitions to UP state if cond does not equal "true", else - * remains in the DOWN state indefinitely. - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_if.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void new_templ (NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_not) -{ - // check arguments - NCDValRef arg; - if (!NCDVal_ListRead(params->args, 1, &arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // compute logical value of argument - int c = ncd_read_boolean(arg); - - // signal up if needed - if ((is_not && !c) || (!is_not && c)) { - NCDModuleInst_Backend_Up(i); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(i, params, 0); -} - -static void func_new_not (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(i, params, 1); -} - -static struct NCDModule modules[] = { - { - .type = "if", - .func_new2 = func_new - }, { - .type = "ifnot", - .func_new2 = func_new_not - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_if = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/imperative.c b/external/badvpn_dns/ncd/modules/imperative.c deleted file mode 100644 index f964888..0000000 --- a/external/badvpn_dns/ncd/modules/imperative.c +++ /dev/null @@ -1,324 +0,0 @@ -/** - * @file imperative.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Imperative statement. - * - * Synopsis: - * imperative(string init_template, list init_args, string deinit_template, list deinit_args, string deinit_timeout) - * - * Description: - * Does the following, in order: - * 1. Starts a template process from (init_template, init_args) and waits for it to - * initialize completely. - * 2. Initiates termination of the process and wait for it to terminate. - * 3. Puts the statement UP, then waits for a statement termination request (which may - * already have been received). - * 4. Starts a template process from (deinit_template, deinit_args) and waits for it - * to initialize completely, or for the timeout to elapse. - * 5. Initiates termination of the process and wait for it to terminate. - * 6. Terminates the statement. - * - * If init_template="<none>", steps (1-2) are skipped. - * If deinit_template="<none>", steps (4-5) are skipped. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/string_begins_with.h> -#include <misc/offset.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_imperative.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_INIT_WORKING 1 -#define STATE_INIT_CLEANING 2 -#define STATE_UP 3 -#define STATE_DEINIT_WORKING 4 -#define STATE_DEINIT_CLEANING 5 - -struct instance { - NCDModuleInst *i; - NCDValRef deinit_template; - NCDValRef deinit_args; - BTimer deinit_timer; - NCDModuleProcess process; - int state; - int dying; -}; - -static int start_process (struct instance *o, NCDValRef template_name, NCDValRef args, NCDModuleProcess_handler_event handler); -static void go_deinit (struct instance *o); -static void init_process_handler_event (NCDModuleProcess *process, int event); -static void deinit_process_handler_event (NCDModuleProcess *process, int event); -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int process_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static void deinit_timer_handler (struct instance *o); -static void instance_free (struct instance *o); - -static int start_process (struct instance *o, NCDValRef template_name, NCDValRef args, NCDModuleProcess_handler_event handler) -{ - ASSERT(NCDVal_IsString(template_name)) - ASSERT(NCDVal_IsList(args)) - - // create process - if (!NCDModuleProcess_InitValue(&o->process, o->i, template_name, args, handler)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - return 0; - } - - // set special functions - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj); - return 1; -} - -static void go_deinit (struct instance *o) -{ - ASSERT(o->dying) - - // deinit is no-op? - if (ncd_is_none(o->deinit_template)) { - instance_free(o); - return; - } - - // start deinit process - if (!start_process(o, o->deinit_template, o->deinit_args, deinit_process_handler_event)) { - instance_free(o); - return; - } - - // start timer - BReactor_SetTimer(o->i->params->iparams->reactor, &o->deinit_timer); - - // set state deinit working - o->state = STATE_DEINIT_WORKING; -} - -static void init_process_handler_event (NCDModuleProcess *process, int event) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == STATE_INIT_WORKING) - - // start terminating - NCDModuleProcess_Terminate(&o->process); - - // set state init cleaning - o->state = STATE_INIT_CLEANING; - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == STATE_INIT_CLEANING) - - // free process - NCDModuleProcess_Free(&o->process); - - // were we requested to die aleady? - if (o->dying) { - go_deinit(o); - return; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state up - o->state = STATE_UP; - } break; - - default: ASSERT(0); - } -} - -static void deinit_process_handler_event (NCDModuleProcess *process, int event) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - ASSERT(o->dying) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == STATE_DEINIT_WORKING) - - // stop timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->deinit_timer); - - // start terminating - NCDModuleProcess_Terminate(&o->process); - - // set state deinit cleaning - o->state = STATE_DEINIT_CLEANING; - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == STATE_DEINIT_CLEANING) - - // free process - NCDModuleProcess_Free(&o->process); - - // die - instance_free(o); - return; - } break; - - default: ASSERT(0); - } -} - -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - ASSERT(o->state != STATE_UP) - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, process_caller_object_func_getobj); - return 1; - } - - return 0; -} - -static int process_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = NCDObject_DataPtr(obj); - ASSERT(o->state != STATE_UP) - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static void deinit_timer_handler (struct instance *o) -{ - ASSERT(o->state == STATE_DEINIT_WORKING) - - ModuleLog(o->i, BLOG_ERROR, "imperative deinit timeout elapsed"); - - // start terminating - NCDModuleProcess_Terminate(&o->process); - - // set state deinit cleaning - o->state = STATE_DEINIT_CLEANING; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef init_template_arg; - NCDValRef init_args; - NCDValRef deinit_template_arg; - NCDValRef deinit_timeout_arg; - if (!NCDVal_ListRead(params->args, 5, &init_template_arg, &init_args, &deinit_template_arg, &o->deinit_args, &deinit_timeout_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(init_template_arg) || !NCDVal_IsList(init_args) || - !NCDVal_IsString(deinit_template_arg) || !NCDVal_IsList(o->deinit_args) || - !NCDVal_IsString(deinit_timeout_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->deinit_template = deinit_template_arg; - - // read timeout - uintmax_t timeout; - if (!ncd_read_uintmax(deinit_timeout_arg, &timeout) || timeout > UINT64_MAX){ - ModuleLog(i, BLOG_ERROR, "wrong timeout"); - goto fail0; - } - - // init timer - BTimer_Init(&o->deinit_timer, timeout, (BTimer_handler)deinit_timer_handler, o); - - if (ncd_is_none(init_template_arg)) { - // signal up - NCDModuleInst_Backend_Up(i); - - // set state up - o->state = STATE_UP; - } else { - // start init process - if (!start_process(o, init_template_arg, init_args, init_process_handler_event)) { - goto fail0; - } - - // set state init working - o->state = STATE_INIT_WORKING; - } - - // set not dying - o->dying = 0; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // set dying - o->dying = 1; - - if (o->state == STATE_UP) { - go_deinit(o); - return; - } -} - -static struct NCDModule modules[] = { - { - .type = "imperative", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_imperative = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/implode.c b/external/badvpn_dns/ncd/modules/implode.c deleted file mode 100644 index 0520eca..0000000 --- a/external/badvpn_dns/ncd/modules/implode.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file implode.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * implode(string glue, list(string) pieces) - * - * Variables: - * string (empty) - concatenation of strings in 'pieces', with 'glue' in between - * every two elements. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/expstring.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_implode.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - char *result; - size_t result_len; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef glue_arg; - NCDValRef pieces_arg; - if (!NCDVal_ListRead(params->args, 2, &glue_arg, &pieces_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(glue_arg) || !NCDVal_IsList(pieces_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // init result string - ExpString str; - if (!ExpString_Init(&str)) { - ModuleLog(i, BLOG_ERROR, "ExpString_Init failed"); - goto fail0; - } - - size_t count = NCDVal_ListCount(pieces_arg); - for (size_t j = 0; j < count; j++) { - NCDValRef piece = NCDVal_ListGet(pieces_arg, j); - - // check piece type - if (!NCDVal_IsString(piece)) { - ModuleLog(i, BLOG_ERROR, "wrong piece type"); - goto fail1; - } - - // append glue - if (j > 0) { - if (!ExpString_AppendBinary(&str, (const uint8_t *)NCDVal_StringData(glue_arg), NCDVal_StringLength(glue_arg))) { - ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail1; - } - } - - // append piece - if (!ExpString_AppendBinary(&str, (const uint8_t *)NCDVal_StringData(piece), NCDVal_StringLength(piece))) { - ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail1; - } - } - - // store result - o->result = ExpString_Get(&str); - o->result_len = ExpString_Length(&str); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - ExpString_Free(&str); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free result - free(o->result); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewStringBin(mem, (uint8_t *)o->result, o->result_len); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "implode", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_implode = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/index.c b/external/badvpn_dns/ncd/modules/index.c deleted file mode 100644 index fe68bdd..0000000 --- a/external/badvpn_dns/ncd/modules/index.c +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file index.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * index index(string value) - * index index::next() - * - * Description: - * Non-negative integer with range of a size_t. - * The first form creates an index from the given decimal string. - * The second form cretes an index with value one more than an existing - * index. - * - * Variables: - * string (empty) - the index value. Note this may be different from - * than the value given to index() if it was not in normal form. - */ - -#include <stdlib.h> -#include <string.h> -#include <stddef.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_index.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - size_t value; -}; - -static void func_new_templ (void *vo, NCDModuleInst *i, size_t value) -{ - struct instance *o = vo; - o->i = i; - - // set value - o->value = value; - - // signal up - NCDModuleInst_Backend_Up(o->i); -} - -static void func_new_from_value (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef arg_value; - if (!NCDVal_ListRead(params->args, 1, &arg_value)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_value)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse value - uintmax_t value; - if (!ncd_read_uintmax(arg_value, &value)) { - ModuleLog(i, BLOG_ERROR, "wrong value"); - goto fail0; - } - - // check overflow - if (value > SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "value too large"); - goto fail0; - } - - func_new_templ(vo, i, value); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_from_index (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *index = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // check overflow - if (index->value == SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "overflow"); - goto fail0; - } - - func_new_templ(vo, i, index->value + 1); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (!strcmp(name, "")) { - *out = ncd_make_uintmax(mem, o->value); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "index", - .func_new2 = func_new_from_value, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "index::next", - .base_type = "index", - .func_new2 = func_new_from_index, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_index = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/list.c b/external/badvpn_dns/ncd/modules/list.c deleted file mode 100644 index e1df1f1..0000000 --- a/external/badvpn_dns/ncd/modules/list.c +++ /dev/null @@ -1,871 +0,0 @@ -/** - * @file list.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * List construction module. - * - * Synopsis: - * list(elem1, ..., elemN) - * list listfrom(list l1, ..., list lN) - * - * Description: - * The first form creates a list with the given elements. - * The second form creates a list by concatenating the given - * lists. - * - * Variables: - * (empty) - list containing elem1, ..., elemN - * length - number of elements in list - * - * Synopsis: list::append(arg) - * - * Synopsis: list::appendv(list arg) - * Description: Appends the elements of arg to the list. - * - * Synopsis: list::length() - * Variables: - * (empty) - number of elements in list at the time of initialization - * of this method - * - * Synopsis: list::get(string index) - * Variables: - * (empty) - element of list at position index (starting from zero) at the time of initialization - * - * Synopsis: list::shift() - * - * Synopsis: list::contains(value) - * Variables: - * (empty) - "true" if list contains value, "false" if not - * - * Synopsis: - * list::find(start_pos, value) - * Description: - * finds the first occurrence of 'value' in the list at position >='start_pos'. - * Variables: - * pos - position of element, or "none" if not found - * found - "true" if found, "false" if not - * - * Sysnopsis: - * list::remove_at(remove_pos) - * Description: - * Removes the element at position 'remove_pos', which must refer to an existing element. - * - * Synopsis: - * list::remove(value) - * Description: - * Removes the first occurrence of value in the list, which must be in the list. - * - * Synopsis: - * list::set(list l1, ..., list lN) - * Description: - * Replaces the list with the concatenation of given lists. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <inttypes.h> - -#include <misc/offset.h> -#include <misc/parse_number.h> -#include <structure/IndexedList.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_list.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct elem { - IndexedListNode il_node; - NCDValMem mem; - NCDValRef val; -}; - -struct instance { - NCDModuleInst *i; - IndexedList il; -}; - -struct length_instance { - NCDModuleInst *i; - uint64_t length; -}; - -struct get_instance { - NCDModuleInst *i; - NCDValMem mem; - NCDValRef val; -}; - -struct contains_instance { - NCDModuleInst *i; - int contains; -}; - -struct find_instance { - NCDModuleInst *i; - int is_found; - uint64_t found_pos; -}; - -static uint64_t list_count (struct instance *o) -{ - return IndexedList_Count(&o->il); -} - -static struct elem * insert_value (NCDModuleInst *i, struct instance *o, NCDValRef val, uint64_t idx) -{ - ASSERT(idx <= list_count(o)) - ASSERT(!NCDVal_IsInvalid(val)) - - struct elem *e = malloc(sizeof(*e)); - if (!e) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - NCDValMem_Init(&e->mem); - - e->val = NCDVal_NewCopy(&e->mem, val); - if (NCDVal_IsInvalid(e->val)) { - goto fail1; - } - - IndexedList_InsertAt(&o->il, &e->il_node, idx); - - return e; - -fail1: - NCDValMem_Free(&e->mem); - free(e); -fail0: - return NULL; -} - -static void remove_elem (struct instance *o, struct elem *e) -{ - IndexedList_Remove(&o->il, &e->il_node); - NCDValMem_Free(&e->mem); - free(e); -} - -static struct elem * get_elem_at (struct instance *o, uint64_t idx) -{ - ASSERT(idx < list_count(o)) - - IndexedListNode *iln = IndexedList_GetAt(&o->il, idx); - struct elem *e = UPPER_OBJECT(iln, struct elem, il_node); - - return e; -} - -static struct elem * get_first_elem (struct instance *o) -{ - ASSERT(list_count(o) > 0) - - IndexedListNode *iln = IndexedList_GetFirst(&o->il); - struct elem *e = UPPER_OBJECT(iln, struct elem, il_node); - - return e; -} - -static struct elem * get_last_elem (struct instance *o) -{ - ASSERT(list_count(o) > 0) - - IndexedListNode *iln = IndexedList_GetLast(&o->il); - struct elem *e = UPPER_OBJECT(iln, struct elem, il_node); - - return e; -} - -static void cut_list_front (struct instance *o, uint64_t count) -{ - while (list_count(o) > count) { - remove_elem(o, get_first_elem(o)); - } -} - -static void cut_list_back (struct instance *o, uint64_t count) -{ - while (list_count(o) > count) { - remove_elem(o, get_last_elem(o)); - } -} - -static int append_list_contents (NCDModuleInst *i, struct instance *o, NCDValRef args) -{ - ASSERT(NCDVal_IsList(args)) - - uint64_t orig_count = list_count(o); - - size_t append_count = NCDVal_ListCount(args); - - for (size_t j = 0; j < append_count; j++) { - NCDValRef elem = NCDVal_ListGet(args, j); - if (!insert_value(i, o, elem, list_count(o))) { - goto fail; - } - } - - return 1; - -fail: - cut_list_back(o, orig_count); - return 0; -} - -static int append_list_contents_contents (NCDModuleInst *i, struct instance *o, NCDValRef args) -{ - ASSERT(NCDVal_IsList(args)) - - uint64_t orig_count = list_count(o); - - size_t append_count = NCDVal_ListCount(args); - - for (size_t j = 0; j < append_count; j++) { - NCDValRef elem = NCDVal_ListGet(args, j); - - if (!NCDVal_IsList(elem)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail; - } - - if (!append_list_contents(i, o, elem)) { - goto fail; - } - } - - return 1; - -fail: - cut_list_back(o, orig_count); - return 0; -} - -static struct elem * find_elem (struct instance *o, NCDValRef val, uint64_t start_idx, uint64_t *out_idx) -{ - if (start_idx >= list_count(o)) { - return NULL; - } - - for (IndexedListNode *iln = IndexedList_GetAt(&o->il, start_idx); iln; iln = IndexedList_GetNext(&o->il, iln)) { - struct elem *e = UPPER_OBJECT(iln, struct elem, il_node); - if (NCDVal_Compare(e->val, val) == 0) { - if (out_idx) { - *out_idx = start_idx; - } - return e; - } - start_idx++; - } - - return NULL; -} - -static int list_to_value (NCDModuleInst *i, struct instance *o, NCDValMem *mem, NCDValRef *out_val) -{ - *out_val = NCDVal_NewList(mem, IndexedList_Count(&o->il)); - if (NCDVal_IsInvalid(*out_val)) { - goto fail; - } - - for (IndexedListNode *iln = IndexedList_GetFirst(&o->il); iln; iln = IndexedList_GetNext(&o->il, iln)) { - struct elem *e = UPPER_OBJECT(iln, struct elem, il_node); - - NCDValRef copy = NCDVal_NewCopy(mem, e->val); - if (NCDVal_IsInvalid(copy)) { - goto fail; - } - - if (!NCDVal_ListAppend(*out_val, copy)) { - goto fail; - } - } - - return 1; - -fail: - return 0; -} - -static void func_new_list (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // init list - IndexedList_Init(&o->il); - - // append contents - if (!append_list_contents(i, o, params->args)) { - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - cut_list_front(o, 0); - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_listfrom (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // init list - IndexedList_Init(&o->il); - - // append contents contents - if (!append_list_contents_contents(i, o, params->args)) { - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - cut_list_front(o, 0); - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free list elements - cut_list_front(o, 0); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (!strcmp(name, "")) { - if (!list_to_value(o->i, o, mem, out)) { - return 0; - } - - return 1; - } - - if (!strcmp(name, "length")) { - *out = ncd_make_uintmax(mem, list_count(o)); - return 1; - } - - return 0; -} - -static void append_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef arg; - if (!NCDVal_ListRead(params->args, 1, &arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // append - if (!insert_value(i, mo, arg, list_count(mo))) { - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void appendv_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef arg; - if (!NCDVal_ListRead(params->args, 1, &arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // append - if (!append_list_contents(i, mo, arg)) { - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void length_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct length_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // remember length - o->length = list_count(mo); - - // signal up - NCDModuleInst_Backend_Up(o->i); - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void length_func_die (void *vo) -{ - struct length_instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int length_func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct length_instance *o = vo; - - if (!strcmp(name, "")) { - *out = ncd_make_uintmax(mem, o->length); - return 1; - } - - return 0; -} - -static void get_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct get_instance *o = vo; - o->i = i; - - // check arguments - NCDValRef index_arg; - if (!NCDVal_ListRead(params->args, 1, &index_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(index_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - uintmax_t index; - if (!ncd_read_uintmax(index_arg, &index)) { - ModuleLog(o->i, BLOG_ERROR, "wrong value"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // check index - if (index >= list_count(mo)) { - ModuleLog(o->i, BLOG_ERROR, "no element at index %"PRIuMAX, index); - goto fail0; - } - - // get element - struct elem *e = get_elem_at(mo, index); - - // init mem - NCDValMem_Init(&o->mem); - - // copy value - o->val = NCDVal_NewCopy(&o->mem, e->val); - if (NCDVal_IsInvalid(o->val)) { - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValMem_Free(&o->mem); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void get_func_die (void *vo) -{ - struct get_instance *o = vo; - - // free mem - NCDValMem_Free(&o->mem); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int get_func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct get_instance *o = vo; - - if (!strcmp(name, "")) { - *out = NCDVal_NewCopy(mem, o->val); - return 1; - } - - return 0; -} - -static void shift_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // check first - if (list_count(mo) == 0) { - ModuleLog(i, BLOG_ERROR, "list has no elements"); - goto fail0; - } - - // remove first - remove_elem(mo, get_first_elem(mo)); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void contains_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct contains_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // search - o->contains = !!find_elem(mo, value_arg, 0, NULL); - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void contains_func_die (void *vo) -{ - struct contains_instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int contains_func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct contains_instance *o = vo; - - if (!strcmp(name, "")) { - *out = ncd_make_boolean(mem, o->contains, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void find_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct find_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef start_pos_arg; - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 2, &start_pos_arg, &value_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(start_pos_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // read start position - uintmax_t start_pos; - if (!ncd_read_uintmax(start_pos_arg, &start_pos) || start_pos > UINT64_MAX) { - ModuleLog(o->i, BLOG_ERROR, "wrong start pos"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // find - o->is_found = !!find_elem(mo, value_arg, start_pos, &o->found_pos); - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void find_func_die (void *vo) -{ - struct find_instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int find_func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct find_instance *o = vo; - - if (!strcmp(name, "pos")) { - char value[64] = "none"; - - if (o->is_found) { - generate_decimal_repr_string(o->found_pos, value); - } - - *out = NCDVal_NewString(mem, value); - return 1; - } - - if (!strcmp(name, "found")) { - *out = ncd_make_boolean(mem, o->is_found, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void removeat_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef remove_pos_arg; - if (!NCDVal_ListRead(params->args, 1, &remove_pos_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(remove_pos_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // read position - uintmax_t remove_pos; - if (!ncd_read_uintmax(remove_pos_arg, &remove_pos)) { - ModuleLog(i, BLOG_ERROR, "wrong pos"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // check position - if (remove_pos >= list_count(mo)) { - ModuleLog(i, BLOG_ERROR, "pos out of range"); - goto fail0; - } - - // remove - remove_elem(mo, get_elem_at(mo, remove_pos)); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void remove_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // find element - struct elem *e = find_elem(mo, value_arg, 0, NULL); - if (!e) { - ModuleLog(i, BLOG_ERROR, "value does not exist"); - goto fail0; - } - - // remove element - remove_elem(mo, e); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void set_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // remember old count - uint64_t old_count = list_count(mo); - - // append contents of our lists - if (!append_list_contents_contents(i, mo, params->args)) { - goto fail0; - } - - // remove old elements - cut_list_front(mo, list_count(mo) - old_count); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "list", - .func_new2 = func_new_list, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "listfrom", - .base_type = "list", - .func_new2 = func_new_listfrom, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "concatlist", // alias for listfrom - .base_type = "list", - .func_new2 = func_new_listfrom, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "list::append", - .func_new2 = append_func_new - }, { - .type = "list::appendv", - .func_new2 = appendv_func_new - }, { - .type = "list::length", - .func_new2 = length_func_new, - .func_die = length_func_die, - .func_getvar = length_func_getvar, - .alloc_size = sizeof(struct length_instance) - }, { - .type = "list::get", - .func_new2 = get_func_new, - .func_die = get_func_die, - .func_getvar = get_func_getvar, - .alloc_size = sizeof(struct get_instance) - }, { - .type = "list::shift", - .func_new2 = shift_func_new - }, { - .type = "list::contains", - .func_new2 = contains_func_new, - .func_die = contains_func_die, - .func_getvar = contains_func_getvar, - .alloc_size = sizeof(struct contains_instance) - }, { - .type = "list::find", - .func_new2 = find_func_new, - .func_die = find_func_die, - .func_getvar = find_func_getvar, - .alloc_size = sizeof(struct find_instance) - }, { - .type = "list::remove_at", - .func_new2 = removeat_func_new - }, { - .type = "list::remove", - .func_new2 = remove_func_new - }, { - .type = "list::set", - .func_new2 = set_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_list = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/load_module.c b/external/badvpn_dns/ncd/modules/load_module.c deleted file mode 100644 index f9bf832..0000000 --- a/external/badvpn_dns/ncd/modules/load_module.c +++ /dev/null @@ -1,313 +0,0 @@ -/** - * @file load_module.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * load_module(string name) - */ - -#include <stddef.h> -#include <limits.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <dlfcn.h> - -#include <misc/balloc.h> -#include <misc/concat_strings.h> -#include <misc/strdup.h> -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/LinkedList0.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_load_module.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -struct global { - LinkedList0 modules_list; -}; - -struct module { - char *name; - void *lib_handle; - int ncdmodule_loaded; - LinkedList0Node modules_list_node; -}; - -static struct module * find_module (const char *name, struct global *g) -{ - for (LinkedList0Node *ln = LinkedList0_GetFirst(&g->modules_list); ln; ln = LinkedList0Node_Next(ln)) { - struct module *mod = UPPER_OBJECT(ln, struct module, modules_list_node); - if (!strcmp(mod->name, name)) { - return mod; - } - } - return NULL; -} - -static struct module * module_init (const char *name, NCDModuleInst *i) -{ - struct global *g = ModuleGlobal(i); - ASSERT(!find_module(name, g)) - - struct module *mod = BAlloc(sizeof(*mod)); - if (!mod) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - goto fail0; - } - - mod->name = b_strdup(name); - if (!mod->name) { - ModuleLog(i, BLOG_ERROR, "b_strdup failed"); - goto fail1; - } - - mod->lib_handle = NULL; - mod->ncdmodule_loaded = 0; - LinkedList0_Prepend(&g->modules_list, &mod->modules_list_node); - - return mod; - -fail1: - BFree(mod); -fail0: - return NULL; -} - -static void module_free (struct module *mod, struct global *g) -{ - LinkedList0_Remove(&g->modules_list, &mod->modules_list_node); - if (mod->lib_handle) { - if (dlclose(mod->lib_handle) != 0) { - BLog(BLOG_ERROR, "dlclose failed"); - } - } - BFree(mod->name); - BFree(mod); -} - -static char * x_read_link (const char *path) -{ - size_t size = 32; - char *buf = BAlloc(size + 1); - if (!buf) { - goto fail0; - } - - ssize_t link_size; - while (1) { - link_size = readlink(path, buf, size); - if (link_size < 0) { - goto fail1; - } - if (link_size >= 0 && link_size < size) { - break; - } - if (size > SIZE_MAX / 2 || 2 * size > SIZE_MAX - 1) { - goto fail1; - } - size *= 2; - char *new_buf = BRealloc(buf, size + 1); - if (!new_buf) { - goto fail1; - } - buf = new_buf; - } - - buf[link_size] = '\0'; - return buf; - -fail1: - BFree(buf); -fail0: - return NULL; -} - -static char * find_module_library (NCDModuleInst *i, const char *module_name) -{ - char *ret = NULL; - - char *self = x_read_link("/proc/self/exe"); - if (!self) { - ModuleLog(i, BLOG_ERROR, "failed to read /proc/self/exe"); - goto fail0; - } - - char *slash = strrchr(self, '/'); - if (!slash) { - ModuleLog(i, BLOG_ERROR, "contents of /proc/self/exe do not have a slash"); - goto fail1; - } - *slash = '\0'; - - const char *paths[] = {"../lib/badvpn-ncd", "../mcvpn", NULL}; - - size_t j; - for (j = 0; paths[j]; j++) { - char *module_path = concat_strings(6, self, "/", paths[j], "/libncdmodule_", module_name, ".so"); - if (!module_path) { - ModuleLog(i, BLOG_ERROR, "concat_strings failed"); - goto fail1; - } - - if (access(module_path, F_OK) == 0) { - ret = module_path; - break; - } - - BFree(module_path); - } - - if (!paths[j]) { - ModuleLog(i, BLOG_ERROR, "failed to find module"); - } - -fail1: - BFree(self); -fail0: - return ret; -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - group->group_state = g; - LinkedList0_Init(&g->modules_list); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - - LinkedList0Node *ln; - while ((ln = LinkedList0_GetFirst(&g->modules_list))) { - struct module *mod = UPPER_OBJECT(ln, struct module, modules_list_node); - module_free(mod, g); - } - - BFree(g); -} - -static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - struct module *mod = find_module(NCDVal_StringData(name_arg), ModuleGlobal(i)); - ASSERT(!mod || mod->lib_handle) - - if (!mod) { - mod = module_init(NCDVal_StringData(name_arg), i); - if (!mod) { - ModuleLog(i, BLOG_ERROR, "module_init failed"); - goto fail0; - } - - // find module library - char *module_path = find_module_library(i, NCDVal_StringData(name_arg)); - if (!module_path) { - module_free(mod, ModuleGlobal(i)); - goto fail0; - } - - // load it as a dynamic library - mod->lib_handle = dlopen(module_path, RTLD_NOW); - BFree(module_path); - if (!mod->lib_handle) { - ModuleLog(i, BLOG_ERROR, "dlopen failed"); - module_free(mod, ModuleGlobal(i)); - goto fail0; - } - } - - if (!mod->ncdmodule_loaded) { - // build name of NCDModuleGroup structure symbol - char *group_symbol = concat_strings(2, "ncdmodule_", NCDVal_StringData(name_arg)); - if (!group_symbol) { - ModuleLog(i, BLOG_ERROR, "concat_strings failed"); - goto fail0; - } - - // resolve NCDModuleGroup structure symbol - void *group = dlsym(mod->lib_handle, group_symbol); - BFree(group_symbol); - if (!group) { - ModuleLog(i, BLOG_ERROR, "dlsym failed"); - goto fail0; - } - - // load module group - if (!NCDModuleInst_Backend_InterpLoadGroup(i, (struct NCDModuleGroup *)group)) { - ModuleLog(i, BLOG_ERROR, "NCDModuleInst_Backend_InterpLoadGroup failed"); - goto fail0; - } - - mod->ncdmodule_loaded = 1; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "load_module", - .func_new2 = func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_load_module = { - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree, - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/log.c b/external/badvpn_dns/ncd/modules/log.c deleted file mode 100644 index 5b4251d..0000000 --- a/external/badvpn_dns/ncd/modules/log.c +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @file log.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Message logging using the BLog system provided by the BadVPN framework. - * Each message has an associated loglevel, which must be one of: "error, "warning", - * "notice", "info", "debug", or a numeric identifier (1=error to 5=debug). - * - * Synopsis: - * log(string level [, string ...]) - * - * Description: - * On init, logs the concatenation of the given strings. - * - * Synopsis: - * log_r(string level [, string ...]) - * - * Description: - * On deinit, logs the concatenation of the given strings. - * - * Synopsis: - * log_fr(string level, list(string) strings_init, list(string) strings_deinit) - * - * Description: - * On init, logs the concatenation of the strings in 'strings_init', - * and on deinit, logs the concatenation of the strings in 'strings_deinit'. - */ - -#include <stdlib.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_log.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -struct rlog_instance { - NCDModuleInst *i; - int level; - NCDValRef list; - size_t start; -}; - -enum {STRING_ERROR, STRING_WARNING, STRING_NOTICE, STRING_INFO, STRING_DEBUG}; - -static const char *strings[] = { - "error", "warning", "notice", "info", "debug", NULL -}; - -static int check_strings (NCDValRef list, size_t start) -{ - ASSERT(NCDVal_IsList(list)) - - size_t count = NCDVal_ListCount(list); - - for (size_t j = start; j < count; j++) { - NCDValRef string = NCDVal_ListGet(list, j); - if (!NCDVal_IsString(string)) { - return 0; - } - } - - return 1; -} - -static void do_log (int level, NCDValRef list, size_t start) -{ - ASSERT(level >= BLOG_ERROR) - ASSERT(level <= BLOG_DEBUG) - ASSERT(check_strings(list, start)) - - if (!BLog_WouldLog(BLOG_CHANNEL_ncd_log_msg, level)) { - return; - } - - size_t count = NCDVal_ListCount(list); - - BLog_Begin(); - - for (size_t j = start; j < count; j++) { - NCDValRef string = NCDVal_ListGet(list, j); - ASSERT(NCDVal_IsString(string)) - BLog_AppendBytes(NCDVal_StringData(string), NCDVal_StringLength(string)); - } - - BLog_Finish(BLOG_CHANNEL_ncd_log_msg, level); -} - -static int parse_level (NCDModuleInst *i, NCDValRef level_arg, int *out_level) -{ - if (!NCDVal_IsString(level_arg)) { - return 0; - } - - NCDStringIndex *string_index = i->params->iparams->string_index; - - uintmax_t level_numeric; - if (ncd_read_uintmax(level_arg, &level_numeric) && level_numeric >= BLOG_ERROR && level_numeric <= BLOG_DEBUG) { - *out_level = level_numeric; - } - else if (NCDVal_StringEqualsId(level_arg, ModuleString(i, STRING_ERROR), string_index)) { - *out_level = BLOG_ERROR; - } - else if (NCDVal_StringEqualsId(level_arg, ModuleString(i, STRING_WARNING), string_index)) { - *out_level = BLOG_WARNING; - } - else if (NCDVal_StringEqualsId(level_arg, ModuleString(i, STRING_NOTICE), string_index)) { - *out_level = BLOG_NOTICE; - } - else if (NCDVal_StringEqualsId(level_arg, ModuleString(i, STRING_INFO), string_index)) { - *out_level = BLOG_INFO; - } - else if (NCDVal_StringEqualsId(level_arg, ModuleString(i, STRING_DEBUG), string_index)) { - *out_level = BLOG_DEBUG; - } - else { - return 0; - } - - return 1; -} - -static void rlog_func_new_common (void *vo, NCDModuleInst *i, int level, NCDValRef list, size_t start) -{ - ASSERT(level >= BLOG_ERROR) - ASSERT(level <= BLOG_DEBUG) - ASSERT(check_strings(list, start)) - - struct rlog_instance *o = vo; - o->i = i; - o->level = level; - o->list = list; - o->start = start; - - NCDModuleInst_Backend_Up(i); -} - -static void rlog_func_die (void *vo) -{ - struct rlog_instance *o = vo; - - do_log(o->level, o->list, o->start); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void log_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (NCDVal_ListCount(params->args) < 1) { - ModuleLog(i, BLOG_ERROR, "missing level argument"); - goto fail0; - } - - int level; - if (!parse_level(i, NCDVal_ListGet(params->args, 0), &level)) { - ModuleLog(i, BLOG_ERROR, "wrong level argument"); - goto fail0; - } - - if (!check_strings(params->args, 1)) { - ModuleLog(i, BLOG_ERROR, "wrong string arguments"); - goto fail0; - } - - do_log(level, params->args, 1); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void log_r_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (NCDVal_ListCount(params->args) < 1) { - ModuleLog(i, BLOG_ERROR, "missing level argument"); - goto fail0; - } - - int level; - if (!parse_level(i, NCDVal_ListGet(params->args, 0), &level)) { - ModuleLog(i, BLOG_ERROR, "wrong level argument"); - goto fail0; - } - - if (!check_strings(params->args, 1)) { - ModuleLog(i, BLOG_ERROR, "wrong string arguments"); - goto fail0; - } - - rlog_func_new_common(vo, i, level, params->args, 1); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void log_fr_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef level_arg; - NCDValRef strings_init_arg; - NCDValRef strings_deinit_arg; - if (!NCDVal_ListRead(params->args, 3, &level_arg, &strings_init_arg, &strings_deinit_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - int level; - if (!parse_level(i, level_arg, &level)) { - ModuleLog(i, BLOG_ERROR, "wrong level argument"); - goto fail0; - } - - if (!NCDVal_IsList(strings_init_arg) || !check_strings(strings_init_arg, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong string_init argument"); - goto fail0; - } - - if (!NCDVal_IsList(strings_deinit_arg) || !check_strings(strings_deinit_arg, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong strings_deinit argument"); - goto fail0; - } - - do_log(level, strings_init_arg, 0); - - rlog_func_new_common(vo, i, level, strings_deinit_arg, 0); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "log", - .func_new2 = log_func_new - }, { - .type = "log_r", - .func_new2 = log_r_func_new, - .func_die = rlog_func_die, - .alloc_size = sizeof(struct rlog_instance) - }, { - .type = "log_fr", - .func_new2 = log_fr_func_new, - .func_die = rlog_func_die, - .alloc_size = sizeof(struct rlog_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_log = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/logical.c b/external/badvpn_dns/ncd/modules/logical.c deleted file mode 100644 index 8ac6660..0000000 --- a/external/badvpn_dns/ncd/modules/logical.c +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file logical.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module for logical operators. - * - * Synopsis: not(string val) - * Variables: - * string (empty) - "true" if val does not equal "true", "false" otherwise - * - * Synopsis: or([string val1, ...]) - * Variables: - * string (empty) - "true" if at least one of the values equals "true", "false" otherwise - * - * Synopsis: and([string val1, ...]) - * Variables: - * string (empty) - "true" if all of the values equal "true", "false" otherwise - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_logical.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - int value; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_not, int is_or) -{ - struct instance *o = vo; - o->i = i; - - // compute value from arguments - if (is_not) { - NCDValRef arg; - if (!NCDVal_ListRead(params->args, 1, &arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->value = !ncd_read_boolean(arg); - } else { - o->value = (is_or ? 0 : 1); - - size_t count = NCDVal_ListCount(params->args); - - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(params->args, j); - - if (!NCDVal_IsString(arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - int this_value = ncd_read_boolean(arg); - if (is_or) { - o->value = o->value || this_value; - } else { - o->value = o->value && this_value; - } - } - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_not (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, 1, 0); -} - -static void func_new_or (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, 0, 1); -} - -static void func_new_and (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, 0, 0); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = ncd_make_boolean(mem, o->value, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "not", - .func_new2 = func_new_not, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "or", - .func_new2 = func_new_or, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "and", - .func_new2 = func_new_and, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_logical = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/modules.h b/external/badvpn_dns/ncd/modules/modules.h deleted file mode 100644 index ea39027..0000000 --- a/external/badvpn_dns/ncd/modules/modules.h +++ /dev/null @@ -1,210 +0,0 @@ -/** - * @file modules.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_NCD_MODULES_MODULES_H -#define BADVPN_NCD_MODULES_MODULES_H - -#include <stddef.h> - -#include <ncd/NCDModule.h> - -extern const struct NCDModuleGroup ncdmodule_var; -extern const struct NCDModuleGroup ncdmodule_list; -extern const struct NCDModuleGroup ncdmodule_depend; -extern const struct NCDModuleGroup ncdmodule_multidepend; -extern const struct NCDModuleGroup ncdmodule_dynamic_depend; -extern const struct NCDModuleGroup ncdmodule_concat; -extern const struct NCDModuleGroup ncdmodule_if; -extern const struct NCDModuleGroup ncdmodule_strcmp; -extern const struct NCDModuleGroup ncdmodule_logical; -extern const struct NCDModuleGroup ncdmodule_sleep; -extern const struct NCDModuleGroup ncdmodule_print; -extern const struct NCDModuleGroup ncdmodule_blocker; -extern const struct NCDModuleGroup ncdmodule_spawn; -extern const struct NCDModuleGroup ncdmodule_imperative; -extern const struct NCDModuleGroup ncdmodule_ref; -extern const struct NCDModuleGroup ncdmodule_index; -extern const struct NCDModuleGroup ncdmodule_alias; -extern const struct NCDModuleGroup ncdmodule_process_manager; -extern const struct NCDModuleGroup ncdmodule_ondemand; -extern const struct NCDModuleGroup ncdmodule_foreach; -extern const struct NCDModuleGroup ncdmodule_choose; -extern const struct NCDModuleGroup ncdmodule_from_string; -extern const struct NCDModuleGroup ncdmodule_to_string; -extern const struct NCDModuleGroup ncdmodule_value; -extern const struct NCDModuleGroup ncdmodule_try; -extern const struct NCDModuleGroup ncdmodule_exit; -extern const struct NCDModuleGroup ncdmodule_getargs; -extern const struct NCDModuleGroup ncdmodule_arithmetic; -extern const struct NCDModuleGroup ncdmodule_parse; -extern const struct NCDModuleGroup ncdmodule_valuemetic; -extern const struct NCDModuleGroup ncdmodule_file; -extern const struct NCDModuleGroup ncdmodule_netmask; -extern const struct NCDModuleGroup ncdmodule_implode; -extern const struct NCDModuleGroup ncdmodule_call2; -extern const struct NCDModuleGroup ncdmodule_assert; -extern const struct NCDModuleGroup ncdmodule_explode; -extern const struct NCDModuleGroup ncdmodule_net_ipv4_addr_in_network; -extern const struct NCDModuleGroup ncdmodule_net_ipv6_addr_in_network; -extern const struct NCDModuleGroup ncdmodule_timer; -extern const struct NCDModuleGroup ncdmodule_file_open; -extern const struct NCDModuleGroup ncdmodule_backtrack; -extern const struct NCDModuleGroup ncdmodule_depend_scope; -extern const struct NCDModuleGroup ncdmodule_substr; -extern const struct NCDModuleGroup ncdmodule_log; -extern const struct NCDModuleGroup ncdmodule_buffer; -extern const struct NCDModuleGroup ncdmodule_getenv; -#ifndef BADVPN_EMSCRIPTEN -extern const struct NCDModuleGroup ncdmodule_regex_match; -extern const struct NCDModuleGroup ncdmodule_run; -extern const struct NCDModuleGroup ncdmodule_runonce; -extern const struct NCDModuleGroup ncdmodule_daemon; -extern const struct NCDModuleGroup ncdmodule_net_backend_waitdevice; -extern const struct NCDModuleGroup ncdmodule_net_backend_waitlink; -extern const struct NCDModuleGroup ncdmodule_net_backend_badvpn; -extern const struct NCDModuleGroup ncdmodule_net_backend_wpa_supplicant; -#ifdef BADVPN_USE_LINUX_RFKILL -extern const struct NCDModuleGroup ncdmodule_net_backend_rfkill; -#endif -extern const struct NCDModuleGroup ncdmodule_net_up; -extern const struct NCDModuleGroup ncdmodule_net_dns; -extern const struct NCDModuleGroup ncdmodule_net_iptables; -extern const struct NCDModuleGroup ncdmodule_net_ipv4_addr; -extern const struct NCDModuleGroup ncdmodule_net_ipv4_route; -extern const struct NCDModuleGroup ncdmodule_net_ipv4_dhcp; -extern const struct NCDModuleGroup ncdmodule_net_ipv4_arp_probe; -extern const struct NCDModuleGroup ncdmodule_net_watch_interfaces; -extern const struct NCDModuleGroup ncdmodule_sys_watch_input; -extern const struct NCDModuleGroup ncdmodule_sys_watch_usb; -#ifdef BADVPN_USE_LINUX_INPUT -extern const struct NCDModuleGroup ncdmodule_sys_evdev; -#endif -#ifdef BADVPN_USE_INOTIFY -extern const struct NCDModuleGroup ncdmodule_sys_watch_directory; -#endif -extern const struct NCDModuleGroup ncdmodule_sys_request_server; -extern const struct NCDModuleGroup ncdmodule_net_ipv6_wait_dynamic_addr; -extern const struct NCDModuleGroup ncdmodule_sys_request_client; -extern const struct NCDModuleGroup ncdmodule_reboot; -extern const struct NCDModuleGroup ncdmodule_net_ipv6_addr; -extern const struct NCDModuleGroup ncdmodule_net_ipv6_route; -extern const struct NCDModuleGroup ncdmodule_socket; -extern const struct NCDModuleGroup ncdmodule_sys_start_process; -extern const struct NCDModuleGroup ncdmodule_load_module; -#endif - -static const struct NCDModuleGroup *ncd_modules[] = { - &ncdmodule_var, - &ncdmodule_list, - &ncdmodule_depend, - &ncdmodule_multidepend, - &ncdmodule_dynamic_depend, - &ncdmodule_concat, - &ncdmodule_if, - &ncdmodule_strcmp, - &ncdmodule_logical, - &ncdmodule_sleep, - &ncdmodule_print, - &ncdmodule_blocker, - &ncdmodule_spawn, - &ncdmodule_imperative, - &ncdmodule_ref, - &ncdmodule_index, - &ncdmodule_alias, - &ncdmodule_process_manager, - &ncdmodule_ondemand, - &ncdmodule_foreach, - &ncdmodule_choose, - &ncdmodule_from_string, - &ncdmodule_to_string, - &ncdmodule_value, - &ncdmodule_try, - &ncdmodule_exit, - &ncdmodule_getargs, - &ncdmodule_arithmetic, - &ncdmodule_parse, - &ncdmodule_valuemetic, - &ncdmodule_file, - &ncdmodule_netmask, - &ncdmodule_implode, - &ncdmodule_call2, - &ncdmodule_assert, - &ncdmodule_explode, - &ncdmodule_net_ipv4_addr_in_network, - &ncdmodule_net_ipv6_addr_in_network, - &ncdmodule_timer, - &ncdmodule_file_open, - &ncdmodule_backtrack, - &ncdmodule_depend_scope, - &ncdmodule_substr, - &ncdmodule_log, - &ncdmodule_buffer, - &ncdmodule_getenv, -#ifndef BADVPN_EMSCRIPTEN - &ncdmodule_regex_match, - &ncdmodule_run, - &ncdmodule_runonce, - &ncdmodule_daemon, - &ncdmodule_net_backend_waitdevice, - &ncdmodule_net_backend_waitlink, - &ncdmodule_net_backend_badvpn, - &ncdmodule_net_backend_wpa_supplicant, -#ifdef BADVPN_USE_LINUX_RFKILL - &ncdmodule_net_backend_rfkill, -#endif - &ncdmodule_net_up, - &ncdmodule_net_dns, - &ncdmodule_net_iptables, - &ncdmodule_net_ipv4_addr, - &ncdmodule_net_ipv4_route, - &ncdmodule_net_ipv4_dhcp, - &ncdmodule_net_ipv4_arp_probe, - &ncdmodule_net_watch_interfaces, - &ncdmodule_sys_watch_input, - &ncdmodule_sys_watch_usb, -#ifdef BADVPN_USE_LINUX_INPUT - &ncdmodule_sys_evdev, -#endif -#ifdef BADVPN_USE_INOTIFY - &ncdmodule_sys_watch_directory, -#endif - &ncdmodule_sys_request_server, - &ncdmodule_net_ipv6_wait_dynamic_addr, - &ncdmodule_sys_request_client, - &ncdmodule_reboot, - &ncdmodule_net_ipv6_addr, - &ncdmodule_net_ipv6_route, - &ncdmodule_socket, - &ncdmodule_sys_start_process, - &ncdmodule_load_module, -#endif - NULL -}; - -#endif diff --git a/external/badvpn_dns/ncd/modules/multidepend.c b/external/badvpn_dns/ncd/modules/multidepend.c deleted file mode 100644 index 9b201ae..0000000 --- a/external/badvpn_dns/ncd/modules/multidepend.c +++ /dev/null @@ -1,401 +0,0 @@ -/** - * @file multidepend.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * This is a compatibility module. It behaves exactly like the depend_scope module, - * except that there is a single global scope for dependency names. - * - * Use depend_scope instead. If you are using multidepend between non-template - * processes, make those processes templates instead and start them via - * process_manager(). For example, instead of this: - * - * process foo { - * multiprovide("FOO"); - * } - * - * process bar { - * multidepend({"FOO"}); - * } - * - * Use this: - * - * process main { - * depend_scope() scope; - * process_manager() mgr; - * mgr->start("foo", "foo", {}); - * mgr->start("bar", "bar", {}); - * } - * - * template foo { - * _caller.scope->provide("FOO"); - * } - * - * template bar { - * _caller.scope->depend({"FOO"}); - * } - * - * Synopsis: - * multiprovide(name) - * - * Synopsis: - * multidepend(list names) - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_multidepend.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -struct provide { - NCDModuleInst *i; - NCDValRef name; - LinkedList1Node provides_list_node; - LinkedList1 depends_list; - int dying; -}; - -struct depend { - NCDModuleInst *i; - NCDValRef names; - LinkedList1Node depends_list_node; - struct provide *provide; - LinkedList1Node provide_depends_list_node; - int provide_collapsing; -}; - -struct global { - LinkedList1 provides_list; - LinkedList1 depends_list; -}; - -static struct provide * find_provide (struct global *g, NCDValRef name) -{ - for (LinkedList1Node *ln = LinkedList1_GetFirst(&g->provides_list); ln; ln = LinkedList1Node_Next(ln)) { - struct provide *provide = UPPER_OBJECT(ln, struct provide, provides_list_node); - if (NCDVal_Compare(provide->name, name) == 0) { - return provide; - } - } - - return NULL; -} - -static struct provide * depend_find_best_provide (struct depend *o) -{ - struct global *g = ModuleGlobal(o->i); - - size_t count = NCDVal_ListCount(o->names); - - for (size_t j = 0; j < count; j++) { - NCDValRef name = NCDVal_ListGet(o->names, j); - struct provide *provide = find_provide(g, name); - if (provide && !provide->dying) { - return provide; - } - } - - return NULL; -} - -static void depend_update (struct depend *o) -{ - // if we're collapsing, do nothing - if (o->provide && o->provide_collapsing) { - return; - } - - // find best provide - struct provide *best_provide = depend_find_best_provide(o); - ASSERT(!best_provide || !best_provide->dying) - - // has anything changed? - if (best_provide == o->provide) { - return; - } - - if (o->provide) { - // set collapsing - o->provide_collapsing = 1; - - // signal down - NCDModuleInst_Backend_Down(o->i); - } else { - // insert to provide's list - LinkedList1_Append(&best_provide->depends_list, &o->provide_depends_list_node); - - // set not collapsing - o->provide_collapsing = 0; - - // set provide - o->provide = best_provide; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - // allocate global state structure - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - // set group state pointer - group->group_state = g; - - // init provides list - LinkedList1_Init(&g->provides_list); - - // init depends list - LinkedList1_Init(&g->depends_list); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - ASSERT(LinkedList1_IsEmpty(&g->depends_list)) - ASSERT(LinkedList1_IsEmpty(&g->provides_list)) - - // free global state structure - BFree(g); -} - -static void provide_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct provide *o = vo; - o->i = i; - - // read arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // remember name - o->name = name_arg; - - // check for existing provide with this name - if (find_provide(g, o->name)) { - ModuleLog(o->i, BLOG_ERROR, "a provide with this name already exists"); - goto fail0; - } - - // insert to provides list - LinkedList1_Append(&g->provides_list, &o->provides_list_node); - - // init depends list - LinkedList1_Init(&o->depends_list); - - // set not dying - o->dying = 0; - - // signal up. - // This comes above the loop which follows, so that effects on related depend statements are - // computed before this process advances, avoiding problems like failed variable resolutions. - NCDModuleInst_Backend_Up(o->i); - - // update depends - for (LinkedList1Node *ln = LinkedList1_GetFirst(&g->depends_list); ln; ln = LinkedList1Node_Next(ln)) { - struct depend *depend = UPPER_OBJECT(ln, struct depend, depends_list_node); - depend_update(depend); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void provide_free (struct provide *o) -{ - struct global *g = ModuleGlobal(o->i); - ASSERT(LinkedList1_IsEmpty(&o->depends_list)) - - // remove from provides list - LinkedList1_Remove(&g->provides_list, &o->provides_list_node); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void provide_func_die (void *vo) -{ - struct provide *o = vo; - ASSERT(!o->dying) - - // if we have no depends, die immediately - if (LinkedList1_IsEmpty(&o->depends_list)) { - provide_free(o); - return; - } - - // set dying - o->dying = 1; - - // start collapsing our depends - for (LinkedList1Node *ln = LinkedList1_GetFirst(&o->depends_list); ln; ln = LinkedList1Node_Next(ln)) { - struct depend *depend = UPPER_OBJECT(ln, struct depend, provide_depends_list_node); - ASSERT(depend->provide == o) - - // update depend to make sure it is collapsing - depend_update(depend); - } -} - -static void depend_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct depend *o = vo; - o->i = i; - - // read arguments - NCDValRef names_arg; - if (!NCDVal_ListRead(params->args, 1, &names_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(names_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // remember names - o->names = names_arg; - - // insert to depends list - LinkedList1_Append(&g->depends_list, &o->depends_list_node); - - // set no provide - o->provide = NULL; - - // update - depend_update(o); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void depend_func_die (void *vo) -{ - struct depend *o = vo; - struct global *g = ModuleGlobal(o->i); - - if (o->provide) { - // remove from provide's list - LinkedList1_Remove(&o->provide->depends_list, &o->provide_depends_list_node); - - // if provide is dying and is empty, let it die - if (o->provide->dying && LinkedList1_IsEmpty(&o->provide->depends_list)) { - provide_free(o->provide); - } - } - - // remove from depends list - LinkedList1_Remove(&g->depends_list, &o->depends_list_node); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void depend_func_clean (void *vo) -{ - struct depend *o = vo; - - if (!(o->provide && o->provide_collapsing)) { - return; - } - - // save provide - struct provide *provide = o->provide; - - // remove from provide's list - LinkedList1_Remove(&provide->depends_list, &o->provide_depends_list_node); - - // set no provide - o->provide = NULL; - - // update - depend_update(o); - - // if provide is dying and is empty, let it die - if (provide->dying && LinkedList1_IsEmpty(&provide->depends_list)) { - provide_free(provide); - } -} - -static int depend_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct depend *o = vo; - - if (!o->provide) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(o->provide->i, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "multiprovide", - .func_new2 = provide_func_new, - .func_die = provide_func_die, - .alloc_size = sizeof(struct provide) - }, { - .type = "multidepend", - .func_new2 = depend_func_new, - .func_die = depend_func_die, - .func_clean = depend_func_clean, - .func_getobj = depend_func_getobj, - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, - .alloc_size = sizeof(struct depend) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_multidepend = { - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree, - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_backend_badvpn.c b/external/badvpn_dns/ncd/modules/net_backend_badvpn.c deleted file mode 100644 index 572ae71..0000000 --- a/external/badvpn_dns/ncd/modules/net_backend_badvpn.c +++ /dev/null @@ -1,281 +0,0 @@ -/** - * @file net_backend_badvpn.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * BadVPN interface module. - * - * Synopsis: net.backend.badvpn(string ifname, string user, string exec, list(string) args) - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/cmdline.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> - -#include <generated/blog_channel_ncd_net_backend_badvpn.h> - -#define RETRY_TIME 5000 - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValNullTermString ifname_nts; - const char *user; - size_t user_len; - const char *exec; - size_t exec_len; - NCDValRef args; - int dying; - int started; - BTimer timer; - BProcess process; -}; - -static void try_process (struct instance *o); -static void process_handler (struct instance *o, int normally, uint8_t normally_exit_status); -static void timer_handler (struct instance *o); -static void instance_free (struct instance *o); - -void try_process (struct instance *o) -{ - CmdLine c; - if (!CmdLine_Init(&c)) { - goto fail0; - } - - // append exec - if (!CmdLine_AppendNoNull(&c, o->exec, o->exec_len)) { - goto fail1; - } - - // append tapdev - if (!CmdLine_Append(&c, "--tapdev") || !CmdLine_Append(&c, o->ifname_nts.data)) { - goto fail1; - } - - // append arguments - size_t count = NCDVal_ListCount(o->args); - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(o->args, j); - if (!CmdLine_AppendNoNull(&c, NCDVal_StringData(arg), NCDVal_StringLength(arg))) { - goto fail1; - } - } - - // terminate cmdline - if (!CmdLine_Finish(&c)) { - goto fail1; - } - - // start process - if (!BProcess_Init(&o->process, o->i->params->iparams->manager, (BProcess_handler)process_handler, o, ((char **)c.arr.v)[0], (char **)c.arr.v, o->user)) { - ModuleLog(o->i, BLOG_ERROR, "BProcess_Init failed"); - goto fail1; - } - - CmdLine_Free(&c); - - // set started - o->started = 1; - - return; - -fail1: - CmdLine_Free(&c); -fail0: - // retry - o->started = 0; - BReactor_SetTimer(o->i->params->iparams->reactor, &o->timer); -} - -void process_handler (struct instance *o, int normally, uint8_t normally_exit_status) -{ - ASSERT(o->started) - - ModuleLog(o->i, BLOG_INFO, "process terminated"); - - // free process - BProcess_Free(&o->process); - - // set not started - o->started = 0; - - if (o->dying) { - instance_free(o); - return; - } - - // set timer - BReactor_SetTimer(o->i->params->iparams->reactor, &o->timer); -} - -void timer_handler (struct instance *o) -{ - ASSERT(!o->started) - - ModuleLog(o->i, BLOG_INFO, "retrying"); - - // try starting process again - try_process(o); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - NCDValRef user_arg; - NCDValRef exec_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 4, &ifname_arg, &user_arg, &exec_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsStringNoNulls(user_arg) || - !NCDVal_IsStringNoNulls(exec_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->user = NCDVal_StringData(user_arg); - o->user_len = NCDVal_StringLength(user_arg); - o->exec = NCDVal_StringData(exec_arg); - o->exec_len = NCDVal_StringLength(exec_arg); - o->args = args_arg; - - // check arguments - size_t count = NCDVal_ListCount(o->args); - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(o->args, j); - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - } - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // create TAP device - if (!NCDIfConfig_make_tuntap(o->ifname_nts.data, o->user, 0)) { - ModuleLog(o->i, BLOG_ERROR, "failed to create TAP device"); - goto fail1; - } - - // set device up - if (!NCDIfConfig_set_up(o->ifname_nts.data)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set device up"); - goto fail2; - } - - // set not dying - o->dying = 0; - - // init timer - BTimer_Init(&o->timer, RETRY_TIME, (BTimer_handler)timer_handler, o); - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // try starting process - try_process(o); - return; - -fail2: - if (!NCDIfConfig_remove_tuntap(o->ifname_nts.data, 0)) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove TAP device"); - } -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o) -{ - ASSERT(!o->started) - - // free timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - // set device down - if (!NCDIfConfig_set_down(o->ifname_nts.data)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set device down"); - } - - // free TAP device - if (!NCDIfConfig_remove_tuntap(o->ifname_nts.data, 0)) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove TAP device"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - if (!o->started) { - instance_free(o); - return; - } - - // request termination - BProcess_Terminate(&o->process); - - // remember dying - o->dying = 1; -} - -static struct NCDModule modules[] = { - { - .type = "net.backend.badvpn", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_backend_badvpn = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_backend_rfkill.c b/external/badvpn_dns/ncd/modules/net_backend_rfkill.c deleted file mode 100644 index 311d973..0000000 --- a/external/badvpn_dns/ncd/modules/net_backend_rfkill.c +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file net_backend_rfkill.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Rfkill monitoring module. - * - * Synopsis: net.backend.rfkill(string type, string name) - * Arguments: - * type - method of determining the index of the rfkill device. "index" for - * rfkill device index, "wlan" for wireless device. Be aware that, for - * the wireless device method, the index is resloved at initialization, - * and no attempt is made to refresh it if the device goes away. In other - * words, you should probably put a "net.backend.waitdevice" statement - * in front of the rfkill statement. - * name - rfkill index or wireless device name - */ - -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <stdio.h> -#include <sys/types.h> -#include <dirent.h> - -#include <misc/string_begins_with.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDRfkillMonitor.h> - -#include <generated/blog_channel_ncd_net_backend_rfkill.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - uint32_t index; - NCDRfkillMonitor monitor; - int up; -}; - -static int find_wlan_rfill (const char *ifname, uint32_t *out_index) -{ - char ieee_path[100]; - snprintf(ieee_path, sizeof(ieee_path), "/sys/class/net/%s/../../ieee80211", ifname); - - int res = 0; - - DIR *d = opendir(ieee_path); - if (!d) { - goto fail0; - } - - struct dirent *e; - while (e = readdir(d)) { - if (!string_begins_with(e->d_name, "phy")) { - continue; - } - - char phy_path[150]; - snprintf(phy_path, sizeof(phy_path), "%s/%s", ieee_path, e->d_name); - - DIR *d2 = opendir(phy_path); - if (!d2) { - continue; - } - - struct dirent *e2; - while (e2 = readdir(d2)) { - int index_pos; - if (!(index_pos = string_begins_with(e2->d_name, "rfkill"))) { - continue; - } - - uint32_t index; - if (sscanf(e2->d_name + index_pos, "%"SCNu32, &index) != 1) { - continue; - } - - res = 1; - *out_index = index; - } - - closedir(d2); - } - - closedir(d); -fail0: - return res; -} - -static void monitor_handler (struct instance *o, struct rfkill_event event) -{ - if (event.idx != o->index) { - return; - } - - int was_up = o->up; - o->up = (event.op != RFKILL_OP_DEL && !event.soft && !event.hard); - - if (o->up && !was_up) { - NCDModuleInst_Backend_Up(o->i); - } - else if (!o->up && was_up) { - NCDModuleInst_Backend_Down(o->i); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef type_arg; - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 2, &type_arg, &name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(type_arg) || !NCDVal_IsStringNoNulls(name_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate name - NCDValNullTermString name_nts; - if (!NCDVal_StringNullTerminate(name_arg, &name_nts)) { - ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - if (NCDVal_StringEquals(type_arg, "index")) { - if (sscanf(name_nts.data, "%"SCNu32, &o->index) != 1) { - ModuleLog(o->i, BLOG_ERROR, "wrong index argument"); - goto fail1; - } - } - else if (NCDVal_StringEquals(type_arg, "wlan")) { - if (!find_wlan_rfill(name_nts.data, &o->index)) { - ModuleLog(o->i, BLOG_ERROR, "failed to find rfkill for wlan interface"); - goto fail1; - } - } - else { - ModuleLog(o->i, BLOG_ERROR, "unknown type argument"); - goto fail1; - } - - // init monitor - if (!NCDRfkillMonitor_Init(&o->monitor, o->i->params->iparams->reactor, (NCDRfkillMonitor_handler)monitor_handler, o)) { - ModuleLog(o->i, BLOG_ERROR, "monitor failed"); - goto fail1; - } - - // set not up - o->up = 0; - - // free name nts - NCDValNullTermString_Free(&name_nts); - return; - -fail1: - NCDValNullTermString_Free(&name_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free monitor - NCDRfkillMonitor_Free(&o->monitor); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.backend.rfkill", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_backend_rfkill = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_backend_waitdevice.c b/external/badvpn_dns/ncd/modules/net_backend_waitdevice.c deleted file mode 100644 index 6ed99f6..0000000 --- a/external/badvpn_dns/ncd/modules/net_backend_waitdevice.c +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @file net_backend_waitdevice.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module which waits for the presence of a network interface. - * - * Synopsis: net.backend.waitdevice(string ifname) - * Description: statement is UP when a network interface named ifname - * exists, and DOWN when it does not. - */ - -#include <stdlib.h> -#include <string.h> -#include <regex.h> - -#include <misc/parse_number.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> - -#include <generated/blog_channel_ncd_net_backend_waitdevice.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define DEVPATH_REGEX "/net/[^/]+$" - -struct instance { - NCDModuleInst *i; - const char *ifname; - size_t ifname_len; - NCDUdevClient client; - regex_t reg; - char *devpath; - uintmax_t ifindex; -}; - -static void client_handler (struct instance *o, char *devpath, int have_map, BStringMap map) -{ - if (o->devpath && !strcmp(devpath, o->devpath) && !NCDUdevManager_Query(o->i->params->iparams->umanager, o->devpath)) { - // free devpath - free(o->devpath); - - // set no devpath - o->devpath = NULL; - - // signal down - NCDModuleInst_Backend_Down(o->i); - } else { - const BStringMap *cache_map = NCDUdevManager_Query(o->i->params->iparams->umanager, devpath); - if (!cache_map) { - goto out; - } - - int match_res = regexec(&o->reg, devpath, 0, NULL, 0); - const char *interface = BStringMap_Get(cache_map, "INTERFACE"); - const char *ifindex_str = BStringMap_Get(cache_map, "IFINDEX"); - - uintmax_t ifindex; - if (!(!match_res && interface && strlen(interface) == o->ifname_len && !memcmp(interface, o->ifname, o->ifname_len) && ifindex_str && parse_unsigned_integer(ifindex_str, &ifindex))) { - goto out; - } - - if (o->devpath && (strcmp(o->devpath, devpath) || o->ifindex != ifindex)) { - // free devpath - free(o->devpath); - - // set no devpath - o->devpath = NULL; - - // signal down - NCDModuleInst_Backend_Down(o->i); - } - - if (!o->devpath) { - // grab devpath - o->devpath = devpath; - devpath = NULL; - - // remember ifindex - o->ifindex = ifindex; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } - } - -out: - free(devpath); - if (have_map) { - BStringMap_Free(&map); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef arg; - if (!NCDVal_ListRead(params->args, 1, &arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->ifname = NCDVal_StringData(arg); - o->ifname_len = NCDVal_StringLength(arg); - - // init client - NCDUdevClient_Init(&o->client, o->i->params->iparams->umanager, o, (NCDUdevClient_handler)client_handler); - - // compile regex - if (regcomp(&o->reg, DEVPATH_REGEX, REG_EXTENDED)) { - ModuleLog(o->i, BLOG_ERROR, "regcomp failed"); - goto fail1; - } - - // set no devpath - o->devpath = NULL; - return; - -fail1: - NCDUdevClient_Free(&o->client); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free devpath - if (o->devpath) { - free(o->devpath); - } - - // free regex - regfree(&o->reg); - - // free client - NCDUdevClient_Free(&o->client); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.backend.waitdevice", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_backend_waitdevice = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_backend_waitlink.c b/external/badvpn_dns/ncd/modules/net_backend_waitlink.c deleted file mode 100644 index 4ea54e8..0000000 --- a/external/badvpn_dns/ncd/modules/net_backend_waitlink.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file net_backend_waitlink.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module which waits for the link on a network interface. - * - * Synopsis: net.backend.waitlink(string ifname) - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/get_iface_info.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> -#include <ncd/extra/NCDInterfaceMonitor.h> - -#include <generated/blog_channel_ncd_net_backend_waitlink.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDInterfaceMonitor monitor; - int up; -}; - -static void instance_free (struct instance *o, int is_error); - -static void monitor_handler (struct instance *o, struct NCDInterfaceMonitor_event event) -{ - ASSERT(event.event == NCDIFMONITOR_EVENT_LINK_UP || event.event == NCDIFMONITOR_EVENT_LINK_DOWN) - - int was_up = o->up; - o->up = (event.event == NCDIFMONITOR_EVENT_LINK_UP); - - if (o->up && !was_up) { - NCDModuleInst_Backend_Up(o->i); - } - else if (!o->up && was_up) { - NCDModuleInst_Backend_Down(o->i); - } -} - -static void monitor_handler_error (struct instance *o) -{ - ModuleLog(o->i, BLOG_ERROR, "monitor error"); - - instance_free(o, 1); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef ifname_arg; - if (!NCDVal_ListRead(params->args, 1, &ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate ifname - NCDValNullTermString ifname_nts; - if (!NCDVal_StringNullTerminate(ifname_arg, &ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // get interface index - int ifindex; - int res = badvpn_get_iface_info(ifname_nts.data, NULL, NULL, &ifindex); - NCDValNullTermString_Free(&ifname_nts); - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to get interface index"); - goto fail0; - } - - // init monitor - if (!NCDInterfaceMonitor_Init(&o->monitor, ifindex, NCDIFMONITOR_WATCH_LINK, i->params->iparams->reactor, o, (NCDInterfaceMonitor_handler)monitor_handler, (NCDInterfaceMonitor_handler_error)monitor_handler_error)) { - ModuleLog(o->i, BLOG_ERROR, "NCDInterfaceMonitor_Init failed"); - goto fail0; - } - - // set not up - o->up = 0; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o, int is_error) -{ - // free monitor - NCDInterfaceMonitor_Free(&o->monitor); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - instance_free(o, 0); -} - -static struct NCDModule modules[] = { - { - .type = "net.backend.waitlink", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_backend_waitlink = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_backend_wpa_supplicant.c b/external/badvpn_dns/ncd/modules/net_backend_wpa_supplicant.c deleted file mode 100644 index ce72198..0000000 --- a/external/badvpn_dns/ncd/modules/net_backend_wpa_supplicant.c +++ /dev/null @@ -1,573 +0,0 @@ -/** - * @file net_backend_wpa_supplicant.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Wireless interface module which runs wpa_supplicant to connect to a wireless network. - * - * Note: wpa_supplicant does not monitor the state of rfkill switches and will fail to - * start if the switch is of when it is started, and will stop working indefinitely if the - * switch is turned off while it is running. Therefore, you should put a "net.backend.rfkill" - * statement in front of the wpa_supplicant statement. - * - * Synopsis: net.backend.wpa_supplicant(string ifname, string conf, string exec, list(string) args) - * Variables: - * bssid - BSSID of the wireless network we connected to, or "none". - * Consists of 6 capital, two-character hexadecimal numbers, separated with colons. - * Example: "01:B2:C3:04:E5:F6" - * ssid - SSID of the wireless network we connected to. Note that this is after what - * wpa_supplicant does to it before it prints it. In particular, it replaces all bytes - * outside [32, 126] with underscores. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <inttypes.h> - -#include <misc/cmdline.h> -#include <misc/string_begins_with.h> -#include <misc/stdbuf_cmdline.h> -#include <misc/balloc.h> -#include <misc/find_program.h> -#include <flow/LineBuffer.h> -#include <system/BInputProcess.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_net_backend_wpa_supplicant.h> - -#define MAX_LINE_LEN 512 -#define EVENT_STRING_CONNECTED "CTRL-EVENT-CONNECTED" -#define EVENT_STRING_DISCONNECTED "CTRL-EVENT-DISCONNECTED" - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - const char *ifname; - size_t ifname_len; - const char *conf; - size_t conf_len; - const char *exec; - size_t exec_len; - NCDValRef args; - int dying; - int up; - BInputProcess process; - int have_pipe; - LineBuffer pipe_buffer; - PacketPassInterface pipe_input; - int have_info; - int info_have_bssid; - uint8_t info_bssid[6]; - char *info_ssid; -}; - -static int parse_hex_digit (uint8_t d, uint8_t *out); -static int parse_trying (uint8_t *data, int data_len, uint8_t *out_bssid, uint8_t **out_ssid, int *out_ssid_len); -static int parse_trying_nobssid (uint8_t *data, int data_len, uint8_t **out_ssid, int *out_ssid_len); -static int build_cmdline (struct instance *o, CmdLine *c); -static int init_info (struct instance *o, int have_bssid, const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len); -static void free_info (struct instance *o); -static void process_error (struct instance *o); -static void process_handler_terminated (struct instance *o, int normally, uint8_t normally_exit_status); -static void process_handler_closed (struct instance *o, int is_error); -static void process_pipe_handler_send (struct instance *o, uint8_t *data, int data_len); -static void instance_free (struct instance *o, int is_error); - -int parse_hex_digit (uint8_t d, uint8_t *out) -{ - switch (d) { - case '0': *out = 0; return 1; - case '1': *out = 1; return 1; - case '2': *out = 2; return 1; - case '3': *out = 3; return 1; - case '4': *out = 4; return 1; - case '5': *out = 5; return 1; - case '6': *out = 6; return 1; - case '7': *out = 7; return 1; - case '8': *out = 8; return 1; - case '9': *out = 9; return 1; - case 'A': case 'a': *out = 10; return 1; - case 'B': case 'b': *out = 11; return 1; - case 'C': case 'c': *out = 12; return 1; - case 'D': case 'd': *out = 13; return 1; - case 'E': case 'e': *out = 14; return 1; - case 'F': case 'f': *out = 15; return 1; - } - - return 0; -} - -int parse_trying (uint8_t *data, int data_len, uint8_t *out_bssid, uint8_t **out_ssid, int *out_ssid_len) -{ - // Trying to associate with AB:CD:EF:01:23:45 (SSID='Some SSID' freq=2462 MHz) - - int p; - if (!(p = data_begins_with((char *)data, data_len, "Trying to associate with "))) { - return 0; - } - data += p; - data_len -= p; - - for (int i = 0; i < 6; i++) { - uint8_t d1; - uint8_t d2; - if (data_len < 2 || !parse_hex_digit(data[0], &d1) || !parse_hex_digit(data[1], &d2)) { - return 0; - } - data += 2; - data_len -= 2; - out_bssid[i] = ((d1 << 4) | d2); - - if (i != 5) { - if (data_len < 1 || data[0] != ':') { - return 0; - } - data += 1; - data_len -= 1; - } - } - - if (!(p = data_begins_with((char *)data, data_len, " (SSID='"))) { - return 0; - } - data += p; - data_len -= p; - - // find last ' - uint8_t *q = NULL; - for (int i = data_len; i > 0; i--) { - if (data[i - 1] == ''') { - q = &data[i - 1]; - break; - } - } - if (!q) { - return 0; - } - - *out_ssid = data; - *out_ssid_len = q - data; - - return 1; -} - -int parse_trying_nobssid (uint8_t *data, int data_len, uint8_t **out_ssid, int *out_ssid_len) -{ - // Trying to associate with SSID 'Some SSID' - - int p; - if (!(p = data_begins_with((char *)data, data_len, "Trying to associate with SSID '"))) { - return 0; - } - data += p; - data_len -= p; - - // find last ' - uint8_t *q = NULL; - for (int i = data_len; i > 0; i--) { - if (data[i - 1] == ''') { - q = &data[i - 1]; - break; - } - } - if (!q) { - return 0; - } - - *out_ssid = data; - *out_ssid_len = q - data; - - return 1; -} - -int build_cmdline (struct instance *o, CmdLine *c) -{ - // init cmdline - if (!CmdLine_Init(c)) { - goto fail0; - } - - // find stdbuf executable - char *stdbuf_exec = badvpn_find_program("stdbuf"); - if (!stdbuf_exec) { - ModuleLog(o->i, BLOG_ERROR, "cannot find stdbuf executable"); - goto fail1; - } - - // append stdbuf part - int res = build_stdbuf_cmdline(c, stdbuf_exec, o->exec, o->exec_len); - free(stdbuf_exec); - if (!res) { - goto fail1; - } - - // append user arguments - size_t count = NCDVal_ListCount(o->args); - for (size_t j = 0; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(o->args, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - // append argument - if (!CmdLine_AppendNoNull(c, NCDVal_StringData(arg), NCDVal_StringLength(arg))) { - goto fail1; - } - } - - // append interface name - if (!CmdLine_Append(c, "-i") || !CmdLine_AppendNoNull(c, o->ifname, o->ifname_len)) { - goto fail1; - } - - // append config file - if (!CmdLine_Append(c, "-c") || !CmdLine_AppendNoNull(c, o->conf, o->conf_len)) { - goto fail1; - } - - // terminate cmdline - if (!CmdLine_Finish(c)) { - goto fail1; - } - - return 1; - -fail1: - CmdLine_Free(c); -fail0: - return 0; -} - -int init_info (struct instance *o, int have_bssid, const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len) -{ - ASSERT(!o->have_info) - - // set bssid - o->info_have_bssid = have_bssid; - if (have_bssid) { - memcpy(o->info_bssid, bssid, 6); - } - - // set ssid - if (!(o->info_ssid = BAllocSize(bsize_add(bsize_fromsize(ssid_len), bsize_fromsize(1))))) { - ModuleLog(o->i, BLOG_ERROR, "BAllocSize failed"); - return 0; - } - memcpy(o->info_ssid, ssid, ssid_len); - o->info_ssid[ssid_len] = '\0'; - - // set have info - o->have_info = 1; - - return 1; -} - -void free_info (struct instance *o) -{ - ASSERT(o->have_info) - - // free ssid - BFree(o->info_ssid); - - // set not have info - o->have_info = 0; -} - -void process_error (struct instance *o) -{ - BInputProcess_Terminate(&o->process); -} - -void process_handler_terminated (struct instance *o, int normally, uint8_t normally_exit_status) -{ - ModuleLog(o->i, (o->dying ? BLOG_INFO : BLOG_ERROR), "process terminated"); - - // die - instance_free(o, !o->dying); - return; -} - -void process_handler_closed (struct instance *o, int is_error) -{ - ASSERT(o->have_pipe) - - if (is_error) { - ModuleLog(o->i, BLOG_ERROR, "pipe error"); - } else { - ModuleLog(o->i, BLOG_INFO, "pipe closed"); - } - - // free buffer - LineBuffer_Free(&o->pipe_buffer); - - // free input interface - PacketPassInterface_Free(&o->pipe_input); - - // set have no pipe - o->have_pipe = 0; -} - -void process_pipe_handler_send (struct instance *o, uint8_t *data, int data_len) -{ - ASSERT(o->have_pipe) - ASSERT(data_len > 0) - - // accept packet - PacketPassInterface_Done(&o->pipe_input); - - if (o->dying) { - return; - } - - // strip "interface: " from beginning of line. Older wpa_supplicant versions (<1.0) don't add this - // prefix, so don't fail if there isn't one. - size_t l1; - size_t l2; - if (o->ifname_len > 0 && (l1 = data_begins_with_bin((char *)data, data_len, o->ifname, o->ifname_len)) && (l2 = data_begins_with((char *)data + l1, data_len - l1, ": "))) { - data += l1 + l2; - data_len -= l1 + l2; - } - - int have_bssid = 1; - uint8_t bssid[6]; - uint8_t *ssid; - int ssid_len; - if (parse_trying(data, data_len, bssid, &ssid, &ssid_len) || (have_bssid = 0, parse_trying_nobssid(data, data_len, &ssid, &ssid_len))) { - ModuleLog(o->i, BLOG_INFO, "trying event"); - - if (o->up) { - ModuleLog(o->i, BLOG_ERROR, "trying unexpected!"); - process_error(o); - return; - } - - if (o->have_info) { - free_info(o); - } - - if (!init_info(o, have_bssid, bssid, ssid, ssid_len)) { - ModuleLog(o->i, BLOG_ERROR, "init_info failed"); - process_error(o); - return; - } - } - else if (data_begins_with((char *)data, data_len, EVENT_STRING_CONNECTED)) { - ModuleLog(o->i, BLOG_INFO, "connected event"); - - if (o->up || !o->have_info) { - ModuleLog(o->i, BLOG_ERROR, "connected unexpected!"); - process_error(o); - return; - } - - o->up = 1; - NCDModuleInst_Backend_Up(o->i); - } - else if (data_begins_with((char *)data, data_len, EVENT_STRING_DISCONNECTED)) { - ModuleLog(o->i, BLOG_INFO, "disconnected event"); - - if (o->have_info) { - free_info(o); - } - - if (o->up) { - o->up = 0; - NCDModuleInst_Backend_Down(o->i); - } - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - NCDValRef conf_arg; - NCDValRef exec_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 4, &ifname_arg, &conf_arg, &exec_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsStringNoNulls(conf_arg) || - !NCDVal_IsStringNoNulls(exec_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->ifname = NCDVal_StringData(ifname_arg); - o->ifname_len = NCDVal_StringLength(ifname_arg); - o->conf = NCDVal_StringData(conf_arg); - o->conf_len = NCDVal_StringLength(conf_arg); - o->exec = NCDVal_StringData(exec_arg); - o->exec_len = NCDVal_StringLength(exec_arg); - o->args = args_arg; - - // set not dying - o->dying = 0; - - // set not up - o->up = 0; - - // build process cmdline - CmdLine c; - if (!build_cmdline(o, &c)) { - ModuleLog(o->i, BLOG_ERROR, "failed to build cmdline"); - goto fail0; - } - - // init process - if (!BInputProcess_Init(&o->process, o->i->params->iparams->reactor, o->i->params->iparams->manager, o, - (BInputProcess_handler_terminated)process_handler_terminated, - (BInputProcess_handler_closed)process_handler_closed - )) { - ModuleLog(o->i, BLOG_ERROR, "BInputProcess_Init failed"); - goto fail1; - } - - // init input interface - PacketPassInterface_Init(&o->pipe_input, MAX_LINE_LEN, (PacketPassInterface_handler_send)process_pipe_handler_send, o, BReactor_PendingGroup(o->i->params->iparams->reactor)); - - // init buffer - if (!LineBuffer_Init(&o->pipe_buffer, BInputProcess_GetInput(&o->process), &o->pipe_input, MAX_LINE_LEN, '\n')) { - ModuleLog(o->i, BLOG_ERROR, "LineBuffer_Init failed"); - goto fail2; - } - - // set have pipe - o->have_pipe = 1; - - // start process - if (!BInputProcess_Start(&o->process, ((char **)c.arr.v)[0], (char **)c.arr.v, NULL)) { - ModuleLog(o->i, BLOG_ERROR, "BInputProcess_Start failed"); - goto fail3; - } - - // set not have info - o->have_info = 0; - - CmdLine_Free(&c); - return; - -fail3: - LineBuffer_Free(&o->pipe_buffer); -fail2: - PacketPassInterface_Free(&o->pipe_input); - BInputProcess_Free(&o->process); -fail1: - CmdLine_Free(&c); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o, int is_error) -{ - // free info - if (o->have_info) { - free_info(o); - } - - if (o->have_pipe) { - // free buffer - LineBuffer_Free(&o->pipe_buffer); - - // free input interface - PacketPassInterface_Free(&o->pipe_input); - } - - // free process - BInputProcess_Free(&o->process); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // request termination - BInputProcess_Terminate(&o->process); - - // remember dying - o->dying = 1; -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->up) - ASSERT(o->have_info) - - if (!strcmp(name, "bssid")) { - char str[18]; - - if (!o->info_have_bssid) { - sprintf(str, "none"); - } else { - uint8_t *id = o->info_bssid; - sprintf(str, "%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8, id[0], id[1], id[2], id[3], id[4], id[5]); - } - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "ssid")) { - *out = NCDVal_NewString(mem, o->info_ssid); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "net.backend.wpa_supplicant", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_backend_wpa_supplicant = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_dns.c b/external/badvpn_dns/ncd/modules/net_dns.c deleted file mode 100644 index 9ecdf1c..0000000 --- a/external/badvpn_dns/ncd/modules/net_dns.c +++ /dev/null @@ -1,434 +0,0 @@ -/** - * @file net_dns.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DNS servers module. - * - * Synopsis: net.dns(list(string) servers, string priority) - * Synopsis: net.dns.resolvconf(list({string type, string value}) lines, string priority) - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <misc/offset.h> -#include <misc/bsort.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <misc/concat_strings.h> -#include <misc/expstring.h> -#include <misc/ipaddr.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_dns.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -struct instance { - NCDModuleInst *i; - LinkedList1 entries; - LinkedList1Node instances_node; // node in instances -}; - -struct dns_entry { - LinkedList1Node list_node; // node in instance.entries - char *line; - int priority; -}; - -struct global { - LinkedList1 instances; -}; - -static struct dns_entry * add_dns_entry (struct instance *o, const char *type, const char *value, int priority) -{ - // allocate entry - struct dns_entry *entry = malloc(sizeof(*entry)); - if (!entry) { - goto fail0; - } - - // generate line - entry->line = concat_strings(4, type, " ", value, "\n"); - if (!entry->line) { - goto fail1; - } - - // set info - entry->priority = priority; - - // add to list - LinkedList1_Append(&o->entries, &entry->list_node); - - return entry; - -fail1: - free(entry); -fail0: - return NULL; -} - -static void remove_dns_entry (struct instance *o, struct dns_entry *entry) -{ - // remove from list - LinkedList1_Remove(&o->entries, &entry->list_node); - - // free line - free(entry->line); - - // free entry - free(entry); -} - -static void remove_entries (struct instance *o) -{ - LinkedList1Node *n; - while (n = LinkedList1_GetFirst(&o->entries)) { - struct dns_entry *e = UPPER_OBJECT(n, struct dns_entry, list_node); - remove_dns_entry(o, e); - } -} - -static size_t count_entries (struct global *g) -{ - size_t c = 0; - - for (LinkedList1Node *n = LinkedList1_GetFirst(&g->instances); n; n = LinkedList1Node_Next(n)) { - struct instance *o = UPPER_OBJECT(n, struct instance, instances_node); - for (LinkedList1Node *en = LinkedList1_GetFirst(&o->entries); en; en = LinkedList1Node_Next(en)) { - c++; - } - } - - return c; -} - -struct dns_sort_entry { - char *line; - int priority; -}; - -static int dns_sort_comparator (const void *v1, const void *v2) -{ - const struct dns_sort_entry *e1 = v1; - const struct dns_sort_entry *e2 = v2; - return B_COMPARE(e1->priority, e2->priority); -} - -static int set_servers (struct global *g) -{ - int ret = 0; - - // count servers - size_t num_entries = count_entries(g); - - // allocate sort array - struct dns_sort_entry *sort_entries = BAllocArray(num_entries, sizeof(sort_entries[0])); - if (!sort_entries) { - goto fail0; - } - - // fill sort array - num_entries = 0; - for (LinkedList1Node *n = LinkedList1_GetFirst(&g->instances); n; n = LinkedList1Node_Next(n)) { - struct instance *o = UPPER_OBJECT(n, struct instance, instances_node); - for (LinkedList1Node *en = LinkedList1_GetFirst(&o->entries); en; en = LinkedList1Node_Next(en)) { - struct dns_entry *e = UPPER_OBJECT(en, struct dns_entry, list_node); - sort_entries[num_entries].line = e->line; - sort_entries[num_entries].priority= e->priority; - num_entries++; - } - } - - // sort by priority - // use a custom insertion sort instead of qsort() because we want a stable sort - struct dns_sort_entry temp; - BInsertionSort(sort_entries, num_entries, sizeof(sort_entries[0]), dns_sort_comparator, &temp); - - ExpString estr; - if (!ExpString_Init(&estr)) { - goto fail1; - } - - for (size_t i = 0; i < num_entries; i++) { - if (!ExpString_Append(&estr, sort_entries[i].line)) { - goto fail2; - } - } - - // set servers - if (!NCDIfConfig_set_resolv_conf(ExpString_Get(&estr), ExpString_Length(&estr))) { - goto fail2; - } - - ret = 1; - -fail2: - ExpString_Free(&estr); -fail1: - BFree(sort_entries); -fail0: - return ret; -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - // allocate global state structure - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - // set group state pointer - group->group_state = g; - - // init instances list - LinkedList1_Init(&g->instances); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - ASSERT(LinkedList1_IsEmpty(&g->instances)) - - // free global state structure - BFree(g); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct instance *o = vo; - o->i = i; - - // init servers list - LinkedList1_Init(&o->entries); - - // get arguments - NCDValRef servers_arg; - NCDValRef priority_arg; - if (!NCDVal_ListRead(params->args, 2, &servers_arg, &priority_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail1; - } - if (!NCDVal_IsList(servers_arg) || !NCDVal_IsString(priority_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - uintmax_t priority; - if (!ncd_read_uintmax(priority_arg, &priority) || priority > INT_MAX) { - ModuleLog(o->i, BLOG_ERROR, "wrong priority"); - goto fail1; - } - - // read servers - size_t count = NCDVal_ListCount(servers_arg); - for (size_t j = 0; j < count; j++) { - NCDValRef server_arg = NCDVal_ListGet(servers_arg, j); - - if (!NCDVal_IsString(server_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - uint32_t addr; - if (!ipaddr_parse_ipv4_addr_bin((char *)NCDVal_StringData(server_arg), NCDVal_StringLength(server_arg), &addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong addr"); - goto fail1; - } - - char addr_str[IPADDR_PRINT_MAX]; - ipaddr_print_addr(addr, addr_str); - - if (!add_dns_entry(o, "nameserver", addr_str, priority)) { - ModuleLog(o->i, BLOG_ERROR, "failed to add dns entry"); - goto fail1; - } - } - - // add to instances - LinkedList1_Append(&g->instances, &o->instances_node); - - // set servers - if (!set_servers(g)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers"); - goto fail2; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail2: - LinkedList1_Remove(&g->instances, &o->instances_node); -fail1: - remove_entries(o); - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_resolvconf (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct instance *o = vo; - o->i = i; - - // init servers list - LinkedList1_Init(&o->entries); - - // get arguments - NCDValRef lines_arg; - NCDValRef priority_arg; - if (!NCDVal_ListRead(params->args, 2, &lines_arg, &priority_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail1; - } - if (!NCDVal_IsList(lines_arg) || !NCDVal_IsString(priority_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - uintmax_t priority; - if (!ncd_read_uintmax(priority_arg, &priority) || priority > INT_MAX) { - ModuleLog(o->i, BLOG_ERROR, "wrong priority"); - goto fail1; - } - - // read lines - size_t count = NCDVal_ListCount(lines_arg); - for (size_t j = 0; j < count; j++) { - int loop_failed = 1; - - NCDValRef line = NCDVal_ListGet(lines_arg, j); - if (!NCDVal_IsList(line) || NCDVal_ListCount(line) != 2) { - ModuleLog(o->i, BLOG_ERROR, "lines element is not a list with two elements"); - goto loop_fail0; - } - - NCDValRef type = NCDVal_ListGet(line, 0); - NCDValRef value = NCDVal_ListGet(line, 1); - if (!NCDVal_IsStringNoNulls(type) || !NCDVal_IsStringNoNulls(value)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type of type or value"); - goto loop_fail0; - } - - NCDValNullTermString type_nts; - if (!NCDVal_StringNullTerminate(type, &type_nts)) { - ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto loop_fail0; - } - - NCDValNullTermString value_nts; - if (!NCDVal_StringNullTerminate(value, &value_nts)) { - ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto loop_fail1; - } - - if (!add_dns_entry(o, type_nts.data, value_nts.data, priority)) { - ModuleLog(o->i, BLOG_ERROR, "failed to add dns entry"); - goto loop_fail2; - } - - loop_failed = 0; - loop_fail2: - NCDValNullTermString_Free(&value_nts); - loop_fail1: - NCDValNullTermString_Free(&type_nts); - loop_fail0: - if (loop_failed) { - goto fail1; - } - } - - // add to instances - LinkedList1_Append(&g->instances, &o->instances_node); - - // set servers - if (!set_servers(g)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers"); - goto fail2; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail2: - LinkedList1_Remove(&g->instances, &o->instances_node); -fail1: - remove_entries(o); - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - struct global *g = ModuleGlobal(o->i); - - // remove from instances - LinkedList1_Remove(&g->instances, &o->instances_node); - - // set servers - set_servers(g); - - // free servers - remove_entries(o); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.dns", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.dns.resolvconf", - .func_new2 = func_new_resolvconf, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_dns = { - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree, - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_iptables.c b/external/badvpn_dns/ncd/modules/net_iptables.c deleted file mode 100644 index a5af2ee..0000000 --- a/external/badvpn_dns/ncd/modules/net_iptables.c +++ /dev/null @@ -1,749 +0,0 @@ -/** - * @file net_iptables.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * iptables and ebtables module. - * - * Note that all iptables/ebtables commands (in general) must be issued synchronously, or - * the kernel may randomly report errors if there is another iptables/ebtables command in - * progress. To solve this, the NCD process contains a single "iptables lock". All - * iptables/ebtables commands exposed here go through that lock. - * In case you wish to call iptables/ebtables directly, the lock is exposed via - * net.iptables.lock(). - * - * The append and insert commands, instead of using the variable-argument form below - * as documented below, may alternatively be called with a single list argument. - * - * Synopsis: - * net.iptables.append(string table, string chain, string arg1 ...) - * Description: - * init: iptables -t table -A chain arg1 ... - * deinit: iptables -t table -D chain arg1 ... - * - * Synopsis: - * net.iptables.insert(string table, string chain, string arg1 ...) - * Description: - * init: iptables -t table -I chain arg1 ... - * deinit: iptables -t table -D chain arg1 ... - * - * Synopsis: - * net.iptables.policy(string table, string chain, string target, string revert_target) - * Description: - * init: iptables -t table -P chain target - * deinit: iptables -t table -P chain revert_target - * - * Synopsis: - * net.iptables.newchain(string table, string chain) - * net.iptables.newchain(string chain) // DEPRECATED, defaults to table="filter" - * Description: - * init: iptables -t table -N chain - * deinit: iptables -t table -X chain - * - * Synopsis: - * net.ebtables.append(string table, string chain, string arg1 ...) - * Description: - * init: ebtables -t table -A chain arg1 ... - * deinit: ebtables -t table -D chain arg1 ... - * - * Synopsis: - * net.ebtables.insert(string table, string chain, string arg1 ...) - * Description: - * init: ebtables -t table -I chain arg1 ... - * deinit: ebtables -t table -D chain arg1 ... - * - * Synopsis: - * net.ebtables.policy(string table, string chain, string target, string revert_target) - * Description: - * init: ebtables -t table -P chain target - * deinit: ebtables -t table -P chain revert_target - * - * Synopsis: - * net.ebtables.newchain(string table, string chain) - * Description: - * init: ebtables -t table -N chain - * deinit: ebtables -t table -X chain - * - * Synopsis: - * net.iptables.lock() - * Description: - * Use at the beginning of a block of custom iptables/ebtables commands to make sure - * they do not interfere with other iptables/ebtables commands. - * WARNING: improper usage of the lock can lead to deadlock. In particular: - * - Do not call any of the iptables/ebtables wrappers above from a lock section; - * those will attempt to aquire the lock themselves. - * - Do not enter another lock section from a lock section. - * - Do not perform any potentially long wait from a lock section. - * - * Synopsis: - * net.iptables.lock::unlock() - * Description: - * Use at the end of a block of custom iptables/ebtables commands to make sure - * they do not interfere with other iptables/ebtables commands. - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <misc/debug.h> -#include <misc/find_program.h> -#include <misc/balloc.h> -#include <ncd/extra/BEventLock.h> - -#include <ncd/modules/command_template.h> - -#include <generated/blog_channel_ncd_net_iptables.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleGlobal(i) ((i)->m->group->group_state) - -static void template_free_func (void *vo, int is_error); - -struct global { - BEventLock iptables_lock; -}; - -struct instance { - NCDModuleInst *i; - command_template_instance cti; -}; - -struct unlock_instance; - -#define LOCK_STATE_LOCKING 1 -#define LOCK_STATE_LOCKED 2 -#define LOCK_STATE_UNLOCKED 3 -#define LOCK_STATE_RELOCKING 4 - -struct lock_instance { - NCDModuleInst *i; - BEventLockJob lock_job; - struct unlock_instance *unlock; - int state; -}; - -struct unlock_instance { - NCDModuleInst *i; - struct lock_instance *lock; -}; - -static void unlock_free (struct unlock_instance *o); - -static int build_append_or_insert_cmdline (NCDModuleInst *i, NCDValRef args, const char *prog, int remove, char **exec, CmdLine *cl, const char *type) -{ - if (NCDVal_ListRead(args, 1, &args) && !NCDVal_IsList(args)) { - ModuleLog(i, BLOG_ERROR, "in one-argument form a list is expected"); - goto fail0; - } - - // read arguments - NCDValRef table_arg; - NCDValRef chain_arg; - if (!NCDVal_ListReadHead(args, 2, &table_arg, &chain_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(table_arg) || !NCDVal_IsStringNoNulls(chain_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - const char *table = NCDVal_StringData(table_arg); - size_t table_len = NCDVal_StringLength(table_arg); - const char *chain = NCDVal_StringData(chain_arg); - size_t chain_len = NCDVal_StringLength(chain_arg); - - // find program - if (!(*exec = badvpn_find_program(prog))) { - ModuleLog(i, BLOG_ERROR, "failed to find program: %s", prog); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add header - if (!CmdLine_Append(cl, *exec) || !CmdLine_Append(cl, "-t") || !CmdLine_AppendNoNull(cl, table, table_len) || !CmdLine_Append(cl, (remove ? "-D" : type)) || !CmdLine_AppendNoNull(cl, chain, chain_len)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // add additional arguments - size_t count = NCDVal_ListCount(args); - for (size_t j = 2; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(args, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail2; - } - - if (!CmdLine_AppendNoNull(cl, NCDVal_StringData(arg), NCDVal_StringLength(arg))) { - ModuleLog(i, BLOG_ERROR, "CmdLine_AppendNoNull failed"); - goto fail2; - } - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static int build_append_cmdline (NCDModuleInst *i, NCDValRef args, const char *prog, int remove, char **exec, CmdLine *cl) -{ - return build_append_or_insert_cmdline(i, args, prog, remove, exec, cl, "-A"); -} - -static int build_insert_cmdline (NCDModuleInst *i, NCDValRef args, const char *prog, int remove, char **exec, CmdLine *cl) -{ - return build_append_or_insert_cmdline(i, args, prog, remove, exec, cl, "-I"); -} - -static int build_policy_cmdline (NCDModuleInst *i, NCDValRef args, const char *prog, int remove, char **exec, CmdLine *cl) -{ - // read arguments - NCDValRef table_arg; - NCDValRef chain_arg; - NCDValRef target_arg; - NCDValRef revert_target_arg; - if (!NCDVal_ListRead(args, 4, &table_arg, &chain_arg, &target_arg, &revert_target_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(table_arg) || !NCDVal_IsStringNoNulls(chain_arg) || - !NCDVal_IsStringNoNulls(target_arg) || !NCDVal_IsStringNoNulls(revert_target_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - const char *table = NCDVal_StringData(table_arg); - size_t table_len = NCDVal_StringLength(table_arg); - const char *chain = NCDVal_StringData(chain_arg); - size_t chain_len = NCDVal_StringLength(chain_arg); - const char *target = NCDVal_StringData(target_arg); - size_t target_len = NCDVal_StringLength(target_arg); - const char *revert_target = NCDVal_StringData(revert_target_arg); - size_t revert_target_len = NCDVal_StringLength(revert_target_arg); - - // find program - if (!(*exec = badvpn_find_program(prog))) { - ModuleLog(i, BLOG_ERROR, "failed to find program: %s", prog); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add arguments - if (!CmdLine_Append(cl, *exec) || !CmdLine_Append(cl, "-t") || !CmdLine_AppendNoNull(cl, table, table_len) || - !CmdLine_Append(cl, "-P") || !CmdLine_AppendNoNull(cl, chain, chain_len) || - !CmdLine_AppendNoNull(cl, (remove ? revert_target : target), (remove ? revert_target_len : target_len)) - ) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static int build_newchain_cmdline (NCDModuleInst *i, NCDValRef args, const char *prog, int remove, char **exec, CmdLine *cl) -{ - // read arguments - NCDValRef table_arg = NCDVal_NewInvalid(); - NCDValRef chain_arg; - if (!NCDVal_ListRead(args, 1, &chain_arg) && !NCDVal_ListRead(args, 2, &table_arg, &chain_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if ((!NCDVal_IsInvalid(table_arg) && !NCDVal_IsStringNoNulls(table_arg)) || !NCDVal_IsStringNoNulls(chain_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - const char *table = (NCDVal_IsInvalid(table_arg) ? "filter" : NCDVal_StringData(table_arg)); - size_t table_len = (NCDVal_IsInvalid(table_arg) ? 6 : NCDVal_StringLength(table_arg)); - const char *chain = NCDVal_StringData(chain_arg); - size_t chain_len = NCDVal_StringLength(chain_arg); - - // find program - if (!(*exec = badvpn_find_program(prog))) { - ModuleLog(i, BLOG_ERROR, "failed to find program: %s", prog); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add arguments - if (!CmdLine_AppendMulti(cl, 2, *exec, "-t") || - !CmdLine_AppendNoNull(cl, table, table_len) || - !CmdLine_Append(cl, (remove ? "-X" : "-N")) || - !CmdLine_AppendNoNull(cl, chain, chain_len) - ) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static int build_iptables_append_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_append_cmdline(i, args, "iptables", remove, exec, cl); -} - -static int build_iptables_insert_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_insert_cmdline(i, args, "iptables", remove, exec, cl); -} - -static int build_iptables_policy_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_policy_cmdline(i, args, "iptables", remove, exec, cl); -} - -static int build_iptables_newchain_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_newchain_cmdline(i, args, "iptables", remove, exec, cl); -} - -static int build_ip6tables_append_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_append_cmdline(i, args, "ip6tables", remove, exec, cl); -} - -static int build_ip6tables_insert_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_insert_cmdline(i, args, "ip6tables", remove, exec, cl); -} - -static int build_ip6tables_policy_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_policy_cmdline(i, args, "ip6tables", remove, exec, cl); -} - -static int build_ip6tables_newchain_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_newchain_cmdline(i, args, "ip6tables", remove, exec, cl); -} - -static int build_ebtables_append_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_append_cmdline(i, args, "ebtables", remove, exec, cl); -} - -static int build_ebtables_insert_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_insert_cmdline(i, args, "ebtables", remove, exec, cl); -} - -static int build_ebtables_policy_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_policy_cmdline(i, args, "ebtables", remove, exec, cl); -} - -static int build_ebtables_newchain_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - return build_newchain_cmdline(i, args, "ebtables", remove, exec, cl); -} - -static void lock_job_handler (struct lock_instance *o) -{ - ASSERT(o->state == LOCK_STATE_LOCKING || o->state == LOCK_STATE_RELOCKING) - - if (o->state == LOCK_STATE_LOCKING) { - ASSERT(!o->unlock) - - // up - NCDModuleInst_Backend_Up(o->i); - - // set state locked - o->state = LOCK_STATE_LOCKED; - } - else if (o->state == LOCK_STATE_RELOCKING) { - ASSERT(o->unlock) - ASSERT(o->unlock->lock == o) - - // die unlock - unlock_free(o->unlock); - o->unlock = NULL; - - // set state locked - o->state = LOCK_STATE_LOCKED; - } -} - -static int func_globalinit (struct NCDInterpModuleGroup *group, const struct NCDModuleInst_iparams *params) -{ - // allocate global state structure - struct global *g = BAlloc(sizeof(*g)); - if (!g) { - BLog(BLOG_ERROR, "BAlloc failed"); - return 0; - } - - // set group state pointer - group->group_state = g; - - // init iptables lock - BEventLock_Init(&g->iptables_lock, BReactor_PendingGroup(params->reactor)); - - return 1; -} - -static void func_globalfree (struct NCDInterpModuleGroup *group) -{ - struct global *g = group->group_state; - - // free iptables lock - BEventLock_Free(&g->iptables_lock); - - // free global state structure - BFree(g); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, command_template_build_cmdline build_cmdline) -{ - struct global *g = ModuleGlobal(i); - struct instance *o = vo; - o->i = i; - - command_template_new(&o->cti, i, params, build_cmdline, template_free_func, o, BLOG_CURRENT_CHANNEL, &g->iptables_lock); -} - -void template_free_func (void *vo, int is_error) -{ - struct instance *o = vo; - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void append_iptables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_iptables_append_cmdline); -} - -static void insert_iptables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_iptables_insert_cmdline); -} - -static void policy_iptables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_iptables_policy_cmdline); -} - -static void newchain_iptables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_iptables_newchain_cmdline); -} - -static void append_ip6tables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ip6tables_append_cmdline); -} - -static void insert_ip6tables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ip6tables_insert_cmdline); -} - -static void policy_ip6tables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ip6tables_policy_cmdline); -} - -static void newchain_ip6tables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ip6tables_newchain_cmdline); -} - -static void append_ebtables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ebtables_append_cmdline); -} - -static void insert_ebtables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ebtables_insert_cmdline); -} - -static void policy_ebtables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ebtables_policy_cmdline); -} - -static void newchain_ebtables_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new(vo, i, params, build_ebtables_newchain_cmdline); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - command_template_die(&o->cti); -} - -static void lock_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct global *g = ModuleGlobal(i); - struct lock_instance *o = vo; - o->i = i; - - // init lock job - BEventLockJob_Init(&o->lock_job, &g->iptables_lock, (BEventLock_handler)lock_job_handler, o); - BEventLockJob_Wait(&o->lock_job); - - // set no unlock - o->unlock = NULL; - - // set state locking - o->state = LOCK_STATE_LOCKING; -} - -static void lock_func_die (void *vo) -{ - struct lock_instance *o = vo; - - if (o->state == LOCK_STATE_UNLOCKED) { - ASSERT(o->unlock) - ASSERT(o->unlock->lock == o) - o->unlock->lock = NULL; - } - else if (o->state == LOCK_STATE_RELOCKING) { - ASSERT(o->unlock) - ASSERT(o->unlock->lock == o) - unlock_free(o->unlock); - } - else { - ASSERT(!o->unlock) - } - - // free lock job - BEventLockJob_Free(&o->lock_job); - - // dead - NCDModuleInst_Backend_Dead(o->i); -} - -static void unlock_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct unlock_instance *o = vo; - o->i = i; - - // get lock lock - struct lock_instance *lock = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure lock doesn't already have an unlock - if (lock->unlock) { - BLog(BLOG_ERROR, "lock already has an unlock"); - goto fail0; - } - - // make sure lock is locked - if (lock->state != LOCK_STATE_LOCKED) { - BLog(BLOG_ERROR, "lock is not locked"); - goto fail0; - } - - // set lock - o->lock = lock; - - // set unlock in lock - lock->unlock = o; - - // up - NCDModuleInst_Backend_Up(o->i); - - // release lock - BEventLockJob_Release(&lock->lock_job); - - // set lock state unlocked - lock->state = LOCK_STATE_UNLOCKED; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void unlock_func_die (void *vo) -{ - struct unlock_instance *o = vo; - - // if lock is gone, die right away - if (!o->lock) { - unlock_free(o); - return; - } - - ASSERT(o->lock->unlock == o) - ASSERT(o->lock->state == LOCK_STATE_UNLOCKED) - - // wait lock - BEventLockJob_Wait(&o->lock->lock_job); - - // set lock state relocking - o->lock->state = LOCK_STATE_RELOCKING; -} - -static void unlock_free (struct unlock_instance *o) -{ - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.iptables.append", - .func_new2 = append_iptables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.iptables.insert", - .func_new2 = insert_iptables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.iptables.policy", - .func_new2 = policy_iptables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.iptables.newchain", - .func_new2 = newchain_iptables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ip6tables.append", - .func_new2 = append_ip6tables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ip6tables.insert", - .func_new2 = insert_ip6tables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ip6tables.policy", - .func_new2 = policy_ip6tables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ip6tables.newchain", - .func_new2 = newchain_ip6tables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ebtables.append", - .func_new2 = append_ebtables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ebtables.insert", - .func_new2 = insert_ebtables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ebtables.policy", - .func_new2 = policy_ebtables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ebtables.newchain", - .func_new2 = newchain_ebtables_func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.iptables.lock", - .func_new2 = lock_func_new, - .func_die = lock_func_die, - .alloc_size = sizeof(struct lock_instance) - }, { - .type = "net.iptables.lock::unlock", - .func_new2 = unlock_func_new, - .func_die = unlock_func_die, - .alloc_size = sizeof(struct unlock_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_iptables = { - .modules = modules, - .func_globalinit = func_globalinit, - .func_globalfree = func_globalfree -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv4_addr.c b/external/badvpn_dns/ncd/modules/net_ipv4_addr.c deleted file mode 100644 index 14eaea4..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv4_addr.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file net_ipv4_addr.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IPv4 address module. - * - * Synopsis: - * net.ipv4.addr(string ifname, string addr, string prefix) - * net.ipv4.addr(string ifname, string cidr_addr) - * - * Description: - * Adds the given address to the given network interface on initialization, - * and removes it on deinitialization. The second form takes the address and - * prefix in CIDR notation (a.b.c.d/n). - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> - -#include <generated/blog_channel_ncd_net_ipv4_addr.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValNullTermString ifname_nts; - struct ipv4_ifaddr ifaddr; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - NCDValRef addr_arg; - NCDValRef prefix_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &ifname_arg, &addr_arg) && - !NCDVal_ListRead(params->args, 3, &ifname_arg, &addr_arg, &prefix_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsString(addr_arg) || - (!NCDVal_IsInvalid(prefix_arg) && !NCDVal_IsString(prefix_arg)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - if (NCDVal_IsInvalid(prefix_arg)) { - if (!ipaddr_parse_ipv4_ifaddr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation address"); - goto fail1; - } - } else { - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr.addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong address"); - goto fail1; - } - - if (!ipaddr_parse_ipv4_prefix_bin(NCDVal_StringData(prefix_arg), NCDVal_StringLength(prefix_arg), &o->ifaddr.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "wrong prefix"); - goto fail1; - } - } - - // add address - if (!NCDIfConfig_add_ipv4_addr(o->ifname_nts.data, o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "failed to add IP address"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // remove address - if (!NCDIfConfig_remove_ipv4_addr(o->ifname_nts.data, o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove IP address"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv4.addr", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv4_addr = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv4_addr_in_network.c b/external/badvpn_dns/ncd/modules/net_ipv4_addr_in_network.c deleted file mode 100644 index fa63811..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv4_addr_in_network.c +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file net_ipv4_addr_in_network.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * net.ipv4.addr_in_network(string addr, string net_addr, string net_prefix) - * net.ipv4.addr_in_network(string addr, string cidr_net_addr) - * net.ipv4.ifnot_addr_in_network(string addr, string net_addr, string net_prefix) - * net.ipv4.ifnot_addr_in_network(string addr, string cidr_net_addr) - * - * Description: - * Checks if two IPv4 addresses belong to the same subnet. - * The prefix length is given either in the a separate argument or along with - * the second address in CIDR notation (address/prefix). - * This can be used to check whether an address belongs to a certain - * subnet, hence the name. - * - * Variables: - * (empty) - "true" if addresses belong to the same subnet, "false" if not - */ - -#include <string.h> - -#include <misc/ipaddr.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_ipv4_addr_in_network.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - int value; -}; - -static void func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_ifnot) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef arg_addr; - NCDValRef arg_net_addr; - NCDValRef arg_net_prefix = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &arg_addr, &arg_net_addr) && - !NCDVal_ListRead(params->args, 3, &arg_addr, &arg_net_addr, &arg_net_prefix) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_addr) || !NCDVal_IsString(arg_net_addr) || - (!NCDVal_IsInvalid(arg_net_prefix) && !NCDVal_IsString(arg_net_prefix)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse addr - uint32_t addr; - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(arg_addr), NCDVal_StringLength(arg_addr), &addr)) { - ModuleLog(o->i, BLOG_ERROR, "bad address"); - goto fail0; - } - - // parse network - struct ipv4_ifaddr network; - if (NCDVal_IsInvalid(arg_net_prefix)) { - if (!ipaddr_parse_ipv4_ifaddr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network)) { - ModuleLog(o->i, BLOG_ERROR, "bad network in CIDR notation"); - goto fail0; - } - } else { - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network.addr)) { - ModuleLog(o->i, BLOG_ERROR, "bad network address"); - goto fail0; - } - if (!ipaddr_parse_ipv4_prefix_bin(NCDVal_StringData(arg_net_prefix), NCDVal_StringLength(arg_net_prefix), &network.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "bad network prefix"); - goto fail0; - } - } - - // test - o->value = ipaddr_ipv4_addrs_in_network(addr, network.addr, network.prefix); - - if (is_ifnot && o->value) { - ModuleLog(o->i, BLOG_ERROR, "addresses belong to same subnet, not proceeding"); - } - - // signal up - if (!is_ifnot || !o->value) { - NCDModuleInst_Backend_Up(o->i); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_normal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(vo, i, params, 0); -} - -static void func_new_ifnot (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(vo, i, params, 1); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (!strcmp(name, "")) { - *out = ncd_make_boolean(mem, o->value, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv4.addr_in_network", - .func_new2 = func_new_normal, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "ip_in_network", // compatibility name - .func_new2 = func_new_normal, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ipv4.ifnot_addr_in_network", - .func_new2 = func_new_ifnot, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv4_addr_in_network = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv4_arp_probe.c b/external/badvpn_dns/ncd/modules/net_ipv4_arp_probe.c deleted file mode 100644 index 6f8e45e..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv4_arp_probe.c +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @file net_ipv4_arp_probe.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * ARP probing module. - * - * Synopsis: - * net.ipv4.arp_probe(string ifname, string addr) - * - * Description: - * Monitors local presence of an IPv4 host on a network interface. - * On initialization, may take some time to determine whether - * the host is present or not, then goes to UP state. When it - * determines that presence has changed, toggles itself DOWN then - * UP to expose the new determination. - * - * Variables: - * exists - "true" if the host exists, "false" if not - */ - -#include <stdlib.h> - -#include <misc/ipaddr.h> -#include <arpprobe/BArpProbe.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_ipv4_arp_probe.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_UNKNOWN 1 -#define STATE_EXIST 2 -#define STATE_NOEXIST 3 - -struct instance { - NCDModuleInst *i; - BArpProbe arpprobe; - int state; -}; - -static void instance_free (struct instance *o, int is_error); - -static void arpprobe_handler (struct instance *o, int event) -{ - switch (event) { - case BARPPROBE_EVENT_EXIST: { - ASSERT(o->state == STATE_UNKNOWN || o->state == STATE_NOEXIST) - - ModuleLog(o->i, BLOG_INFO, "exist"); - - if (o->state == STATE_NOEXIST) { - // signal down - NCDModuleInst_Backend_Down(o->i); - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state exist - o->state = STATE_EXIST; - } break; - - case BARPPROBE_EVENT_NOEXIST: { - ASSERT(o->state == STATE_UNKNOWN || o->state == STATE_EXIST) - - ModuleLog(o->i, BLOG_INFO, "noexist"); - - if (o->state == STATE_EXIST) { - // signal down - NCDModuleInst_Backend_Down(o->i); - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state noexist - o->state = STATE_NOEXIST; - } break; - - case BARPPROBE_EVENT_ERROR: { - ModuleLog(o->i, BLOG_ERROR, "error"); - - // die - instance_free(o, 1); - return; - } break; - - default: ASSERT(0); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef arg_ifname; - NCDValRef arg_addr; - if (!NCDVal_ListRead(params->args, 2, &arg_ifname, &arg_addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(arg_ifname) || !NCDVal_IsString(arg_addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse address - uint32_t addr; - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(arg_addr), NCDVal_StringLength(arg_addr), &addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong address"); - goto fail0; - } - - // null terminate ifname - NCDValNullTermString ifname_nts; - if (!NCDVal_StringNullTerminate(arg_ifname, &ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // init arpprobe - int res = BArpProbe_Init(&o->arpprobe, ifname_nts.data, addr, i->params->iparams->reactor, o, (BArpProbe_handler)arpprobe_handler); - NCDValNullTermString_Free(&ifname_nts); - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "BArpProbe_Init failed"); - goto fail0; - } - - // set state unknown - o->state = STATE_UNKNOWN; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o, int is_error) -{ - // free arpprobe - BArpProbe_Free(&o->arpprobe); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - instance_free(o, 0); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->state == STATE_EXIST || o->state == STATE_NOEXIST) - - if (!strcmp(name, "exists")) { - *out = ncd_make_boolean(mem, o->state == STATE_EXIST, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv4.arp_probe", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv4_arp_probe = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv4_dhcp.c b/external/badvpn_dns/ncd/modules/net_ipv4_dhcp.c deleted file mode 100644 index d9e8b74..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv4_dhcp.c +++ /dev/null @@ -1,351 +0,0 @@ -/** - * @file net_ipv4_dhcp.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DHCP client module. - * - * Synopsis: - * net.ipv4.dhcp(string ifname [, list opts]) - * - * Description: - * Runs a DHCP client on a network interface. When an address is obtained, - * transitions up (but does not assign anything). If the lease times out, - * transitions down. - * The interface must already be up. - * Supported options (in the opts argument): - * - "hostname", (string value): send this hostname to the DHCP server - * - "vendorclassid", (string value): send this vendor class identifier - * - "auto_clientid": send a client identifier generated from the MAC address - * - * Variables: - * string addr - assigned IP address ("A.B.C.D") - * string prefix - address prefix length ("N") - * string cidr_addr - address and prefix in CIDR notation ("A.B.C.D/N") - * string gateway - router address ("A.B.C.D"), or "none" if not provided - * list(string) dns_servers - DNS server addresses ("A.B.C.D" ...) - * string server_mac - MAC address of the DHCP server (6 two-digit caps hexadecimal values - * separated with colons, e.g."AB:CD:EF:01:02:03") - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <misc/ipaddr.h> -#include <dhcpclient/BDHCPClient.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_net_ipv4_dhcp.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - BDHCPClient dhcp; - int up; -}; - -static void instance_free (struct instance *o, int is_error); - -static void dhcp_handler (struct instance *o, int event) -{ - switch (event) { - case BDHCPCLIENT_EVENT_UP: { - ASSERT(!o->up) - o->up = 1; - NCDModuleInst_Backend_Up(o->i); - } break; - - case BDHCPCLIENT_EVENT_DOWN: { - ASSERT(o->up) - o->up = 0; - NCDModuleInst_Backend_Down(o->i); - } break; - - case BDHCPCLIENT_EVENT_ERROR: { - instance_free(o, 1); - return; - } break; - - default: ASSERT(0); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef ifname_arg; - NCDValRef opts_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &ifname_arg) && !NCDVal_ListRead(params->args, 2, &ifname_arg, &opts_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg) || (!NCDVal_IsInvalid(opts_arg) && !NCDVal_IsList(opts_arg))) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - NCDValNullTermString hostname_nts = NCDValNullTermString_NewDummy(); - NCDValNullTermString vendorclassid_nts = NCDValNullTermString_NewDummy(); - - struct BDHCPClient_opts opts = {}; - - // read options - size_t count = NCDVal_IsInvalid(opts_arg) ? 0 : NCDVal_ListCount(opts_arg); - for (size_t j = 0; j < count; j++) { - NCDValRef opt = NCDVal_ListGet(opts_arg, j); - - // read name - if (!NCDVal_IsString(opt)) { - ModuleLog(o->i, BLOG_ERROR, "wrong option name type"); - goto fail1; - } - - if (NCDVal_StringEquals(opt, "hostname") || NCDVal_StringEquals(opt, "vendorclassid")) { - int is_hostname = NCDVal_StringEquals(opt, "hostname"); - - // read value - if (j == count) { - ModuleLog(o->i, BLOG_ERROR, "option value missing"); - goto fail1; - } - NCDValRef val = NCDVal_ListGet(opts_arg, j + 1); - if (!NCDVal_IsStringNoNulls(val)) { - ModuleLog(o->i, BLOG_ERROR, "wrong option value type"); - goto fail1; - } - - // null terminate - NCDValNullTermString nts; - if (!NCDVal_StringNullTerminate(val, &nts)) { - ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail1; - } - NCDValNullTermString *nts_ptr = (is_hostname ? &hostname_nts : &vendorclassid_nts); - NCDValNullTermString_Free(nts_ptr); - *nts_ptr = nts; - - if (is_hostname) { - opts.hostname = nts.data; - } else { - opts.vendorclassid = nts.data; - } - - j++; - } - else if (NCDVal_StringEquals(opt, "auto_clientid")) { - opts.auto_clientid = 1; - } - else { - ModuleLog(o->i, BLOG_ERROR, "unknown option name"); - goto fail1; - } - } - - // null terminate ifname - NCDValNullTermString ifname_nts; - if (!NCDVal_StringNullTerminate(ifname_arg, &ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail1; - } - - // init DHCP - int res = BDHCPClient_Init(&o->dhcp, ifname_nts.data, opts, o->i->params->iparams->reactor, o->i->params->iparams->random2, (BDHCPClient_handler)dhcp_handler, o); - NCDValNullTermString_Free(&ifname_nts); - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "BDHCPClient_Init failed"); - goto fail1; - } - - // set not up - o->up = 0; - - // free options nts's - NCDValNullTermString_Free(&hostname_nts); - NCDValNullTermString_Free(&vendorclassid_nts); - return; - -fail1: - NCDValNullTermString_Free(&hostname_nts); - NCDValNullTermString_Free(&vendorclassid_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o, int is_error) -{ - // free DHCP - BDHCPClient_Free(&o->dhcp); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - instance_free(o, 0); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->up) - - if (!strcmp(name, "addr")) { - uint32_t addr; - BDHCPClient_GetClientIP(&o->dhcp, &addr); - - char str[IPADDR_PRINT_MAX]; - ipaddr_print_addr(addr, str); - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "prefix")) { - uint32_t addr; - BDHCPClient_GetClientIP(&o->dhcp, &addr); - uint32_t mask; - BDHCPClient_GetClientMask(&o->dhcp, &mask); - - struct ipv4_ifaddr ifaddr; - if (!ipaddr_ipv4_ifaddr_from_addr_mask(addr, mask, &ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "bad netmask"); - return 0; - } - - char str[10]; - sprintf(str, "%d", ifaddr.prefix); - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "cidr_addr")) { - uint32_t addr; - BDHCPClient_GetClientIP(&o->dhcp, &addr); - uint32_t mask; - BDHCPClient_GetClientMask(&o->dhcp, &mask); - - struct ipv4_ifaddr ifaddr; - if (!ipaddr_ipv4_ifaddr_from_addr_mask(addr, mask, &ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "bad netmask"); - return 0; - } - - char str[IPADDR_PRINT_MAX]; - ipaddr_print_ifaddr(ifaddr, str); - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "gateway")) { - char str[IPADDR_PRINT_MAX]; - - uint32_t addr; - if (!BDHCPClient_GetRouter(&o->dhcp, &addr)) { - strcpy(str, "none"); - } else { - ipaddr_print_addr(addr, str); - } - - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "dns_servers")) { - uint32_t servers[BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS]; - int num_servers = BDHCPClient_GetDNS(&o->dhcp, servers, BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS); - - *out = NCDVal_NewList(mem, num_servers); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - - for (int i = 0; i < num_servers; i++) { - char str[IPADDR_PRINT_MAX]; - ipaddr_print_addr(servers[i], str); - - NCDValRef server = NCDVal_NewString(mem, str); - if (NCDVal_IsInvalid(server)) { - goto fail; - } - - if (!NCDVal_ListAppend(*out, server)) { - goto fail; - } - } - - return 1; - } - - if (!strcmp(name, "server_mac")) { - uint8_t mac[6]; - BDHCPClient_GetServerMAC(&o->dhcp, mac); - - char str[18]; - sprintf(str, "%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8":%02"PRIX8, - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - *out = NCDVal_NewString(mem, str); - return 1; - } - - return 0; - -fail: - *out = NCDVal_NewInvalid(); - return 1; -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv4.dhcp", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv4_dhcp = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv4_route.c b/external/badvpn_dns/ncd/modules/net_ipv4_route.c deleted file mode 100644 index 0f34388..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv4_route.c +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @file net_ipv4_route.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IPv4 route module. - * - * Synopsis: - * net.ipv4.route(string dest, string dest_prefix, string gateway, string metric, string ifname) - * net.ipv4.route(string cidr_dest, string gateway, string metric, string ifname) - * - * Description: - * Adds an IPv4 route to the system's routing table on initiailzation, and - * removes it on deinitialization. The second form takes the destination in - * CIDR notation (a.b.c.d/n). - * If 'gateway' is "none", the route will only be associated with an interface. - * If 'gateway' is "blackhole", the route will be a blackhole route (and 'ifname' is unused). - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_ipv4_route.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define TYPE_NORMAL 1 -#define TYPE_IFONLY 2 -#define TYPE_BLACKHOLE 3 - -struct instance { - NCDModuleInst *i; - struct ipv4_ifaddr dest; - int type; - uint32_t gateway; - int metric; - NCDValNullTermString ifname_nts; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef dest_arg; - NCDValRef dest_prefix_arg = NCDVal_NewInvalid(); - NCDValRef gateway_arg; - NCDValRef metric_arg; - NCDValRef ifname_arg; - if (!NCDVal_ListRead(params->args, 4, &dest_arg, &gateway_arg, &metric_arg, &ifname_arg) && - !NCDVal_ListRead(params->args, 5, &dest_arg, &dest_prefix_arg, &gateway_arg, &metric_arg, &ifname_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(dest_arg) || !NCDVal_IsString(gateway_arg) || - !NCDVal_IsString(metric_arg) || !NCDVal_IsStringNoNulls(ifname_arg) || - (!NCDVal_IsInvalid(dest_prefix_arg) && !NCDVal_IsString(dest_prefix_arg)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // read dest - if (NCDVal_IsInvalid(dest_prefix_arg)) { - if (!ipaddr_parse_ipv4_ifaddr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest)) { - ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation dest"); - goto fail0; - } - } else { - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest.addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong dest addr"); - goto fail0; - } - if (!ipaddr_parse_ipv4_prefix_bin(NCDVal_StringData(dest_prefix_arg), NCDVal_StringLength(dest_prefix_arg), &o->dest.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "wrong dest prefix"); - goto fail0; - } - } - - // read gateway and choose type - if (NCDVal_StringEquals(gateway_arg, "none")) { - o->type = TYPE_IFONLY; - } - else if (NCDVal_StringEquals(gateway_arg, "blackhole")) { - o->type = TYPE_BLACKHOLE; - } else { - if (!ipaddr_parse_ipv4_addr_bin(NCDVal_StringData(gateway_arg), NCDVal_StringLength(gateway_arg), &o->gateway)) { - ModuleLog(o->i, BLOG_ERROR, "wrong gateway"); - goto fail0; - } - o->type = TYPE_NORMAL; - } - - // read metric - uintmax_t metric; - if (!ncd_read_uintmax(metric_arg, &metric) || metric > INT_MAX) { - ModuleLog(i, BLOG_ERROR, "bad metric"); - goto fail0; - } - o->metric = metric; - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // add route - int res = 0; // to remove warning - switch (o->type) { - case TYPE_NORMAL: - res = NCDIfConfig_add_ipv4_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); - break; - case TYPE_IFONLY: - res = NCDIfConfig_add_ipv4_route(o->dest, NULL, o->metric, o->ifname_nts.data); - break; - case TYPE_BLACKHOLE: - res = NCDIfConfig_add_ipv4_blackhole_route(o->dest, o->metric); - break; - default: ASSERT(0); - } - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to add route"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // remove route - int res = 0; // to remove warning - switch (o->type) { - case TYPE_NORMAL: - res = NCDIfConfig_remove_ipv4_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); - break; - case TYPE_IFONLY: - res = NCDIfConfig_remove_ipv4_route(o->dest, NULL, o->metric, o->ifname_nts.data); - break; - case TYPE_BLACKHOLE: - res = NCDIfConfig_remove_ipv4_blackhole_route(o->dest, o->metric); - break; - default: ASSERT(0); - } - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove route"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv4.route", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv4_route = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv6_addr.c b/external/badvpn_dns/ncd/modules/net_ipv6_addr.c deleted file mode 100644 index debee66..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv6_addr.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file net_ipv6_addr.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IPv6 address module. - * - * Synopsis: - * net.ipv6.addr(string ifname, string addr, string prefix) - * net.ipv6.addr(string ifname, string cidr_addr) - * - * Description: - * Adds the given address to the given network interface on initialization, - * and removes it on deinitialization. The second form takes the address and - * prefix in CIDR notation (a.b.c.d/n). - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> - -#include <generated/blog_channel_ncd_net_ipv6_addr.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValNullTermString ifname_nts; - struct ipv6_ifaddr ifaddr; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - NCDValRef addr_arg; - NCDValRef prefix_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &ifname_arg, &addr_arg) && - !NCDVal_ListRead(params->args, 3, &ifname_arg, &addr_arg, &prefix_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsString(addr_arg) || - (!NCDVal_IsInvalid(prefix_arg) && !NCDVal_IsString(prefix_arg)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - if (NCDVal_IsInvalid(prefix_arg)) { - if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation address"); - goto fail1; - } - } else { - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr.addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong address"); - goto fail1; - } - - if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(prefix_arg), NCDVal_StringLength(prefix_arg), &o->ifaddr.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "wrong prefix"); - goto fail1; - } - } - - // add address - if (!NCDIfConfig_add_ipv6_addr(o->ifname_nts.data, o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "failed to add IP address"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // remove address - if (!NCDIfConfig_remove_ipv6_addr(o->ifname_nts.data, o->ifaddr)) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove IP address"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv6.addr", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv6_addr = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv6_addr_in_network.c b/external/badvpn_dns/ncd/modules/net_ipv6_addr_in_network.c deleted file mode 100644 index 1ae9677..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv6_addr_in_network.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * @file net_ipv6_addr_in_network.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * net.ipv6.addr_in_network(string addr, string net_addr, string net_prefix) - * net.ipv6.addr_in_network(string addr, string cidr_net_addr) - * net.ipv6.ifnot_addr_in_network(string addr, string net_addr, string net_prefix) - * net.ipv6.ifnot_addr_in_network(string addr, string cidr_net_addr) - * - * Description: - * Checks if two IPv6 addresses belong to the same subnet. - * The prefix length is given either in the a separate argument or along with - * the second address in CIDR notation (address/prefix). - * This can be used to check whether an address belongs to a certain - * subnet, hence the name. - * - * Variables: - * (empty) - "true" if addresses belong to the same subnet, "false" if not - */ - -#include <string.h> - -#include <misc/ipaddr6.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_ipv6_addr_in_network.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - int value; -}; - -static void func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_ifnot) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef arg_addr; - NCDValRef arg_net_addr; - NCDValRef arg_net_prefix = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &arg_addr, &arg_net_addr) && - !NCDVal_ListRead(params->args, 3, &arg_addr, &arg_net_addr, &arg_net_prefix) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_addr) || !NCDVal_IsString(arg_net_addr) || - (!NCDVal_IsInvalid(arg_net_prefix) && !NCDVal_IsString(arg_net_prefix)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse addr - struct ipv6_addr addr; - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(arg_addr), NCDVal_StringLength(arg_addr), &addr)) { - ModuleLog(o->i, BLOG_ERROR, "bad address"); - goto fail0; - } - - // parse network - struct ipv6_ifaddr network; - if (NCDVal_IsInvalid(arg_net_prefix)) { - if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network)) { - ModuleLog(o->i, BLOG_ERROR, "bad network in CIDR notation"); - goto fail0; - } - } else { - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network.addr)) { - ModuleLog(o->i, BLOG_ERROR, "bad network address"); - goto fail0; - } - if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(arg_net_prefix), NCDVal_StringLength(arg_net_prefix), &network.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "bad network prefix"); - goto fail0; - } - } - - // test - o->value = ipaddr6_ipv6_addrs_in_network(addr, network.addr, network.prefix); - - if (is_ifnot && o->value) { - ModuleLog(o->i, BLOG_ERROR, "addresses belong to same subnet, not proceeding"); - } - - // signal up - if (!is_ifnot || !o->value) { - NCDModuleInst_Backend_Up(o->i); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_normal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(vo, i, params, 0); -} - -static void func_new_ifnot (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_common(vo, i, params, 1); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (!strcmp(name, "")) { - *out = ncd_make_boolean(mem, o->value, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv6.addr_in_network", - .func_new2 = func_new_normal, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.ipv6.ifnot_addr_in_network", - .func_new2 = func_new_ifnot, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv6_addr_in_network = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv6_route.c b/external/badvpn_dns/ncd/modules/net_ipv6_route.c deleted file mode 100644 index 2f4ed0b..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv6_route.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file net_ipv6_route.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * IPv6 route module. - * - * Synopsis: - * net.ipv6.route(string dest, string dest_prefix, string gateway, string metric, string ifname) - * net.ipv6.route(string cidr_dest, string gateway, string metric, string ifname) - * - * Description: - * Adds an IPv6 route to the system's routing table on initiailzation, and - * removes it on deinitialization. The second form takes the destination in - * CIDR notation (address/prefix). - * If 'gateway' is "none", the route will only be associated with an interface. - * If 'gateway' is "blackhole", the route will be a blackhole route (and 'ifname' is unused). - * NOTE: blackhole routes for IPv6 are not yet implemented in Linux; - * adding them via this interface will only work once they - * have been. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_net_ipv6_route.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define TYPE_NORMAL 1 -#define TYPE_IFONLY 2 -#define TYPE_BLACKHOLE 3 - -struct instance { - NCDModuleInst *i; - struct ipv6_ifaddr dest; - int type; - struct ipv6_addr gateway; - int metric; - NCDValNullTermString ifname_nts; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef dest_arg; - NCDValRef dest_prefix_arg = NCDVal_NewInvalid(); - NCDValRef gateway_arg; - NCDValRef metric_arg; - NCDValRef ifname_arg; - if (!NCDVal_ListRead(params->args, 4, &dest_arg, &gateway_arg, &metric_arg, &ifname_arg) && - !NCDVal_ListRead(params->args, 5, &dest_arg, &dest_prefix_arg, &gateway_arg, &metric_arg, &ifname_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(dest_arg) || !NCDVal_IsString(gateway_arg) || - !NCDVal_IsString(metric_arg) || !NCDVal_IsStringNoNulls(ifname_arg) || - (!NCDVal_IsInvalid(dest_prefix_arg) && !NCDVal_IsString(dest_prefix_arg)) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // read dest - if (NCDVal_IsInvalid(dest_prefix_arg)) { - if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest)) { - ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation dest"); - goto fail0; - } - } else { - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest.addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong dest addr"); - goto fail0; - } - if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(dest_prefix_arg), NCDVal_StringLength(dest_prefix_arg), &o->dest.prefix)) { - ModuleLog(o->i, BLOG_ERROR, "wrong dest prefix"); - goto fail0; - } - } - - // read gateway and choose type - if (NCDVal_StringEquals(gateway_arg, "none")) { - o->type = TYPE_IFONLY; - } - else if (NCDVal_StringEquals(gateway_arg, "blackhole")) { - o->type = TYPE_BLACKHOLE; - } else { - if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(gateway_arg), NCDVal_StringLength(gateway_arg), &o->gateway)) { - ModuleLog(o->i, BLOG_ERROR, "wrong gateway"); - goto fail0; - } - o->type = TYPE_NORMAL; - } - - // read metric - uintmax_t metric; - if (!ncd_read_uintmax(metric_arg, &metric) || metric > INT_MAX) { - ModuleLog(i, BLOG_ERROR, "bad metric"); - goto fail0; - } - o->metric = metric; - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // add route - int res = 0; // to remove warning - switch (o->type) { - case TYPE_NORMAL: - res = NCDIfConfig_add_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); - break; - case TYPE_IFONLY: - res = NCDIfConfig_add_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data); - break; - case TYPE_BLACKHOLE: - res = NCDIfConfig_add_ipv6_blackhole_route(o->dest, o->metric); - break; - default: ASSERT(0); - } - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to add route"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // remove route - int res = 0; // to remove warning - switch (o->type) { - case TYPE_NORMAL: - res = NCDIfConfig_remove_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); - break; - case TYPE_IFONLY: - res = NCDIfConfig_remove_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data); - break; - case TYPE_BLACKHOLE: - res = NCDIfConfig_remove_ipv6_blackhole_route(o->dest, o->metric); - break; - default: ASSERT(0); - } - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to remove route"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv6.route", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv6_route = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_ipv6_wait_dynamic_addr.c b/external/badvpn_dns/ncd/modules/net_ipv6_wait_dynamic_addr.c deleted file mode 100644 index f0404d5..0000000 --- a/external/badvpn_dns/ncd/modules/net_ipv6_wait_dynamic_addr.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file net_ipv6_wait_dynamic_addr.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * net.ipv6.wait_dynamic_addr(string ifname) - * - * Description: - * Waits for a dynamic IPv6 address to be obtained on the interface, - * and goes up when it is obtained. - * If the address is subsequently lost, goes back down and again waits - * for an address. - * - * Variables: - * string addr - dynamic address obtained on the interface - * string prefix - prefix length - * string cidr_addr - address and prefix (addr/prefix) - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <misc/get_iface_info.h> -#include <misc/ipaddr6.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDInterfaceMonitor.h> - -#include <generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDInterfaceMonitor monitor; - struct ipv6_ifaddr ifaddr; - int up; -}; - -static void instance_free (struct instance *o, int is_error); - -static void monitor_handler (struct instance *o, struct NCDInterfaceMonitor_event event) -{ - if (!o->up && event.event == NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED && (event.u.ipv6_addr.addr_flags & NCDIFMONITOR_ADDR_FLAG_DYNAMIC)) { - // rememeber address, set up - o->ifaddr = event.u.ipv6_addr.addr; - o->up = 1; - - // signal up - NCDModuleInst_Backend_Up(o->i); - } - else if (o->up && event.event == NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED && !memcmp(event.u.ipv6_addr.addr.addr.bytes, o->ifaddr.addr.bytes, 16) && event.u.ipv6_addr.addr.prefix == o->ifaddr.prefix) { - // set not up - o->up = 0; - - // signal down - NCDModuleInst_Backend_Down(o->i); - } -} - -static void monitor_handler_error (struct instance *o) -{ - ModuleLog(o->i, BLOG_ERROR, "monitor error"); - - instance_free(o, 1); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - if (!NCDVal_ListRead(params->args, 1, &ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate ifname - NCDValNullTermString ifname_nts; - if (!NCDVal_StringNullTerminate(ifname_arg, &ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // get interface index - int ifindex; - int res = badvpn_get_iface_info(ifname_nts.data, NULL, NULL, &ifindex); - NCDValNullTermString_Free(&ifname_nts); - if (!res) { - ModuleLog(o->i, BLOG_ERROR, "failed to get interface index"); - goto fail0; - } - - // init monitor - if (!NCDInterfaceMonitor_Init(&o->monitor, ifindex, NCDIFMONITOR_WATCH_IPV6_ADDR, i->params->iparams->reactor, o, (NCDInterfaceMonitor_handler)monitor_handler, (NCDInterfaceMonitor_handler_error)monitor_handler_error)) { - ModuleLog(o->i, BLOG_ERROR, "NCDInterfaceMonitor_Init failed"); - goto fail0; - } - - // set not up - o->up = 0; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o, int is_error) -{ - // free monitor - NCDInterfaceMonitor_Free(&o->monitor); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - instance_free(o, 0); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->up) - - if (!strcmp(name, "addr")) { - char str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(o->ifaddr.addr, str); - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "prefix")) { - char str[10]; - sprintf(str, "%d", o->ifaddr.prefix); - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (!strcmp(name, "cidr_addr")) { - char str[IPADDR6_PRINT_MAX]; - ipaddr6_print_ifaddr(o->ifaddr, str); - *out = NCDVal_NewString(mem, str); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "net.ipv6.wait_dynamic_addr", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_ipv6_wait_dynamic_addr = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_up.c b/external/badvpn_dns/ncd/modules/net_up.c deleted file mode 100644 index 3aa04ce..0000000 --- a/external/badvpn_dns/ncd/modules/net_up.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file net_up.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Network interface up and down module. - * - * Synopsis: net.up(string ifname) - * Description: Sets a network interface up on initialization and down on - * deinitialization. - */ - -#include <stdlib.h> - -#include <ncd/NCDModule.h> -#include <ncd/extra/NCDIfConfig.h> - -#include <generated/blog_channel_ncd_net_up.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValNullTermString ifname_nts; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef ifname_arg; - if (!NCDVal_ListRead(params->args, 1, &ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(ifname_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate ifname - if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // set interface up - if (!NCDIfConfig_set_up(o->ifname_nts.data)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set interface up"); - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - - return; - -fail1: - NCDValNullTermString_Free(&o->ifname_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // set interface down - if (!NCDIfConfig_set_down(o->ifname_nts.data)) { - ModuleLog(o->i, BLOG_ERROR, "failed to set interface down"); - } - - // free ifname nts - NCDValNullTermString_Free(&o->ifname_nts); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "net.up", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_up = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/net_watch_interfaces.c b/external/badvpn_dns/ncd/modules/net_watch_interfaces.c deleted file mode 100644 index 7bd7b70..0000000 --- a/external/badvpn_dns/ncd/modules/net_watch_interfaces.c +++ /dev/null @@ -1,474 +0,0 @@ -/** - * @file net_watch_interfaces.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Network interface watcher. - * - * Synopsis: net.watch_interfaces() - * Description: reports network interface events. Transitions up when an event is detected, and - * goes down waiting for the next event when net.watch_interfaces::nextevent() is called. - * On startup, "added" events are reported for existing interfaces. - * Variables: - * string event_type - what happened with the interface: "added" or "removed". This may not be - * consistent across events. - * string devname - interface name - * string bus - bus location, for example "pci:0000:06:00.0", "usb:2-1.3:1.0", or "unknown" - * - * Synopsis: net.watch_interfaces::nextevent() - * Description: makes the watch_interfaces module transition down in order to report the next event. - */ - -#include <stdlib.h> -#include <string.h> -#include <regex.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/parse_number.h> -#include <misc/bsize.h> -#include <structure/LinkedList1.h> -#include <udevmonitor/NCDUdevManager.h> -#include <ncd/NCDModule.h> -#include <ncd/modules/event_template.h> - -#include <generated/blog_channel_ncd_net_watch_interfaces.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define DEVPATH_REGEX "/net/[^/]+$" -#define DEVPATH_USB_REGEX "/usb[^/]*(/[^/]+)+/([^/]+)/net/[^/]+$" -#define DEVPATH_PCI_REGEX "/pci[^/]*/[^/]+/([^/]+)/net/[^/]+$" - -struct device { - char *ifname; - char *devpath; - uintmax_t ifindex; - BStringMap removed_map; - LinkedList1Node devices_list_node; -}; - -struct instance { - NCDModuleInst *i; - NCDUdevClient client; - LinkedList1 devices_list; - regex_t reg; - regex_t usb_reg; - regex_t pci_reg; - event_template templ; -}; - -static void templ_func_free (struct instance *o, int is_error); - -static struct device * find_device_by_ifname (struct instance *o, const char *ifname) -{ - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); - while (list_node) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->ifname, ifname)) { - return device; - } - list_node = LinkedList1Node_Next(list_node); - } - - return NULL; -} - -static struct device * find_device_by_devpath (struct instance *o, const char *devpath) -{ - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); - while (list_node) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->devpath, devpath)) { - return device; - } - list_node = LinkedList1Node_Next(list_node); - } - - return NULL; -} - -static void free_device (struct instance *o, struct device *device, int have_removed_map) -{ - // remove from devices list - LinkedList1_Remove(&o->devices_list, &device->devices_list_node); - - // free removed map - if (have_removed_map) { - BStringMap_Free(&device->removed_map); - } - - // free devpath - free(device->devpath); - - // free ifname - free(device->ifname); - - // free structure - free(device); -} - -static int make_event_map (struct instance *o, int added, const char *ifname, const char *bus, BStringMap *out_map) -{ - // init map - BStringMap map; - BStringMap_Init(&map); - - // set type - if (!BStringMap_Set(&map, "event_type", (added ? "added" : "removed"))) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set ifname - if (!BStringMap_Set(&map, "devname", ifname)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set bus - if (!BStringMap_Set(&map, "bus", bus)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - *out_map = map; - return 1; - -fail1: - BStringMap_Free(&map); - return 0; -} - -static void queue_event (struct instance *o, BStringMap map) -{ - // pass event to template - int was_empty; - event_template_queue(&o->templ, map, &was_empty); - - // if event queue was empty, stop receiving udev events - if (was_empty) { - NCDUdevClient_Pause(&o->client); - } -} - -static void add_device (struct instance *o, const char *ifname, const char *devpath, uintmax_t ifindex, const char *bus) -{ - ASSERT(!find_device_by_ifname(o, ifname)) - ASSERT(!find_device_by_devpath(o, devpath)) - - // allocate structure - struct device *device = malloc(sizeof(*device)); - if (!device) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init ifname - if (!(device->ifname = strdup(ifname))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail1; - } - - // init devpath - if (!(device->devpath = strdup(devpath))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail2; - } - - // set ifindex - device->ifindex = ifindex; - - // init removed map - if (!make_event_map(o, 0, ifname, bus, &device->removed_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail3; - } - - // init added map - BStringMap added_map; - if (!make_event_map(o, 1, ifname, bus, &added_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail4; - } - - // insert to devices list - LinkedList1_Append(&o->devices_list, &device->devices_list_node); - - // queue event - queue_event(o, added_map); - - return; - -fail4: - BStringMap_Free(&device->removed_map); -fail3: - free(device->devpath); -fail2: - free(device->ifname); -fail1: - free(device); -fail0: - ModuleLog(o->i, BLOG_ERROR, "failed to add device %s", ifname); -} - -static void remove_device (struct instance *o, struct device *device) -{ - queue_event(o, device->removed_map); - free_device(o, device, 0); -} - -static void next_event (struct instance *o) -{ - ASSERT(event_template_is_enabled(&o->templ)) - - // order template to finish the current event - int is_empty; - event_template_dequeue(&o->templ, &is_empty); - - // if template has no events, continue udev events - if (is_empty) { - NCDUdevClient_Continue(&o->client); - } -} - -static void make_bus (struct instance *o, const char *devpath, const BStringMap *map, char *out_bus, size_t bus_avail) -{ - regmatch_t pmatch[3]; - - const char *type; - const char *id; - size_t id_len; - - if (!regexec(&o->usb_reg, devpath, 3, pmatch, 0)) { - type = "usb"; - id = devpath + pmatch[2].rm_so; - id_len = pmatch[2].rm_eo - pmatch[2].rm_so; - } - else if (!regexec(&o->pci_reg, devpath, 3, pmatch, 0)) { - type = "pci"; - id = devpath + pmatch[1].rm_so; - id_len = pmatch[1].rm_eo - pmatch[1].rm_so; - } else { - goto fail; - } - - size_t type_len = strlen(type); - bsize_t bus_len = bsize_add(bsize_fromsize(type_len), bsize_add(bsize_fromint(1), bsize_add(bsize_fromsize(id_len), bsize_fromint(1)))); - if (bus_len.is_overflow || bus_len.value > bus_avail) { - goto fail; - } - - memcpy(out_bus, type, type_len); - out_bus[type_len] = ':'; - memcpy(out_bus + type_len + 1, id, id_len); - out_bus[type_len + 1 + id_len] = '\0'; - return; - -fail: - snprintf(out_bus, bus_avail, "%s", "unknown"); -} - -static void client_handler (struct instance *o, char *devpath, int have_map, BStringMap map) -{ - // lookup existing device with this devpath - struct device *ex_device = find_device_by_devpath(o, devpath); - // lookup cache entry - const BStringMap *cache_map = NCDUdevManager_Query(o->i->params->iparams->umanager, devpath); - - if (!cache_map) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - int match_res = regexec(&o->reg, devpath, 0, NULL, 0); - const char *interface = BStringMap_Get(cache_map, "INTERFACE"); - const char *ifindex_str = BStringMap_Get(cache_map, "IFINDEX"); - - uintmax_t ifindex; - if (!(!match_res && interface && ifindex_str && parse_unsigned_integer(ifindex_str, &ifindex))) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - if (ex_device && (strcmp(ex_device->ifname, interface) || ex_device->ifindex != ifindex)) { - remove_device(o, ex_device); - ex_device = NULL; - } - - if (!ex_device) { - struct device *ex_ifname_device = find_device_by_ifname(o, interface); - if (ex_ifname_device) { - remove_device(o, ex_ifname_device); - } - - char bus[128]; - make_bus(o, devpath, cache_map, bus, sizeof(bus)); - - add_device(o, interface, devpath, ifindex, bus); - } - -out: - free(devpath); - if (have_map) { - BStringMap_Free(&map); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init client - NCDUdevClient_Init(&o->client, o->i->params->iparams->umanager, o, (NCDUdevClient_handler)client_handler); - - // init devices list - LinkedList1_Init(&o->devices_list); - - // compile regex's - if (regcomp(&o->reg, DEVPATH_REGEX, REG_EXTENDED)) { - ModuleLog(o->i, BLOG_ERROR, "regcomp failed"); - goto fail1; - } - if (regcomp(&o->usb_reg, DEVPATH_USB_REGEX, REG_EXTENDED)) { - ModuleLog(o->i, BLOG_ERROR, "regcomp failed"); - goto fail2; - } - if (regcomp(&o->pci_reg, DEVPATH_PCI_REGEX, REG_EXTENDED)) { - ModuleLog(o->i, BLOG_ERROR, "regcomp failed"); - goto fail3; - } - - event_template_new(&o->templ, o->i, BLOG_CURRENT_CHANNEL, 3, o, (event_template_func_free)templ_func_free); - return; - -fail3: - regfree(&o->usb_reg); -fail2: - regfree(&o->reg); -fail1: - NCDUdevClient_Free(&o->client); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void templ_func_free (struct instance *o, int is_error) -{ - // free devices - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&o->devices_list)) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - free_device(o, device, 1); - } - - // free regex's - regfree(&o->pci_reg); - regfree(&o->usb_reg); - regfree(&o->reg); - - // free client - NCDUdevClient_Free(&o->client); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - event_template_die(&o->templ); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - return event_template_getvar(&o->templ, name, mem, out); -} - -static void nextevent_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure we are currently reporting an event - if (!event_template_is_enabled(&mo->templ)) { - ModuleLog(i, BLOG_ERROR, "not reporting an event"); - goto fail0; - } - - // signal up. - // Do it before finishing the event so our process does not advance any further if - // we would be killed the event provider going down. - NCDModuleInst_Backend_Up(i); - - // wait for next event - next_event(mo); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "net.watch_interfaces", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "net.watch_interfaces::nextevent", - .func_new2 = nextevent_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_net_watch_interfaces = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/netmask.c b/external/badvpn_dns/ncd/modules/netmask.c deleted file mode 100644 index 53d9398..0000000 --- a/external/badvpn_dns/ncd/modules/netmask.c +++ /dev/null @@ -1,263 +0,0 @@ -/** - * @file netmask.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * ipv4_prefix_to_mask(string prefix) - * - * Variables: - * string (empty) - prefix, converted to dotted decimal format without leading - * zeros - * - * Synopsis: - * ipv4_mask_to_prefix(string mask) - * - * Variables: - * string (empty) - mask, converted to prefix length - * - * Synopsis: - * ipv4_net_from_addr_and_prefix(string addr, string prefix) - * - * Variables: - * string (empty) - network part of the address, according to given prefix - * length, in dotted decimal format without leading zeros - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <inttypes.h> - -#include <misc/ipaddr.h> -#include <misc/parse_number.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_netmask.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct addr_instance { - NCDModuleInst *i; - uint32_t addr; -}; - -struct prefix_instance { - NCDModuleInst *i; - int prefix; -}; - -static void addr_func_init_templ (void *vo, NCDModuleInst *i, uint32_t addr) -{ - struct addr_instance *o = vo; - o->i = i; - - // remember address - o->addr = addr; - - // signal up - NCDModuleInst_Backend_Up(i); -} - -static void prefix_to_mask_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef prefix_arg; - if (!NCDVal_ListRead(params->args, 1, &prefix_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(prefix_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse prefix - int prefix; - if (!ipaddr_parse_ipv4_prefix_bin((char *)NCDVal_StringData(prefix_arg), NCDVal_StringLength(prefix_arg), &prefix)) { - ModuleLog(i, BLOG_ERROR, "bad prefix"); - goto fail0; - } - - // make mask - uint32_t mask = ipaddr_ipv4_mask_from_prefix(prefix); - - addr_func_init_templ(vo, i, mask); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void ipv4_net_from_addr_and_prefix_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef addr_arg; - NCDValRef prefix_arg; - if (!NCDVal_ListRead(params->args, 2, &addr_arg, &prefix_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(addr_arg) || !NCDVal_IsString(prefix_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse addr - uint32_t addr; - if (!ipaddr_parse_ipv4_addr_bin((char *)NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &addr)) { - ModuleLog(i, BLOG_ERROR, "bad addr"); - goto fail0; - } - - // parse prefix - int prefix; - if (!ipaddr_parse_ipv4_prefix_bin((char *)NCDVal_StringData(prefix_arg), NCDVal_StringLength(prefix_arg), &prefix)) { - ModuleLog(i, BLOG_ERROR, "bad prefix"); - goto fail0; - } - - // make network - uint32_t network = (addr & ipaddr_ipv4_mask_from_prefix(prefix)); - - addr_func_init_templ(vo, i, network); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void addr_func_die (void *vo) -{ - struct addr_instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int addr_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct addr_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - char buf[IPADDR_PRINT_MAX]; - ipaddr_print_addr(o->addr, buf); - - *out = NCDVal_NewString(mem, buf); - return 1; - } - - return 0; -} - -static void mask_to_prefix_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct prefix_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef mask_arg; - if (!NCDVal_ListRead(params->args, 1, &mask_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(mask_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse mask - uint32_t mask; - if (!ipaddr_parse_ipv4_addr_bin((char *)NCDVal_StringData(mask_arg), NCDVal_StringLength(mask_arg), &mask)) { - ModuleLog(i, BLOG_ERROR, "bad mask"); - goto fail0; - } - - // build prefix - if (!ipaddr_ipv4_prefix_from_mask(mask, &o->prefix)) { - ModuleLog(i, BLOG_ERROR, "bad mask"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void prefix_func_die (void *vo) -{ - struct prefix_instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int prefix_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct prefix_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - char buf[6]; - sprintf(buf, "%d", o->prefix); - - *out = NCDVal_NewString(mem, buf); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "ipv4_prefix_to_mask", - .func_new2 = prefix_to_mask_func_init, - .func_die = addr_func_die, - .func_getvar2 = addr_func_getvar2, - .alloc_size = sizeof(struct addr_instance) - }, { - .type = "ipv4_mask_to_prefix", - .func_new2 = mask_to_prefix_func_init, - .func_die = prefix_func_die, - .func_getvar2 = prefix_func_getvar2, - .alloc_size = sizeof(struct prefix_instance) - }, { - .type = "ipv4_net_from_addr_and_prefix", - .func_new2 = ipv4_net_from_addr_and_prefix_func_init, - .func_die = addr_func_die, - .func_getvar2 = addr_func_getvar2, - .alloc_size = sizeof(struct addr_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_netmask = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/ondemand.c b/external/badvpn_dns/ncd/modules/ondemand.c deleted file mode 100644 index 15c2531..0000000 --- a/external/badvpn_dns/ncd/modules/ondemand.c +++ /dev/null @@ -1,372 +0,0 @@ -/** - * @file ondemand.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * On-demand process manager. - * - * Synopsis: - * ondemand(string template_name, list args) - * - * Description: - * Manages an on-demand template process using a process template named - * template_name. - * On deinitialization, if the process is running, reqests its termination - * and waits for it to terminate. - * - * Synopsis: - * ondemand::demand() - * - * Description: - * Demands the availability of an on-demand template process. - * This statement is in UP state if and only if the template process of the - * corresponding ondemand object is completely up. - * - * Variables: - * Exposes variables and objects from the template process corresponding to - * the ondemand object. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_ondemand.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct ondemand { - NCDModuleInst *i; - NCDValRef template_name; - NCDValRef args; - LinkedList1 demands_list; - int dying; - int have_process; - NCDModuleProcess process; - int process_terminating; - int process_up; -}; - -struct demand { - NCDModuleInst *i; - struct ondemand *od; - LinkedList1Node demands_list_node; -}; - -static int ondemand_start_process (struct ondemand *o); -static void ondemand_terminate_process (struct ondemand *o); -static void ondemand_process_handler (NCDModuleProcess *process, int event); -static void ondemand_free (struct ondemand *o); -static void demand_free (struct demand *o, int is_error); - -static int ondemand_start_process (struct ondemand *o) -{ - ASSERT(!o->dying) - ASSERT(!o->have_process) - - // start process - if (!NCDModuleProcess_InitValue(&o->process, o->i, o->template_name, o->args, ondemand_process_handler)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set have process - o->have_process = 1; - - // set process not terminating - o->process_terminating = 0; - - // set process not up - o->process_up = 0; - - return 1; - -fail0: - return 0; -} - -static void ondemand_terminate_process (struct ondemand *o) -{ - ASSERT(o->have_process) - ASSERT(!o->process_terminating) - - // request termination - NCDModuleProcess_Terminate(&o->process); - - // set process terminating - o->process_terminating = 1; - - if (o->process_up) { - // set process down - o->process_up = 0; - - // signal demands down - for (LinkedList1Node *n = LinkedList1_GetFirst(&o->demands_list); n; n = LinkedList1Node_Next(n)) { - struct demand *demand = UPPER_OBJECT(n, struct demand, demands_list_node); - ASSERT(demand->od == o) - NCDModuleInst_Backend_Down(demand->i); - } - } -} - -static void ondemand_process_handler (NCDModuleProcess *process, int event) -{ - struct ondemand *o = UPPER_OBJECT(process, struct ondemand, process); - ASSERT(o->have_process) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(!o->process_terminating) - ASSERT(!o->process_up) - - // set process up - o->process_up = 1; - - // signal demands up - for (LinkedList1Node *n = LinkedList1_GetFirst(&o->demands_list); n; n = LinkedList1Node_Next(n)) { - struct demand *demand = UPPER_OBJECT(n, struct demand, demands_list_node); - ASSERT(demand->od == o) - NCDModuleInst_Backend_Up(demand->i); - } - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(!o->process_terminating) - ASSERT(o->process_up) - - // continue process - NCDModuleProcess_Continue(&o->process); - - // set process down - o->process_up = 0; - - // signal demands down - for (LinkedList1Node *n = LinkedList1_GetFirst(&o->demands_list); n; n = LinkedList1Node_Next(n)) { - struct demand *demand = UPPER_OBJECT(n, struct demand, demands_list_node); - ASSERT(demand->od == o) - NCDModuleInst_Backend_Down(demand->i); - } - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->process_terminating) - ASSERT(!o->process_up) - - // free process - NCDModuleProcess_Free(&o->process); - - // set have no process - o->have_process = 0; - - // if dying, die finally - if (o->dying) { - ondemand_free(o); - return; - } - - // if demands arrivied, restart process - if (!LinkedList1_IsEmpty(&o->demands_list)) { - if (!ondemand_start_process(o)) { - // error demands - while (!LinkedList1_IsEmpty(&o->demands_list)) { - struct demand *demand = UPPER_OBJECT(LinkedList1_GetFirst(&o->demands_list), struct demand, demands_list_node); - ASSERT(demand->od == o) - demand_free(demand, 1); - } - } - } - } break; - } -} - -static void ondemand_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct ondemand *o = vo; - o->i = i; - - // read arguments - NCDValRef arg_template_name; - NCDValRef arg_args; - if (!NCDVal_ListRead(params->args, 2, &arg_template_name, &arg_args)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(arg_template_name) || !NCDVal_IsList(arg_args)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->template_name = arg_template_name; - o->args = arg_args; - - // init demands list - LinkedList1_Init(&o->demands_list); - - // set not dying - o->dying = 0; - - // set have no process - o->have_process = 0; - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void ondemand_free (struct ondemand *o) -{ - ASSERT(!o->have_process) - - // die demands - while (!LinkedList1_IsEmpty(&o->demands_list)) { - struct demand *demand = UPPER_OBJECT(LinkedList1_GetFirst(&o->demands_list), struct demand, demands_list_node); - ASSERT(demand->od == o) - demand_free(demand, 0); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void ondemand_func_die (void *vo) -{ - struct ondemand *o = vo; - ASSERT(!o->dying) - - // if not have process, die right away - if (!o->have_process) { - ondemand_free(o); - return; - } - - // set dying - o->dying = 1; - - // request process termination if not already - if (!o->process_terminating) { - ondemand_terminate_process(o); - } -} - -static void demand_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct demand *o = vo; - o->i = i; - - // read arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // set ondemand - o->od = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // add to ondemand's demands list - LinkedList1_Append(&o->od->demands_list, &o->demands_list_node); - - // start process if needed - if (!o->od->have_process) { - ASSERT(!o->od->dying) - - if (!ondemand_start_process(o->od)) { - goto fail1; - } - } - - // if process is up, signal up - if (o->od->process_up) { - NCDModuleInst_Backend_Up(i); - } - - return; - -fail1: - LinkedList1_Remove(&o->od->demands_list, &o->demands_list_node); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void demand_free (struct demand *o, int is_error) -{ - // remove from ondemand's demands list - LinkedList1_Remove(&o->od->demands_list, &o->demands_list_node); - - // request process termination if no longer needed - if (o->od->have_process && !o->od->process_terminating && LinkedList1_IsEmpty(&o->od->demands_list)) { - ondemand_terminate_process(o->od); - } - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void demand_func_die (void *vo) -{ - struct demand *o = vo; - - demand_free(o, 0); -} - -static int demand_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct demand *o = vo; - ASSERT(o->od->have_process) - ASSERT(o->od->process_up) - - return NCDModuleProcess_GetObj(&o->od->process, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "ondemand", - .func_new2 = ondemand_func_new, - .func_die = ondemand_func_die, - .alloc_size = sizeof(struct ondemand) - }, { - .type = "ondemand::demand", - .func_new2 = demand_func_new, - .func_die = demand_func_die, - .func_getobj = demand_func_getobj, - .alloc_size = sizeof(struct demand) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_ondemand = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/parse.c b/external/badvpn_dns/ncd/modules/parse.c deleted file mode 100644 index f4f4065..0000000 --- a/external/badvpn_dns/ncd/modules/parse.c +++ /dev/null @@ -1,392 +0,0 @@ -/** - * @file parse.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * parse_number(string str) - * parse_value(string str) - * parse_ipv4_addr(string str) - * parse_ipv6_addr(string str) - * - * Variables: - * succeeded - "true" or "false", reflecting success of the parsing - * (empty) - normalized parsed value (only if succeeded) - * - * Synopsis: - * parse_ipv4_cidr_addr(string str) - * parse_ipv6_cidr_addr(string str) - * - * Variables: - * succeeded - "true" or "false", reflecting success of the parsing - * (empty) - normalized CIDR notation address (only if succeeded) - * addr - normalized address without prefix (only if succeeded) - * prefix - normalized prefix without address (only if succeeded) - */ - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> - -#include <misc/parse_number.h> -#include <misc/ipaddr.h> -#include <misc/ipaddr6.h> -#include <ncd/NCDValParser.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_parse.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -struct instance { - NCDModuleInst *i; - NCDValMem mem; - NCDValRef value; - int succeeded; -}; - -struct ipv4_cidr_instance { - NCDModuleInst *i; - int succeeded; - struct ipv4_ifaddr ifaddr; -}; - -struct ipv6_cidr_instance { - NCDModuleInst *i; - int succeeded; - struct ipv6_ifaddr ifaddr; -}; - -enum {STRING_ADDR, STRING_PREFIX}; - -static const char *strings[] = { - "addr", "prefix", NULL -}; - -typedef int (*parse_func) (NCDModuleInst *i, const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out); - -static int parse_number (NCDModuleInst *i, const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out) -{ - uintmax_t n; - if (!parse_unsigned_integer_bin(str, str_len, &n)) { - ModuleLog(i, BLOG_ERROR, "failed to parse number"); - return 0; - } - - *out = ncd_make_uintmax(mem, n); - if (NCDVal_IsInvalid(*out)) { - return 0; - } - - return 1; -} - -static int parse_value (NCDModuleInst *i, const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out) -{ - if (!NCDValParser_Parse(str, str_len, mem, out)) { - ModuleLog(i, BLOG_ERROR, "failed to parse value"); - return 0; - } - - return 1; -} - -static int parse_ipv4_addr (NCDModuleInst *i, const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out) -{ - uint32_t addr; - if (!ipaddr_parse_ipv4_addr_bin(str, str_len, &addr)) { - ModuleLog(i, BLOG_ERROR, "failed to parse ipv4 addresss"); - return 0; - } - - char buf[IPADDR_PRINT_MAX]; - ipaddr_print_addr(addr, buf); - - *out = NCDVal_NewString(mem, buf); - if (NCDVal_IsInvalid(*out)) { - return 0; - } - - return 1; -} - -static int parse_ipv6_addr (NCDModuleInst *i, const char *str, size_t str_len, NCDValMem *mem, NCDValRef *out) -{ - struct ipv6_addr addr; - if (!ipaddr6_parse_ipv6_addr_bin(str, str_len, &addr)) { - ModuleLog(i, BLOG_ERROR, "failed to parse ipv6 addresss"); - return 0; - } - - char buf[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(addr, buf); - - *out = NCDVal_NewString(mem, buf); - if (NCDVal_IsInvalid(*out)) { - return 0; - } - - return 1; -} - -static void new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, parse_func pfunc) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef str_arg; - if (!NCDVal_ListRead(params->args, 1, &str_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // init mem - NCDValMem_Init(&o->mem); - - // parse - o->succeeded = pfunc(i, NCDVal_StringData(str_arg), NCDVal_StringLength(str_arg), &o->mem, &o->value); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free mem - NCDValMem_Free(&o->mem); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_SUCCEEDED) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - if (o->succeeded && name == NCD_STRING_EMPTY) { - *out = NCDVal_NewCopy(mem, o->value); - return 1; - } - - return 0; -} - -static void func_new_parse_number (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, parse_number); -} - -static void func_new_parse_value (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, parse_value); -} - -static void func_new_parse_ipv4_addr (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, parse_ipv4_addr); -} - -static void func_new_parse_ipv6_addr (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, parse_ipv6_addr); -} - -static void ipv4_cidr_addr_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct ipv4_cidr_instance *o = vo; - o->i = i; - - NCDValRef str_arg; - if (!NCDVal_ListRead(params->args, 1, &str_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->succeeded = ipaddr_parse_ipv4_ifaddr_bin(NCDVal_StringData(str_arg), NCDVal_StringLength(str_arg), &o->ifaddr); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int ipv4_cidr_addr_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct ipv4_cidr_instance *o = vo; - - if (name == NCD_STRING_SUCCEEDED) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - if (!o->succeeded) { - return 0; - } - - char str[IPADDR_PRINT_MAX]; - - if (name == NCD_STRING_EMPTY) { - ipaddr_print_ifaddr(o->ifaddr, str); - } - else if (name == ModuleString(o->i, STRING_ADDR)) { - ipaddr_print_addr(o->ifaddr.addr, str); - } - else if (name == ModuleString(o->i, STRING_PREFIX)) { - sprintf(str, "%d", o->ifaddr.prefix); - } - else { - return 0; - } - - *out = NCDVal_NewString(mem, str); - return 1; -} - -static void ipv6_cidr_addr_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct ipv6_cidr_instance *o = vo; - o->i = i; - - NCDValRef str_arg; - if (!NCDVal_ListRead(params->args, 1, &str_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - o->succeeded = ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(str_arg), NCDVal_StringLength(str_arg), &o->ifaddr); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int ipv6_cidr_addr_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct ipv6_cidr_instance *o = vo; - - if (name == NCD_STRING_SUCCEEDED) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - if (!o->succeeded) { - return 0; - } - - char str[IPADDR6_PRINT_MAX]; - - if (name == NCD_STRING_EMPTY) { - ipaddr6_print_ifaddr(o->ifaddr, str); - } - else if (name == ModuleString(o->i, STRING_ADDR)) { - ipaddr6_print_addr(o->ifaddr.addr, str); - } - else if (name == ModuleString(o->i, STRING_PREFIX)) { - sprintf(str, "%d", o->ifaddr.prefix); - } - else { - return 0; - } - - *out = NCDVal_NewString(mem, str); - return 1; -} - -static struct NCDModule modules[] = { - { - .type = "parse_number", - .func_new2 = func_new_parse_number, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "parse_value", - .func_new2 = func_new_parse_value, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "parse_ipv4_addr", - .func_new2 = func_new_parse_ipv4_addr, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "parse_ipv6_addr", - .func_new2 = func_new_parse_ipv6_addr, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "parse_ipv4_cidr_addr", - .func_new2 = ipv4_cidr_addr_func_new, - .func_getvar2 = ipv4_cidr_addr_func_getvar2, - .alloc_size = sizeof(struct ipv4_cidr_instance) - }, { - .type = "parse_ipv6_cidr_addr", - .func_new2 = ipv6_cidr_addr_func_new, - .func_getvar2 = ipv6_cidr_addr_func_getvar2, - .alloc_size = sizeof(struct ipv6_cidr_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_parse = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/print.c b/external/badvpn_dns/ncd/modules/print.c deleted file mode 100644 index 6fa0b56..0000000 --- a/external/badvpn_dns/ncd/modules/print.c +++ /dev/null @@ -1,207 +0,0 @@ -/** - * @file print.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Modules for printing to standard output. - * - * Synopsis: - * print([string str ...]) - * Description: - * On initialization, prints strings to standard output. - * - * Synopsis: - * println([string str ...]) - * Description: - * On initialization, prints strings to standard output, and a newline. - * - * Synopsis: - * rprint([string str ...]) - * Description: - * On deinitialization, prints strings to standard output. - * - * Synopsis: - * rprintln([string str ...]) - * Description: - * On deinitialization, prints strings to standard output, and a newline. - */ - -#include <stdlib.h> -#include <stdio.h> - -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_print.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct rprint_instance { - NCDModuleInst *i; - NCDValRef args; - int ln; -}; - -static int check_args (NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - size_t num_args = NCDVal_ListCount(params->args); - - for (size_t j = 0; j < num_args; j++) { - NCDValRef arg = NCDVal_ListGet(params->args, j); - if (!NCDVal_IsString(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - return 0; - } - } - - return 1; -} - -static void do_print (NCDModuleInst *i, NCDValRef args, int ln) -{ - size_t num_args = NCDVal_ListCount(args); - - for (size_t j = 0; j < num_args; j++) { - NCDValRef arg = NCDVal_ListGet(args, j); - ASSERT(NCDVal_IsString(arg)) - - b_cstring arg_cstr = NCDVal_StringCstring(arg); - - B_CSTRING_LOOP_RANGE(arg_cstr, 0, arg_cstr.length, pos, chunk_data, chunk_length, { - size_t chunk_pos = 0; - while (chunk_pos < chunk_length) { - ssize_t res = fwrite(chunk_data + chunk_pos, 1, chunk_length - chunk_pos, stdout); - if (res <= 0) { - goto out; - } - chunk_pos += res; - } - }) - } - -out: - if (ln) { - printf("\n"); - } -} - -static void rprint_func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int ln) -{ - struct rprint_instance *o = vo; - o->i = i; - o->args = params->args; - o->ln = ln; - - if (!check_args(i, params)) { - goto fail0; - } - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void rprint_func_die (void *vo) -{ - struct rprint_instance *o = vo; - - do_print(o->i, o->args, o->ln); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void print_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (!check_args(i, params)) { - goto fail0; - } - - do_print(i, params->args, 0); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void println_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (!check_args(i, params)) { - goto fail0; - } - - do_print(i, params->args, 1); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void rprint_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - return rprint_func_new_common(vo, i, params, 0); -} - -static void rprintln_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - return rprint_func_new_common(vo, i, params, 1); -} - -static struct NCDModule modules[] = { - { - .type = "print", - .func_new2 = print_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "println", - .func_new2 = println_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "rprint", - .func_new2 = rprint_func_new, - .func_die = rprint_func_die, - .alloc_size = sizeof(struct rprint_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "rprintln", - .func_new2 = rprintln_func_new, - .func_die = rprint_func_die, - .alloc_size = sizeof(struct rprint_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_print = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/process_manager.c b/external/badvpn_dns/ncd/modules/process_manager.c deleted file mode 100644 index 390c8d5..0000000 --- a/external/badvpn_dns/ncd/modules/process_manager.c +++ /dev/null @@ -1,538 +0,0 @@ -/** - * @file process_manager.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module which allows starting and controlling template processes using an imperative - * interface. - * - * Synopsis: - * process_manager() - * - * Description: - * Represents a set of managed processes. Each process has a "name", which is a value - * that uniquely identifies it within its process manager. - * When deinitialization is requested, requests termination of all managed processes - * and waits for all of them to terminate before deinitializing. - * Managed processes can access objects as seen from the process_manager() statement - * via the special _caller object. - * - * Synopsis: - * process_manager::start(name, string template_name, list args) - * process_manager::start(string template_name, list args) - * - * Description: - * Creates a new process from the template named 'template_name', with arguments 'args', - * identified by 'name' within the process manager. If the two-argument form of start() is - * used, the process does not have a name, and cannot be imperatively stopped using - * stop(). - * If a process with this name already exists and is not being terminated, does nothing. - * If it exists and is being terminated, it will be restarted using the given parameters - * after it terminates. If the process does not exist, it is created immediately, and the - * immediate effects of the process being created happnen before the immediate effects of - * the start() statement going up. - * - * Synopsis: - * process_manager::stop(name) - * - * Description: - * Initiates termination of the process identified by 'name' within the process manager. - * If there is no such process, or the process is already being terminated, does nothing. - * If the process does exist and is not already being terminated, termination of the - * process is requested, and the immediate effects of the termination request happen - * before the immediate effects of the stop() statement going up. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/strdup.h> -#include <misc/balloc.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_process_manager.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define RETRY_TIME 10000 - -#define PROCESS_STATE_RUNNING 1 -#define PROCESS_STATE_STOPPING 2 -#define PROCESS_STATE_RESTARTING 3 -#define PROCESS_STATE_RETRYING 4 - -struct instance { - NCDModuleInst *i; - LinkedList1 processes_list; - int dying; -}; - -struct process { - struct instance *manager; - LinkedList1Node processes_list_node; - BSmallTimer retry_timer; // running if state=retrying - int state; - NCD_string_id_t template_name; - NCDValMem current_mem; - NCDValSafeRef current_name; - NCDValSafeRef current_args; - NCDValMem next_mem; // next_* if state=restarting - NCDValSafeRef next_name; - NCDValSafeRef next_args; - NCDModuleProcess module_process; // if state!=retrying -}; - -static struct process * find_process (struct instance *o, NCDValRef name); -static int process_new (struct instance *o, NCDValMem *mem, NCDValSafeRef name, NCDValSafeRef template_name, NCDValSafeRef args); -static void process_free (struct process *p); -static void process_try (struct process *p); -static void process_retry_timer_handler (BSmallTimer *retry_timer); -static void process_module_process_handler_event (NCDModuleProcess *module_process, int event); -static int process_module_process_func_getspecialobj (NCDModuleProcess *module_process, NCD_string_id_t name, NCDObject *out_object); -static int process_module_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static void process_stop (struct process *p); -static int process_restart (struct process *p, NCDValMem *mem, NCDValSafeRef name, NCDValSafeRef template_name, NCDValSafeRef args); -static void instance_free (struct instance *o); - -static struct process * find_process (struct instance *o, NCDValRef name) -{ - ASSERT(!NCDVal_IsInvalid(name)) - - LinkedList1Node *n = LinkedList1_GetFirst(&o->processes_list); - while (n) { - struct process *p = UPPER_OBJECT(n, struct process, processes_list_node); - ASSERT(p->manager == o) - if (!NCDVal_IsInvalid(NCDVal_FromSafe(&p->current_mem, p->current_name)) && NCDVal_Compare(NCDVal_FromSafe(&p->current_mem, p->current_name), name) == 0) { - return p; - } - n = LinkedList1Node_Next(n); - } - - return NULL; -} - -static int process_new (struct instance *o, NCDValMem *mem, NCDValSafeRef name, NCDValSafeRef template_name, NCDValSafeRef args) -{ - ASSERT(!o->dying) - ASSERT(NCDVal_IsInvalid(NCDVal_FromSafe(mem, name)) || !find_process(o, NCDVal_FromSafe(mem, name))) - ASSERT(NCDVal_IsString(NCDVal_FromSafe(mem, template_name))) - ASSERT(NCDVal_IsList(NCDVal_FromSafe(mem, args))) - - // allocate structure - struct process *p = BAlloc(sizeof(*p)); - if (!p) { - ModuleLog(o->i, BLOG_ERROR, "BAlloc failed"); - goto fail0; - } - - // set manager - p->manager = o; - - // insert to processes list - LinkedList1_Append(&o->processes_list, &p->processes_list_node); - - // init retry timer - BSmallTimer_Init(&p->retry_timer, process_retry_timer_handler); - - // init template name - p->template_name = ncd_get_string_id(NCDVal_FromSafe(mem, template_name), o->i->params->iparams->string_index); - if (p->template_name < 0) { - ModuleLog(o->i, BLOG_ERROR, "ncd_get_string_id failed"); - goto fail1; - } - - // init current mem as a copy of mem - if (!NCDValMem_InitCopy(&p->current_mem, mem)) { - ModuleLog(o->i, BLOG_ERROR, "NCDValMem_InitCopy failed"); - goto fail1; - } - - // remember name and args - p->current_name = name; - p->current_args = args; - - // try starting it - process_try(p); - return 1; - -fail1: - LinkedList1_Remove(&o->processes_list, &p->processes_list_node); - BFree(p); -fail0: - return 0; -} - -static void process_free (struct process *p) -{ - struct instance *o = p->manager; - - // free current mem - NCDValMem_Free(&p->current_mem); - - // free timer - BReactor_RemoveSmallTimer(o->i->params->iparams->reactor, &p->retry_timer); - - // remove from processes list - LinkedList1_Remove(&o->processes_list, &p->processes_list_node); - - // free structure - BFree(p); -} - -static void process_try (struct process *p) -{ - struct instance *o = p->manager; - ASSERT(!o->dying) - ASSERT(!BSmallTimer_IsRunning(&p->retry_timer)) - - // init module process - if (!NCDModuleProcess_InitId(&p->module_process, o->i, p->template_name, NCDVal_FromSafe(&p->current_mem, p->current_args), process_module_process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail; - } - - // set special objects function - NCDModuleProcess_SetSpecialFuncs(&p->module_process, process_module_process_func_getspecialobj); - - // set state - p->state = PROCESS_STATE_RUNNING; - return; - -fail: - // set timer - BReactor_SetSmallTimer(o->i->params->iparams->reactor, &p->retry_timer, BTIMER_SET_RELATIVE, RETRY_TIME); - - // set state - p->state = PROCESS_STATE_RETRYING; -} - -static void process_retry_timer_handler (BSmallTimer *retry_timer) -{ - struct process *p = UPPER_OBJECT(retry_timer, struct process, retry_timer); - struct instance *o = p->manager; - B_USE(o) - ASSERT(p->state == PROCESS_STATE_RETRYING) - ASSERT(!o->dying) - - // retry - process_try(p); -} - -void process_module_process_handler_event (NCDModuleProcess *module_process, int event) -{ - struct process *p = UPPER_OBJECT(module_process, struct process, module_process); - struct instance *o = p->manager; - ASSERT(p->state != PROCESS_STATE_RETRYING) - ASSERT(p->state != PROCESS_STATE_RESTARTING || !o->dying) - ASSERT(!BSmallTimer_IsRunning(&p->retry_timer)) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(p->state == PROCESS_STATE_RUNNING) - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(p->state == PROCESS_STATE_RUNNING) - - // allow process to continue - NCDModuleProcess_Continue(&p->module_process); - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(p->state == PROCESS_STATE_RESTARTING || p->state == PROCESS_STATE_STOPPING) - - // free module process - NCDModuleProcess_Free(&p->module_process); - - if (p->state == PROCESS_STATE_RESTARTING) { - // free current mem - NCDValMem_Free(&p->current_mem); - - // move next mem/values over current mem/values - p->current_mem = p->next_mem; - p->current_name = p->next_name; - p->current_args = p->next_args; - - // try starting it again - process_try(p); - return; - } - - // free process - process_free(p); - - // if manager is dying and there are no more processes, let it die - if (o->dying && LinkedList1_IsEmpty(&o->processes_list)) { - instance_free(o); - } - } break; - } -} - -static int process_module_process_func_getspecialobj (NCDModuleProcess *module_process, NCD_string_id_t name, NCDObject *out_object) -{ - struct process *p = UPPER_OBJECT(module_process, struct process, module_process); - ASSERT(p->state != PROCESS_STATE_RETRYING) - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, p, NCDObject_no_getvar, process_module_process_caller_obj_func_getobj); - return 1; - } - - return 0; -} - -static int process_module_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct process *p = NCDObject_DataPtr(obj); - struct instance *o = p->manager; - ASSERT(p->state != PROCESS_STATE_RETRYING) - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static void process_stop (struct process *p) -{ - switch (p->state) { - case PROCESS_STATE_RETRYING: { - // free process - process_free(p); - } break; - - case PROCESS_STATE_RUNNING: { - // request process to terminate - NCDModuleProcess_Terminate(&p->module_process); - - // set state - p->state = PROCESS_STATE_STOPPING; - } break; - - case PROCESS_STATE_RESTARTING: { - // free next mem - NCDValMem_Free(&p->next_mem); - - // set state - p->state = PROCESS_STATE_STOPPING; - } break; - - case PROCESS_STATE_STOPPING: { - // nothing to do - } break; - - default: ASSERT(0); - } -} - -static int process_restart (struct process *p, NCDValMem *mem, NCDValSafeRef name, NCDValSafeRef template_name, NCDValSafeRef args) -{ - struct instance *o = p->manager; - ASSERT(!o->dying) - ASSERT(p->state == PROCESS_STATE_STOPPING) - ASSERT(!NCDVal_IsInvalid(NCDVal_FromSafe(&p->current_mem, p->current_name)) || NCDVal_IsInvalid(NCDVal_FromSafe(mem, name))) - ASSERT(NCDVal_IsInvalid(NCDVal_FromSafe(&p->current_mem, p->current_name)) || NCDVal_Compare(NCDVal_FromSafe(mem, name), NCDVal_FromSafe(&p->current_mem, p->current_name)) == 0) - ASSERT(NCDVal_IsString(NCDVal_FromSafe(mem, template_name))) - ASSERT(NCDVal_IsList(NCDVal_FromSafe(mem, args))) - - // copy mem to next mem - if (!NCDValMem_InitCopy(&p->next_mem, mem)) { - ModuleLog(o->i, BLOG_ERROR, "NCDValMem_InitCopy failed"); - goto fail0; - } - - // remember name and args to next - p->next_name = name; - p->next_args = args; - - // set state - p->state = PROCESS_STATE_RESTARTING; - return 1; - -fail0: - return 0; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init processes list - LinkedList1_Init(&o->processes_list); - - // set not dying - o->dying = 0; - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o) -{ - ASSERT(LinkedList1_IsEmpty(&o->processes_list)) - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // request all processes to die - LinkedList1Node *n = LinkedList1_GetFirst(&o->processes_list); - while (n) { - LinkedList1Node *next = LinkedList1Node_Next(n); - struct process *p = UPPER_OBJECT(n, struct process, processes_list_node); - process_stop(p); - n = next; - } - - // if there are no processes, die immediately - if (LinkedList1_IsEmpty(&o->processes_list)) { - instance_free(o); - return; - } - - // set dying - o->dying = 1; -} - -static void start_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef name_arg = NCDVal_NewInvalid(); - NCDValRef template_name_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 2, &template_name_arg, &args_arg) && - !NCDVal_ListRead(params->args, 3, &name_arg, &template_name_arg, &args_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(template_name_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // signal up. - // Do it before creating the process so that the process starts initializing before our own process continues. - NCDModuleInst_Backend_Up(i); - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - if (!mo->dying) { - struct process *p = (NCDVal_IsInvalid(name_arg) ? NULL : find_process(mo, name_arg)); - if (!p || p->state == PROCESS_STATE_STOPPING) { - if (p) { - if (!process_restart(p, args_arg.mem, NCDVal_ToSafe(name_arg), NCDVal_ToSafe(template_name_arg), NCDVal_ToSafe(args_arg))) { - ModuleLog(i, BLOG_ERROR, "failed to restart process"); - goto fail0; - } - } else { - if (!process_new(mo, args_arg.mem, NCDVal_ToSafe(name_arg), NCDVal_ToSafe(template_name_arg), NCDVal_ToSafe(args_arg))) { - ModuleLog(i, BLOG_ERROR, "failed to create process"); - goto fail0; - } - } - } - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void stop_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef name_arg; - if (!NCDVal_ListRead(params->args, 1, &name_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // signal up. - // Do it before stopping the process so that the process starts terminating before our own process continues. - NCDModuleInst_Backend_Up(i); - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - if (!mo->dying) { - struct process *p = find_process(mo, name_arg); - if (p && p->state != PROCESS_STATE_STOPPING) { - process_stop(p); - } - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "process_manager", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "process_manager::start", - .func_new2 = start_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "process_manager::stop", - .func_new2 = stop_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_process_manager = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/reboot.c b/external/badvpn_dns/ncd/modules/reboot.c deleted file mode 100644 index 3522431..0000000 --- a/external/badvpn_dns/ncd/modules/reboot.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file reboot.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * hard_reboot() - * hard_poweroff() - */ - -#include <unistd.h> -#include <sys/reboot.h> - -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_reboot.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void func_new_hard_reboot (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // reboot - if (reboot(RB_AUTOBOOT) < 0) { - ModuleLog(i, BLOG_ERROR, "reboot(RB_AUTOBOOT) failed"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_hard_poweroff (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // power off - if (reboot(RB_POWER_OFF) < 0) { - ModuleLog(i, BLOG_ERROR, "reboot(RB_POWER_OFF) failed"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "hard_reboot", - .func_new2 = func_new_hard_reboot - }, { - .type = "hard_poweroff", - .func_new2 = func_new_hard_poweroff - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_reboot = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/ref.c b/external/badvpn_dns/ncd/modules/ref.c deleted file mode 100644 index a0e9cf8..0000000 --- a/external/badvpn_dns/ncd/modules/ref.c +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @file ref.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * References module. - * - * Synopsis: - * refhere() - * Variables: - * Exposes variables and objects as seen from this refhere() statement. - * - * Synopsis: - * ref refhere::ref() - * ref ref::ref() - * Variables: - * Exposes variables and objects as seen from the corresponding refhere() - * statement. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <structure/LinkedList0.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_ref.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct refhere_instance { - NCDModuleInst *i; - LinkedList0 refs_list; -}; - -struct ref_instance { - NCDModuleInst *i; - struct refhere_instance *rh; - LinkedList0Node refs_list_node; -}; - -static void ref_instance_free (struct ref_instance *o); - -static void refhere_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct refhere_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init refs list - LinkedList0_Init(&o->refs_list); - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void refhere_func_die (void *vo) -{ - struct refhere_instance *o = vo; - - // die refs - while (!LinkedList0_IsEmpty(&o->refs_list)) { - struct ref_instance *ref = UPPER_OBJECT(LinkedList0_GetFirst(&o->refs_list), struct ref_instance, refs_list_node); - ASSERT(ref->rh == o) - ref_instance_free(ref); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int refhere_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct refhere_instance *o = vo; - - // We don't redirect methods, and there will never be an object - // with empty name. Fail here so we don't report non-errors. - if (objname == NCD_STRING_EMPTY) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(o->i, objname, out_object); -} - -static void ref_func_new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, struct refhere_instance *rh) -{ - struct ref_instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // set refhere - o->rh = rh; - - // add to refhere's refs list - LinkedList0_Prepend(&o->rh->refs_list, &o->refs_list_node); - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void ref_func_new_from_refhere (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct refhere_instance *rh = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - return ref_func_new_templ(vo, i, params, rh); -} - -static void ref_func_new_from_ref (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct ref_instance *ref = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - return ref_func_new_templ(vo, i, params, ref->rh); -} - -static void ref_instance_free (struct ref_instance *o) -{ - // remove from refhere's reft list - LinkedList0_Remove(&o->rh->refs_list, &o->refs_list_node); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void ref_func_die (void *vo) -{ - struct ref_instance *o = vo; - - ref_instance_free(o); -} - -static int ref_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object) -{ - struct ref_instance *o = vo; - - // We don't redirect methods, and there will never be an object - // with empty name. Fail here so we don't report non-errors. - if (objname == NCD_STRING_EMPTY) { - return 0; - } - - return NCDModuleInst_Backend_GetObj(o->rh->i, objname, out_object); -} - -static struct NCDModule modules[] = { - { - .type = "refhere", - .func_new2 = refhere_func_new, - .func_die = refhere_func_die, - .func_getobj = refhere_func_getobj, - .alloc_size = sizeof(struct refhere_instance) - }, { - .type = "refhere::ref", - .base_type = "ref", - .func_new2 = ref_func_new_from_refhere, - .func_die = ref_func_die, - .func_getobj = ref_func_getobj, - .alloc_size = sizeof(struct ref_instance) - }, { - .type = "ref::ref", - .base_type = "ref", - .func_new2 = ref_func_new_from_ref, - .func_die = ref_func_die, - .func_getobj = ref_func_getobj, - .alloc_size = sizeof(struct ref_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_ref = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/regex_match.c b/external/badvpn_dns/ncd/modules/regex_match.c deleted file mode 100644 index d541b88..0000000 --- a/external/badvpn_dns/ncd/modules/regex_match.c +++ /dev/null @@ -1,369 +0,0 @@ -/** - * @file regex_match.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Regular expression matching module. - * - * Synopsis: - * regex_match(string input, string regex) - * - * Variables: - * succeeded - "true" or "false", indicating whether input matched regex - * matchN - for N=0,1,2,..., the matching data for the N-th subexpression - * (match0 = whole match) - * - * Description: - * Matches 'input' with the POSIX extended regular expression 'regex'. - * 'regex' must be a string without null bytes, but 'input' can contain null bytes. - * However, it's difficult, if not impossible, to actually match nulls with the regular - * expression. - * The input and regex strings are interpreted according to the POSIX regex functions - * (regcomp(), regexec()); in particular, the current locale setting affects the - * interpretation. - * - * Synopsis: - * regex_replace(string input, list(string) regex, list(string) replace) - * - * Variables: - * string (empty) - transformed input - * - * Description: - * Replaces matching parts of a string. Replacement is performed by repetedly matching - * the remaining part of the string with all regular expressions. On each step, out of - * all regular expressions that match the remainder of the string, the one whose match - * starts at the least position wins, and the matching part is replaced with the - * replacement string corresponding to this regular expression. The process continues - * from the end of the just-replaced portion until no more regular expressions match. - * If multiple regular expressions match at the least position, the one that appears - * first in the 'regex' argument wins. - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <regex.h> - -#include <misc/string_begins_with.h> -#include <misc/parse_number.h> -#include <misc/expstring.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_regex_match.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define MAX_MATCHES 64 - -struct instance { - NCDModuleInst *i; - const char *input; - size_t input_len; - int succeeded; - int num_matches; - regmatch_t matches[MAX_MATCHES]; -}; - -struct replace_instance { - NCDModuleInst *i; - char *output; - size_t output_len; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef input_arg; - NCDValRef regex_arg; - if (!NCDVal_ListRead(params->args, 2, &input_arg, ®ex_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(input_arg) || !NCDVal_IsStringNoNulls(regex_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->input = NCDVal_StringData(input_arg); - o->input_len = NCDVal_StringLength(input_arg); - - // make sure we don't overflow regoff_t - if (o->input_len > INT_MAX) { - ModuleLog(o->i, BLOG_ERROR, "input string too long"); - goto fail0; - } - - // null terminate regex - NCDValNullTermString regex_nts; - if (!NCDVal_StringNullTerminate(regex_arg, ®ex_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // compile regex - regex_t preg; - int ret = regcomp(&preg, regex_nts.data, REG_EXTENDED); - NCDValNullTermString_Free(®ex_nts); - if (ret != 0) { - ModuleLog(o->i, BLOG_ERROR, "regcomp failed (error=%d)", ret); - goto fail0; - } - - // execute match - o->matches[0].rm_so = 0; - o->matches[0].rm_eo = o->input_len; - o->succeeded = (regexec(&preg, o->input, MAX_MATCHES, o->matches, REG_STARTEND) == 0); - - // free regex - regfree(&preg); - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (!strcmp(name, "succeeded")) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - size_t pos; - uintmax_t n; - if ((pos = string_begins_with(name, "match")) && parse_unsigned_integer(name + pos, &n)) { - if (o->succeeded && n < MAX_MATCHES && o->matches[n].rm_so >= 0) { - regmatch_t *m = &o->matches[n]; - - ASSERT(m->rm_so <= o->input_len) - ASSERT(m->rm_eo >= m->rm_so) - ASSERT(m->rm_eo <= o->input_len) - - size_t len = m->rm_eo - m->rm_so; - - *out = NCDVal_NewStringBin(mem, (uint8_t *)o->input + m->rm_so, len); - return 1; - } - } - - return 0; -} - -static void replace_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct replace_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef input_arg; - NCDValRef regex_arg; - NCDValRef replace_arg; - if (!NCDVal_ListRead(params->args, 3, &input_arg, ®ex_arg, &replace_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail1; - } - if (!NCDVal_IsString(input_arg) || !NCDVal_IsList(regex_arg) || !NCDVal_IsList(replace_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - // check number of regex/replace - if (NCDVal_ListCount(regex_arg) != NCDVal_ListCount(replace_arg)) { - ModuleLog(i, BLOG_ERROR, "number of regex's is not the same as number of replacements"); - goto fail1; - } - size_t num_regex = NCDVal_ListCount(regex_arg); - - // allocate array for compiled regex's - regex_t *regs = BAllocArray(num_regex, sizeof(regs[0])); - if (!regs) { - ModuleLog(i, BLOG_ERROR, "BAllocArray failed"); - goto fail1; - } - size_t num_done_regex = 0; - - // compile regex's, check arguments - while (num_done_regex < num_regex) { - NCDValRef regex = NCDVal_ListGet(regex_arg, num_done_regex); - NCDValRef replace = NCDVal_ListGet(replace_arg, num_done_regex); - - if (!NCDVal_IsStringNoNulls(regex) || !NCDVal_IsString(replace)) { - ModuleLog(i, BLOG_ERROR, "wrong regex/replace type for pair %zu", num_done_regex); - goto fail2; - } - - // null terminate regex - NCDValNullTermString regex_nts; - if (!NCDVal_StringNullTerminate(regex, ®ex_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail2; - } - - int res = regcomp(®s[num_done_regex], regex_nts.data, REG_EXTENDED); - NCDValNullTermString_Free(®ex_nts); - if (res != 0) { - ModuleLog(i, BLOG_ERROR, "regcomp failed for pair %zu (error=%d)", num_done_regex, res); - goto fail2; - } - - num_done_regex++; - } - - // init output string - ExpString out; - if (!ExpString_Init(&out)) { - ModuleLog(i, BLOG_ERROR, "ExpString_Init failed"); - goto fail2; - } - - // input state - const char *in = NCDVal_StringData(input_arg); - size_t in_pos = 0; - size_t in_len = NCDVal_StringLength(input_arg); - - // process input - while (in_pos < in_len) { - // find first match - int have_match = 0; - size_t match_regex = 0; // to remove warning - regmatch_t match = {0, 0}; // to remove warning - for (size_t j = 0; j < num_regex; j++) { - regmatch_t this_match; - this_match.rm_so = 0; - this_match.rm_eo = in_len - in_pos; - if (regexec(®s[j], in + in_pos, 1, &this_match, REG_STARTEND) == 0 && (!have_match || this_match.rm_so < match.rm_so)) { - have_match = 1; - match_regex = j; - match = this_match; - } - } - - // if no match, append remaining data and finish - if (!have_match) { - if (!ExpString_AppendBinary(&out, (const uint8_t *)in + in_pos, in_len - in_pos)) { - ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail3; - } - break; - } - - // append data before match - if (!ExpString_AppendBinary(&out, (const uint8_t *)in + in_pos, match.rm_so)) { - ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail3; - } - - // append replacement data - NCDValRef replace = NCDVal_ListGet(replace_arg, match_regex); - if (!ExpString_AppendBinary(&out, (const uint8_t *)NCDVal_StringData(replace), NCDVal_StringLength(replace))) { - ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed"); - goto fail3; - } - - in_pos += match.rm_eo; - } - - // set output - o->output = ExpString_Get(&out); - o->output_len = ExpString_Length(&out); - - // free compiled regex's - while (num_done_regex-- > 0) { - regfree(®s[num_done_regex]); - } - - // free array - BFree(regs); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail3: - ExpString_Free(&out); -fail2: - while (num_done_regex-- > 0) { - regfree(®s[num_done_regex]); - } - BFree(regs); -fail1: - NCDModuleInst_Backend_DeadError(i); -} - -static void replace_func_die (void *vo) -{ - struct replace_instance *o = vo; - - // free output - BFree(o->output); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int replace_func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct replace_instance *o = vo; - - if (!strcmp(name, "")) { - *out = NCDVal_NewStringBin(mem, (uint8_t *)o->output, o->output_len); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "regex_match", - .func_new2 = func_new, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "regex_replace", - .func_new2 = replace_func_new, - .func_die = replace_func_die, - .func_getvar = replace_func_getvar, - .alloc_size = sizeof(struct replace_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_regex_match = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/run.c b/external/badvpn_dns/ncd/modules/run.c deleted file mode 100644 index 147914c..0000000 --- a/external/badvpn_dns/ncd/modules/run.c +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @file run.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module for running arbitrary programs. - * NOTE: There is no locking - the program may run in parallel with other - * NCD processes and their programs. - * - * Synopsis: run(list do_cmd, list undo_cmd) - * Arguments: - * list do_cmd - Command run on startup. The first element is the full path - * to the executable, other elements are command line arguments (excluding - * the zeroth argument). An empty list is interpreted as no operation. - * list undo_cmd - Command run on shutdown, like do_cmd. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/strdup.h> -#include <ncd/extra/value_utils.h> -#include <ncd/modules/command_template.h> - -#include <generated/blog_channel_ncd_run.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void template_free_func (void *vo, int is_error); - -struct instance { - NCDModuleInst *i; - BEventLock lock; - command_template_instance cti; -}; - -static int build_cmdline (NCDModuleInst *i, NCDValRef args, int remove, char **exec, CmdLine *cl) -{ - // read arguments - NCDValRef do_cmd_arg; - NCDValRef undo_cmd_arg; - if (!NCDVal_ListRead(args, 2, &do_cmd_arg, &undo_cmd_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(do_cmd_arg) || !NCDVal_IsList(undo_cmd_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - NCDValRef list = (remove ? undo_cmd_arg : do_cmd_arg); - size_t count = NCDVal_ListCount(list); - - // check if there is no command - if (count == 0) { - *exec = NULL; - return 1; - } - - // read exec - NCDValRef exec_arg = NCDVal_ListGet(list, 0); - if (!NCDVal_IsStringNoNulls(exec_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - if (!(*exec = ncd_strdup(exec_arg))) { - ModuleLog(i, BLOG_ERROR, "ncd_strdup failed"); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add header - if (!CmdLine_Append(cl, *exec)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // add additional arguments - for (size_t j = 1; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(list, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail2; - } - - b_cstring arg_cstr = NCDVal_StringCstring(arg); - if (!CmdLine_AppendCstring(cl, arg_cstr, 0, arg_cstr.length)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_AppendCstring failed"); - goto fail2; - } - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // init dummy event lock - BEventLock_Init(&o->lock, BReactor_PendingGroup(i->params->iparams->reactor)); - - command_template_new(&o->cti, i, params, build_cmdline, template_free_func, o, BLOG_CURRENT_CHANNEL, &o->lock); - return; -} - -void template_free_func (void *vo, int is_error) -{ - struct instance *o = vo; - - // free dummy event lock - BEventLock_Free(&o->lock); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - command_template_die(&o->cti); -} - -static struct NCDModule modules[] = { - { - .type = "run", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_run= { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/runonce.c b/external/badvpn_dns/ncd/modules/runonce.c deleted file mode 100644 index bd7cea4..0000000 --- a/external/badvpn_dns/ncd/modules/runonce.c +++ /dev/null @@ -1,331 +0,0 @@ -/** - * @file runonce.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Imperative program execution module. On initialization, starts the process. - * Goes to UP state when the process terminates. When requested to die, waits for - * the process to terminate if it's running, optionally sending SIGTERM. - * - * Synopsis: runonce(list(string) cmd, [list opts]) - * Arguments: - * cmd - Command to run on startup. The first element is the full path - * to the executable, other elements are command line arguments (excluding - * the zeroth argument). - * opts - Map of options: - * "term_on_deinit":"true" - If we get a deinit request while the process is - * running, send it SIGTERM. - * "keep_stdout":"true" - Start the program with the same stdout as the NCD process. - * "keep_stderr":true" - Start the program with the same stderr as the NCD process. - * "do_setsid":"true" - Call setsid() in the child before exec. This is needed to - * start the 'agetty' program. - * "username":username_string - Start the process under the permissions of the - * specified user. - * Variables: - * string exit_status - if the program exited normally, the non-negative exit code, otherwise -1 - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <misc/cmdline.h> -#include <misc/strdup.h> -#include <system/BProcess.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/NCDBProcessOpts.h> - -#include <generated/blog_channel_ncd_runonce.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_RUNNING 1 -#define STATE_RUNNING_DIE 2 -#define STATE_FINISHED 3 - -struct instance { - NCDModuleInst *i; - int term_on_deinit; - int state; - BProcess process; - int exit_status; -}; - -static void instance_free (struct instance *o); - -static int build_cmdline (NCDModuleInst *i, NCDValRef cmd_arg, char **exec, CmdLine *cl) -{ - ASSERT(!NCDVal_IsInvalid(cmd_arg)) - - if (!NCDVal_IsList(cmd_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - size_t count = NCDVal_ListCount(cmd_arg); - - // read exec - if (count == 0) { - ModuleLog(i, BLOG_ERROR, "missing executable name"); - goto fail0; - } - NCDValRef exec_arg = NCDVal_ListGet(cmd_arg, 0); - if (!NCDVal_IsStringNoNulls(exec_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - if (!(*exec = ncd_strdup(exec_arg))) { - ModuleLog(i, BLOG_ERROR, "strdup failed"); - goto fail0; - } - - // start cmdline - if (!CmdLine_Init(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed"); - goto fail1; - } - - // add header - if (!CmdLine_Append(cl, *exec)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed"); - goto fail2; - } - - // add additional arguments - for (size_t j = 1; j < count; j++) { - NCDValRef arg = NCDVal_ListGet(cmd_arg, j); - - if (!NCDVal_IsStringNoNulls(arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail2; - } - - b_cstring arg_cstr = NCDVal_StringCstring(arg); - if (!CmdLine_AppendCstring(cl, arg_cstr, 0, arg_cstr.length)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_AppendCstring failed"); - goto fail2; - } - } - - // finish - if (!CmdLine_Finish(cl)) { - ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed"); - goto fail2; - } - - return 1; - -fail2: - CmdLine_Free(cl); -fail1: - free(*exec); -fail0: - return 0; -} - -static void process_handler (struct instance *o, int normally, uint8_t normally_exit_status) -{ - ASSERT(o->state == STATE_RUNNING || o->state == STATE_RUNNING_DIE) - - // free process - BProcess_Free(&o->process); - - // if we were requested to die, die now - if (o->state == STATE_RUNNING_DIE) { - instance_free(o); - return; - } - - // remember exit status - o->exit_status = (normally ? normally_exit_status : -1); - - // set state - o->state = STATE_FINISHED; - - // set up - NCDModuleInst_Backend_Up(o->i); -} - -static int opts_func_unknown (void *user, NCDValRef key, NCDValRef val) -{ - struct instance *o = user; - - if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "term_on_deinit")) { - o->term_on_deinit = ncd_read_boolean(val); - return 1; - } - - return 0; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // init arguments - o->term_on_deinit = 0; - - // read arguments - NCDValRef cmd_arg; - NCDValRef opts_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &cmd_arg) && !NCDVal_ListRead(params->args, 2, &cmd_arg, &opts_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - NCDBProcessOpts opts; - - // deprecated options format - if (!NCDVal_IsInvalid(opts_arg) && NCDVal_IsList(opts_arg)) { - int keep_stdout = 0; - int keep_stderr = 0; - int do_setsid = 0; - - // read options - size_t count = NCDVal_IsInvalid(opts_arg) ? 0 : NCDVal_ListCount(opts_arg); - for (size_t j = 0; j < count; j++) { - NCDValRef opt = NCDVal_ListGet(opts_arg, j); - - // read name - if (!NCDVal_IsString(opt)) { - ModuleLog(o->i, BLOG_ERROR, "wrong option name type"); - goto fail0; - } - - if (NCDVal_StringEquals(opt, "term_on_deinit")) { - o->term_on_deinit = 1; - } - else if (NCDVal_StringEquals(opt, "keep_stdout")) { - keep_stdout = 1; - } - else if (NCDVal_StringEquals(opt, "keep_stderr")) { - keep_stderr = 1; - } - else if (NCDVal_StringEquals(opt, "do_setsid")) { - do_setsid = 1; - } - else { - ModuleLog(o->i, BLOG_ERROR, "unknown option name"); - goto fail0; - } - } - - NCDBProcessOpts_InitOld(&opts, keep_stdout, keep_stderr, do_setsid); - } else { - if (!NCDBProcessOpts_Init(&opts, opts_arg, opts_func_unknown, o, i, BLOG_CURRENT_CHANNEL)) { - goto fail0; - } - } - - // build cmdline - char *exec; - CmdLine cl; - if (!build_cmdline(o->i, cmd_arg, &exec, &cl)) { - NCDBProcessOpts_Free(&opts); - goto fail0; - } - - // start process - struct BProcess_params p_params = NCDBProcessOpts_GetParams(&opts); - if (!BProcess_Init2(&o->process, o->i->params->iparams->manager, (BProcess_handler)process_handler, o, exec, CmdLine_Get(&cl), p_params)) { - ModuleLog(i, BLOG_ERROR, "BProcess_Init failed"); - CmdLine_Free(&cl); - free(exec); - NCDBProcessOpts_Free(&opts); - goto fail0; - } - - CmdLine_Free(&cl); - free(exec); - NCDBProcessOpts_Free(&opts); - - // set state - o->state = STATE_RUNNING; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(o->state != STATE_RUNNING_DIE) - - if (o->state == STATE_FINISHED) { - instance_free(o); - return; - } - - // send SIGTERM if requested - if (o->term_on_deinit) { - BProcess_Terminate(&o->process); - } - - o->state = STATE_RUNNING_DIE; -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->state == STATE_FINISHED) - - if (!strcmp(name, "exit_status")) { - char str[30]; - snprintf(str, sizeof(str), "%d", o->exit_status); - - *out = NCDVal_NewString(mem, str); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "runonce", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_runonce = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/sleep.c b/external/badvpn_dns/ncd/modules/sleep.c deleted file mode 100644 index a139aa9..0000000 --- a/external/badvpn_dns/ncd/modules/sleep.c +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file sleep.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * sleep(string ms_start [, string ms_stop]) - * - * Description: - * On init, sleeps 'ms_start' milliseconds then goes up, or goes up immediately - * if 'ms_start' is an empty string. - * On deinit, sleeps 'ms_stop' milliseconds then dies, or dies immediately if - * 'ms_stop' is an empty string or is not provided. If a deinit is requested while - * the init sleep is still in progress, the init sleep is aborted and the deinit - * sleep is started immediately (if any). - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <inttypes.h> -#include <limits.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_sleep.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - btime_t ms_stop; - BTimer timer; - int dying; -}; - -static void instance_free (struct instance *o); - -static void timer_handler (void *vo) -{ - struct instance *o = vo; - - if (!o->dying) { - // signal up - NCDModuleInst_Backend_Up(o->i); - } else { - // die - instance_free(o); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef ms_start_arg; - NCDValRef ms_stop_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &ms_start_arg) && - !NCDVal_ListRead(params->args, 2, &ms_start_arg, &ms_stop_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(ms_start_arg) || (!NCDVal_IsInvalid(ms_stop_arg) && !NCDVal_IsString(ms_stop_arg))) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - uintmax_t ms; - btime_t ms_start; - - if (NCDVal_StringEqualsId(ms_start_arg, NCD_STRING_EMPTY, i->params->iparams->string_index)) { - ms_start = -1; - } else { - if (!ncd_read_uintmax(ms_start_arg, &ms) || ms > INT64_MAX) { - ModuleLog(o->i, BLOG_ERROR, "wrong start time"); - goto fail0; - } - ms_start = ms; - } - - if (NCDVal_IsInvalid(ms_stop_arg) || NCDVal_StringEqualsId(ms_stop_arg, NCD_STRING_EMPTY, i->params->iparams->string_index)) { - o->ms_stop = -1; - } else { - if (!ncd_read_uintmax(ms_stop_arg, &ms) || ms > INT64_MAX) { - ModuleLog(o->i, BLOG_ERROR, "wrong stop time"); - goto fail0; - } - o->ms_stop = ms; - } - - // init timer - BTimer_Init(&o->timer, 0, timer_handler, o); - - // set not dying - o->dying = 0; - - if (ms_start < 0) { - // go up - NCDModuleInst_Backend_Up(i); - } else { - // set timer - BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, ms_start); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o) -{ - // free timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - if (o->ms_stop < 0) { - // die immediately - instance_free(o); - return; - } - - // set dying - o->dying = 1; - - // set timer - BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, o->ms_stop); -} - -static struct NCDModule modules[] = { - { - .type = "sleep", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sleep = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/socket.c b/external/badvpn_dns/ncd/modules/socket.c deleted file mode 100644 index 59ca8d7..0000000 --- a/external/badvpn_dns/ncd/modules/socket.c +++ /dev/null @@ -1,1057 +0,0 @@ -/** - * @file socket.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * sys.socket sys.connect(string addr [, map options]) - * - * Options: - * "read_size" - the maximum number of bytes that can be read by a single - * read() call. Must be greater than zero. Greater values may improve - * performance, but will increase memory usage. Default: 8192. - * - * Variables: - * string is_error - "true" if there was an error with the connection, - * "false" if not - * - * Description: - * Attempts to establish a connection to a server. The address should be - * in one of the following forms: - * - {"tcp", {"ipv4", ipv4_address, port_number}}, - * - {"tcp", {"ipv6", ipv6_address, port_number}}, - * - {"unix", socket_path}. - * When the connection attempt is finished, the sys.connect() statement goes - * up, and the 'is_error' variable should be used to check for connection - * failure. If there was no error, the read(), write() and close() methods - * can be used to work with the connection. - * If an error occurs after the connection has been established, the - * sys.connect() statement will automatically trigger backtracking, and the - * 'is_error' variable will be changed to "true". This means that all - * errors with the connection can be handled at the place of sys.connect(), - * and no special care is normally needed to handle error in read() and - * write(). - * WARNING: when you're not trying to either send or receive data, the - * connection may be unable to detect any events with the connection. - * You should never be neither sending nor receiving for an indefinite time. - * - * Synopsis: - * sys.socket::read() - * - * Variables: - * string (empty) - some data received from the socket, or empty on EOF - * string not_eof - "true" if EOF was not encountered, "false" if it was - * - * Description: - * Receives data from the connection. If EOF was encountered (remote host - * has closed the connection), this returns no data. Otherwise it returns - * at least one byte. - * WARNING: after you receive EOF from a sys.listen() type socket, is is - * your responsibility to call close() eventually, else the cline process - * may remain alive indefinitely. - * WARNING: this may return an arbitrarily small chunk of data. There is - * no significance to the size of the chunks. Correct code will behave - * the same no matter how the incoming data stream is split up. - * WARNING: if a read() is terminated while it is still in progress, i.e. - * has not gone up yet, then the connection is automatically closed, as - * if close() was called. - * - * Synopsis: - * sys.socket::write(string data) - * - * Description: - * Sends data to the connection. - * WARNING: this may block if the operating system's internal send buffer - * is full. Be careful not to enter a deadlock where both ends of the - * connection are trying to send data to the other, but neither is trying - * to receive any data. - * WARNING: if a write() is terminated while it is still in progress, i.e. - * has not gone up yet, then the connection is automatically closed, as - * if close() was called. - * - * Synopsis: - * sys.socket::close() - * - * Description: - * Closes the connection. After this, any further read(), write() or close() - * will trigger an error with the interpreter. For client sockets created - * via sys.listen(), this will immediately trigger termination of the client - * process. - * - * Synopsis: - * sys.listen(string address, string client_template, list args [, map options]) - * - * Options: - * "read_size" - the maximum number of bytes that can be read by a single - * read() call. Must be greater than zero. Greater values may improve - * performance, but will increase memory usage. Default: 8192. - * - * Variables: - * string is_error - "true" if listening failed to inittialize, "false" if - * not - * - * Special objects and variables in client_template: - * sys.socket _socket - the socket object for the client - * string _socket.client_addr - the address of the client. The form is - * like the second part of the sys.connect() address format, e.g. - * {"ipv4", "1.2.3.4", "4000"}. - * - * Description: - * Starts listening on the specified address. The 'is_error' variable - * reflects the success of listening initiation. If listening succeeds, - * then for every client that connects, a process is automatically created - * from the template specified by 'client_template', and the 'args' list - * is used as template arguments. Inside such processes, a special object - * '_socket' is available, which represents the connection, and supports - * the same methods as sys.connect(), i.e. read(), write() and close(). - * When an error occurs with the connection, the socket is automatically - * closed, triggering process termination. - */ - -#include <stdlib.h> -#include <limits.h> -#include <stdarg.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/LinkedList0.h> -#include <system/BConnection.h> -#include <system/BConnectionGeneric.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/address_utils.h> -#include <ncd/extra/NCDBuf.h> - -#include <generated/blog_channel_ncd_socket.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -#define CONNECTION_TYPE_CONNECT 1 -#define CONNECTION_TYPE_LISTEN 2 - -#define CONNECTION_STATE_CONNECTING 1 -#define CONNECTION_STATE_ESTABLISHED 2 -#define CONNECTION_STATE_ERROR 3 -#define CONNECTION_STATE_ABORTED 4 - -#define DEFAULT_READ_BUF_SIZE 8192 - -struct connection { - union { - struct { - NCDModuleInst *i; - BConnector connector; - size_t read_buf_size; - } connect; - struct { - struct listen_instance *listen_inst; - LinkedList0Node clients_list_node; - BAddr addr; - NCDModuleProcess process; - } listen; - }; - - unsigned int type:2; - unsigned int state:3; - unsigned int recv_closed:1; - BConnection connection; - NCDBufStore store; - struct read_instance *read_inst; - struct write_instance *write_inst; -}; - -struct read_instance { - NCDModuleInst *i; - struct connection *con_inst; - NCDBuf *buf; - size_t read_size; -}; - -struct write_instance { - NCDModuleInst *i; - struct connection *con_inst; - b_cstring cstr; - size_t pos; -}; - -struct listen_instance { - NCDModuleInst *i; - unsigned int have_error:1; - unsigned int dying:1; - size_t read_buf_size; - NCDValRef client_template; - NCDValRef client_template_args; - BListener listener; - LinkedList0 clients_list; -}; - -enum {STRING_SOCKET, STRING_SYS_SOCKET, STRING_CLIENT_ADDR}; - -static const char *strings[] = { - "_socket", "sys.socket", "client_addr", NULL -}; - -static int parse_options (NCDModuleInst *i, NCDValRef options, size_t *out_read_size); -static void connection_log (struct connection *o, int level, const char *fmt, ...); -static void connection_free_connection (struct connection *o); -static void connection_error (struct connection *o); -static void connection_abort (struct connection *o); -static void connection_connector_handler (void *user, int is_error); -static void connection_connection_handler (void *user, int event); -static void connection_send_handler_done (void *user, int data_len); -static void connection_recv_handler_done (void *user, int data_len); -static void connection_process_handler (struct NCDModuleProcess_s *process, int event); -static int connection_process_func_getspecialobj (struct NCDModuleProcess_s *process, NCD_string_id_t name, NCDObject *out_object); -static int connection_process_socket_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); -static void listen_listener_handler (void *user); - -static int parse_options (NCDModuleInst *i, NCDValRef options, size_t *out_read_size) -{ - ASSERT(out_read_size) - - *out_read_size = DEFAULT_READ_BUF_SIZE; - - if (!NCDVal_IsInvalid(options)) { - if (!NCDVal_IsMap(options)) { - ModuleLog(i, BLOG_ERROR, "options argument is not a map"); - return 0; - } - - int num_recognized = 0; - NCDValRef value; - - if (!NCDVal_IsInvalid(value = NCDVal_MapGetValue(options, "read_size"))) { - uintmax_t read_size; - if (!NCDVal_IsString(value) || !ncd_read_uintmax(value, &read_size) || read_size > SIZE_MAX || read_size == 0) { - ModuleLog(i, BLOG_ERROR, "wrong read_size"); - return 0; - } - num_recognized++; - *out_read_size = read_size; - } - - if (NCDVal_MapCount(options) > num_recognized) { - ModuleLog(i, BLOG_ERROR, "unrecognized options present"); - return 0; - } - } - - return 1; -} - -static void connection_log (struct connection *o, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - - switch (o->type) { - case CONNECTION_TYPE_CONNECT: { - NCDModuleInst_Backend_LogVarArg(o->connect.i, BLOG_CURRENT_CHANNEL, level, fmt, vl); - } break; - - case CONNECTION_TYPE_LISTEN: { - if (BLog_WouldLog(BLOG_CURRENT_CHANNEL, level)) { - BLog_Begin(); - o->listen.listen_inst->i->params->logfunc(o->listen.listen_inst->i); - char addr_str[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&o->listen.addr, addr_str); - BLog_Append("client %s: ", addr_str); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(BLOG_CURRENT_CHANNEL, level); - } - } break; - - default: ASSERT(0); - } - - va_end(vl); -} - -static void connection_free_connection (struct connection *o) -{ - // disconnect read instance - if (o->read_inst) { - ASSERT(o->read_inst->con_inst == o) - o->read_inst->con_inst = NULL; - } - - // disconnect write instance - if (o->write_inst) { - ASSERT(o->write_inst->con_inst == o) - o->write_inst->con_inst = NULL; - } - - // free connection interfaces - BConnection_RecvAsync_Free(&o->connection); - BConnection_SendAsync_Free(&o->connection); - - // free connection - BConnection_Free(&o->connection); - - // free store - NCDBufStore_Free(&o->store); -} - -static void connection_error (struct connection *o) -{ - ASSERT(o->state == CONNECTION_STATE_CONNECTING || - o->state == CONNECTION_STATE_ESTABLISHED) - - // for listen clients, we don't report errors directly, - // we just terminate the client process - if (o->type == CONNECTION_TYPE_LISTEN) { - ASSERT(o->state != CONNECTION_STATE_CONNECTING) - connection_abort(o); - return; - } - - // free connector - if (o->state == CONNECTION_STATE_CONNECTING) { - BConnector_Free(&o->connect.connector); - } - - // free connection resources - if (o->state == CONNECTION_STATE_ESTABLISHED) { - connection_free_connection(o); - } - - // trigger reporting of failure - if (o->state == CONNECTION_STATE_ESTABLISHED) { - NCDModuleInst_Backend_Down(o->connect.i); - } - NCDModuleInst_Backend_Up(o->connect.i); - - // set state - o->state = CONNECTION_STATE_ERROR; -} - -static void connection_abort (struct connection *o) -{ - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - - // free connection resources - connection_free_connection(o); - - // if this is a listen connection, terminate client process - if (o->type == CONNECTION_TYPE_LISTEN) { - NCDModuleProcess_Terminate(&o->listen.process); - } - - // set state - o->state = CONNECTION_STATE_ABORTED; -} - -static void connection_connector_handler (void *user, int is_error) -{ - struct connection *o = user; - ASSERT(o->type == CONNECTION_TYPE_CONNECT) - ASSERT(o->state == CONNECTION_STATE_CONNECTING) - - // check error - if (is_error) { - connection_log(o, BLOG_ERROR, "connection failed"); - goto fail; - } - - // init connection - if (!BConnection_Init(&o->connection, BConnection_source_connector(&o->connect.connector), o->connect.i->params->iparams->reactor, o, connection_connection_handler)) { - connection_log(o, BLOG_ERROR, "BConnection_Init failed"); - goto fail; - } - - // init connection interfaces - BConnection_SendAsync_Init(&o->connection); - BConnection_RecvAsync_Init(&o->connection); - - // setup send/recv done callbacks - StreamPassInterface_Sender_Init(BConnection_SendAsync_GetIf(&o->connection), connection_send_handler_done, o); - StreamRecvInterface_Receiver_Init(BConnection_RecvAsync_GetIf(&o->connection), connection_recv_handler_done, o); - - // init store - NCDBufStore_Init(&o->store, o->connect.read_buf_size); - - // set not reading, not writing, recv not closed - o->read_inst = NULL; - o->write_inst = NULL; - o->recv_closed = 0; - - // free connector - BConnector_Free(&o->connect.connector); - - // set state - o->state = CONNECTION_STATE_ESTABLISHED; - - // go up - NCDModuleInst_Backend_Up(o->connect.i); - return; - -fail: - connection_error(o); -} - -static void connection_connection_handler (void *user, int event) -{ - struct connection *o = user; - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - ASSERT(event == BCONNECTION_EVENT_RECVCLOSED || event == BCONNECTION_EVENT_ERROR) - ASSERT(event != BCONNECTION_EVENT_RECVCLOSED || !o->recv_closed) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - // if we have read operation, make it finish with eof - if (o->read_inst) { - ASSERT(o->read_inst->con_inst == o) - o->read_inst->con_inst = NULL; - o->read_inst->read_size = 0; - NCDModuleInst_Backend_Up(o->read_inst->i); - o->read_inst = NULL; - } - - // set recv closed - o->recv_closed = 1; - return; - } - - connection_log(o, BLOG_ERROR, "connection error"); - - // handle error - connection_error(o); -} - -static void connection_send_handler_done (void *user, int data_len) -{ - struct connection *o = user; - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - ASSERT(o->write_inst) - ASSERT(o->write_inst->con_inst == o) - ASSERT(o->write_inst->pos < o->write_inst->cstr.length) - ASSERT(data_len > 0) - ASSERT(data_len <= o->write_inst->cstr.length - o->write_inst->pos) - - struct write_instance *wr = o->write_inst; - - // update send state - wr->pos += data_len; - - // if there's more to send, send again - if (wr->pos < wr->cstr.length) { - size_t chunk_len; - const char *chunk_data = b_cstring_get(wr->cstr, wr->pos, wr->cstr.length - wr->pos, &chunk_len); - size_t to_send = (chunk_len > INT_MAX ? INT_MAX : chunk_len); - StreamPassInterface_Sender_Send(BConnection_SendAsync_GetIf(&o->connection), (uint8_t *)chunk_data, to_send); - return; - } - - // finish write operation - wr->con_inst = NULL; - NCDModuleInst_Backend_Up(wr->i); - o->write_inst = NULL; -} - -static void connection_recv_handler_done (void *user, int data_len) -{ - struct connection *o = user; - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - ASSERT(o->read_inst) - ASSERT(o->read_inst->con_inst == o) - ASSERT(!o->recv_closed) - ASSERT(data_len > 0) - ASSERT(data_len <= NCDBufStore_BufSize(&o->store)) - - struct read_instance *re = o->read_inst; - - // finish read operation - re->con_inst = NULL; - re->read_size = data_len; - NCDModuleInst_Backend_Up(re->i); - o->read_inst = NULL; -} - -static void connection_process_handler (struct NCDModuleProcess_s *process, int event) -{ - struct connection *o = UPPER_OBJECT(process, struct connection, listen.process); - ASSERT(o->type == CONNECTION_TYPE_LISTEN) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(o->state == CONNECTION_STATE_ESTABLISHED) - NCDModuleProcess_Continue(&o->listen.process); - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == CONNECTION_STATE_ABORTED) - - struct listen_instance *li = o->listen.listen_inst; - ASSERT(!li->have_error) - - // remove from clients list - LinkedList0_Remove(&li->clients_list, &o->listen.clients_list_node); - - // free process - NCDModuleProcess_Free(&o->listen.process); - - // free connection structure - free(o); - - // if listener is dying and this was the last process, have it die - if (li->dying && LinkedList0_IsEmpty(&li->clients_list)) { - NCDModuleInst_Backend_Dead(li->i); - } - } break; - - default: ASSERT(0); - } -} - -static int connection_process_func_getspecialobj (struct NCDModuleProcess_s *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct connection *o = UPPER_OBJECT(process, struct connection, listen.process); - ASSERT(o->type == CONNECTION_TYPE_LISTEN) - - if (name == ModuleString(o->listen.listen_inst->i, STRING_SOCKET)) { - *out_object = NCDObject_Build(ModuleString(o->listen.listen_inst->i, STRING_SYS_SOCKET), o, connection_process_socket_obj_func_getvar, NCDObject_no_getobj); - return 1; - } - - return 0; -} - -static int connection_process_socket_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) -{ - struct connection *o = NCDObject_DataPtr(obj); - ASSERT(o->type == CONNECTION_TYPE_LISTEN) - - if (name == ModuleString(o->listen.listen_inst->i, STRING_CLIENT_ADDR)) { - *out_value = ncd_make_baddr(o->listen.addr, mem); - if (NCDVal_IsInvalid(*out_value)) { - connection_log(o, BLOG_ERROR, "ncd_make_baddr failed"); - } - return 1; - } - - return 0; -} - -static void listen_listener_handler (void *user) -{ - struct listen_instance *o = user; - ASSERT(!o->have_error) - ASSERT(!o->dying) - - // allocate connection structure - struct connection *con = malloc(sizeof(*con)); - if (!con) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set connection type and listen instance - con->type = CONNECTION_TYPE_LISTEN; - con->listen.listen_inst = o; - - // init connection - if (!BConnection_Init(&con->connection, BConnection_source_listener(&o->listener, &con->listen.addr), o->i->params->iparams->reactor, con, connection_connection_handler)) { - ModuleLog(o->i, BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // init connection interfaces - BConnection_SendAsync_Init(&con->connection); - BConnection_RecvAsync_Init(&con->connection); - - // setup send/recv done callbacks - StreamPassInterface_Sender_Init(BConnection_SendAsync_GetIf(&con->connection), connection_send_handler_done, con); - StreamRecvInterface_Receiver_Init(BConnection_RecvAsync_GetIf(&con->connection), connection_recv_handler_done, con); - - // init process - if (!NCDModuleProcess_InitValue(&con->listen.process, o->i, o->client_template, o->client_template_args, connection_process_handler)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_InitValue failed"); - goto fail2; - } - - // set special objects callback - NCDModuleProcess_SetSpecialFuncs(&con->listen.process, connection_process_func_getspecialobj); - - // insert to clients list - LinkedList0_Prepend(&o->clients_list, &con->listen.clients_list_node); - - // init store - NCDBufStore_Init(&con->store, o->read_buf_size); - - // set not reading, not writing, recv not closed - con->read_inst = NULL; - con->write_inst = NULL; - con->recv_closed = 0; - - // set state - con->state = CONNECTION_STATE_ESTABLISHED; - return; - -fail2: - BConnection_RecvAsync_Free(&con->connection); - BConnection_SendAsync_Free(&con->connection); - BConnection_Free(&con->connection); -fail1: - free(con); -fail0: - return; -} - -static void connect_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct connection *o = vo; - o->type = CONNECTION_TYPE_CONNECT; - o->connect.i = i; - - // pass connection pointer to methods so the same methods can work for - // listen type connections - NCDModuleInst_Backend_PassMemToMethods(i); - - // read arguments - NCDValRef address_arg; - NCDValRef options_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &address_arg) && - !NCDVal_ListRead(params->args, 2, &address_arg, &options_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // parse options - if (!parse_options(i, options_arg, &o->connect.read_buf_size)) { - goto fail0; - } - - // read address - struct BConnection_addr address; - if (!ncd_read_bconnection_addr(address_arg, &address)) { - ModuleLog(i, BLOG_ERROR, "wrong address"); - goto error; - } - - // init connector - if (!BConnector_InitGeneric(&o->connect.connector, address, i->params->iparams->reactor, o, connection_connector_handler)) { - ModuleLog(i, BLOG_ERROR, "BConnector_InitGeneric failed"); - goto error; - } - - // set state - o->state = CONNECTION_STATE_CONNECTING; - return; - -error: - // go up in error state - o->state = CONNECTION_STATE_ERROR; - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void connect_func_die (void *vo) -{ - struct connection *o = vo; - ASSERT(o->type == CONNECTION_TYPE_CONNECT) - - // free connector - if (o->state == CONNECTION_STATE_CONNECTING) { - BConnector_Free(&o->connect.connector); - } - - // free connection resources - if (o->state == CONNECTION_STATE_ESTABLISHED) { - connection_free_connection(o); - } - - NCDModuleInst_Backend_Dead(o->connect.i); -} - -static int connect_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct connection *o = vo; - ASSERT(o->type == CONNECTION_TYPE_CONNECT) - ASSERT(o->state != CONNECTION_STATE_CONNECTING) - - if (name == NCD_STRING_IS_ERROR) { - int is_error = (o->state == CONNECTION_STATE_ERROR); - *out = ncd_make_boolean(mem, is_error, o->connect.i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void read_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct read_instance *o = vo; - o->i = i; - - // read arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get connection - struct connection *con_inst = params->method_user; - - // check connection state - if (con_inst->state != CONNECTION_STATE_ESTABLISHED) { - ModuleLog(i, BLOG_ERROR, "connection is not established"); - goto fail0; - } - - // check if there's already a read in progress - if (con_inst->read_inst) { - ModuleLog(i, BLOG_ERROR, "read is already in progress"); - goto fail0; - } - - // get buffer - o->buf = NCDBufStore_GetBuf(&con_inst->store); - if (!o->buf) { - ModuleLog(i, BLOG_ERROR, "NCDBufStore_GetBuf failed"); - goto fail0; - } - - // if eof was reached, go up immediately - if (con_inst->recv_closed) { - o->con_inst = NULL; - o->read_size = 0; - NCDModuleInst_Backend_Up(i); - return; - } - - // set connection - o->con_inst = con_inst; - - // register read operation in connection - con_inst->read_inst = o; - - // receive - size_t buf_size = NCDBufStore_BufSize(&con_inst->store); - int to_read = (buf_size > INT_MAX ? INT_MAX : buf_size); - StreamRecvInterface_Receiver_Recv(BConnection_RecvAsync_GetIf(&con_inst->connection), (uint8_t *)NCDBuf_Data(o->buf), to_read); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void read_func_die (void *vo) -{ - struct read_instance *o = vo; - - // if we're receiving, abort connection - if (o->con_inst) { - ASSERT(o->con_inst->state == CONNECTION_STATE_ESTABLISHED) - ASSERT(o->con_inst->read_inst == o) - connection_abort(o->con_inst); - } - - // release buffer - BRefTarget_Deref(NCDBuf_RefTarget(o->buf)); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int read_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct read_instance *o = vo; - ASSERT(!o->con_inst) - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewExternalString(mem, NCDBuf_Data(o->buf), o->read_size, NCDBuf_RefTarget(o->buf)); - return 1; - } - - if (name == NCD_STRING_NOT_EOF) { - *out = ncd_make_boolean(mem, (o->read_size != 0), o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void write_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct write_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef data_arg; - if (!NCDVal_ListRead(params->args, 1, &data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // get connection - struct connection *con_inst = params->method_user; - - // check connection state - if (con_inst->state != CONNECTION_STATE_ESTABLISHED) { - ModuleLog(i, BLOG_ERROR, "connection is not established"); - goto fail0; - } - - // check if there's already a write in progress - if (con_inst->write_inst) { - ModuleLog(i, BLOG_ERROR, "write is already in progress"); - goto fail0; - } - - // set send state - o->cstr = NCDVal_StringCstring(data_arg); - o->pos = 0; - - // if there's nothing to send, go up immediately - if (o->cstr.length == 0) { - o->con_inst = NULL; - NCDModuleInst_Backend_Up(i); - return; - } - - // set connection - o->con_inst = con_inst; - - // register write operation in connection - con_inst->write_inst = o; - - // send - size_t chunk_len; - const char *chunk_data = b_cstring_get(o->cstr, o->pos, o->cstr.length - o->pos, &chunk_len); - size_t to_send = (chunk_len > INT_MAX ? INT_MAX : chunk_len); - StreamPassInterface_Sender_Send(BConnection_SendAsync_GetIf(&con_inst->connection), (uint8_t *)chunk_data, to_send); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void write_func_die (void *vo) -{ - struct write_instance *o = vo; - - // if we're sending, abort connection - if (o->con_inst) { - ASSERT(o->con_inst->state == CONNECTION_STATE_ESTABLISHED) - ASSERT(o->con_inst->write_inst == o) - connection_abort(o->con_inst); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void close_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get connection - struct connection *con_inst = params->method_user; - - // check connection state - if (con_inst->state != CONNECTION_STATE_ESTABLISHED) { - ModuleLog(i, BLOG_ERROR, "connection is not established"); - goto fail0; - } - - // abort - connection_abort(con_inst); - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void listen_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct listen_instance *o = vo; - o->i = i; - - // read arguments - NCDValRef address_arg; - NCDValRef client_template_arg; - NCDValRef args_arg; - NCDValRef options_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 3, &address_arg, &client_template_arg, &args_arg) && - !NCDVal_ListRead(params->args, 4, &address_arg, &client_template_arg, &args_arg, &options_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(client_template_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // parse options - if (!parse_options(i, options_arg, &o->read_buf_size)) { - goto fail0; - } - - // remember client template and arguments - o->client_template = client_template_arg; - o->client_template_args = args_arg; - - // set no error, not dying - o->have_error = 0; - o->dying = 0; - - // read address - struct BConnection_addr address; - if (!ncd_read_bconnection_addr(address_arg, &address)) { - ModuleLog(i, BLOG_ERROR, "wrong address"); - goto error; - } - - // init listener - if (!BListener_InitGeneric(&o->listener, address, i->params->iparams->reactor, o, listen_listener_handler)) { - ModuleLog(i, BLOG_ERROR, "BListener_InitGeneric failed"); - goto error; - } - - // init clients list - LinkedList0_Init(&o->clients_list); - - // go up - NCDModuleInst_Backend_Up(i); - return; - -error: - // go up with error - o->have_error = 1; - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void listen_func_die (void *vo) -{ - struct listen_instance *o = vo; - ASSERT(!o->dying) - - // free listener - if (!o->have_error) { - BListener_Free(&o->listener); - } - - // if we have no clients, die right away - if (o->have_error || LinkedList0_IsEmpty(&o->clients_list)) { - NCDModuleInst_Backend_Dead(o->i); - return; - } - - // set dying - o->dying = 1; - - // abort all clients and wait for them - for (LinkedList0Node *ln = LinkedList0_GetFirst(&o->clients_list); ln; ln = LinkedList0Node_Next(ln)) { - struct connection *con = UPPER_OBJECT(ln, struct connection, listen.clients_list_node); - ASSERT(con->type == CONNECTION_TYPE_LISTEN) - ASSERT(con->listen.listen_inst == o) - ASSERT(con->state == CONNECTION_STATE_ESTABLISHED || con->state == CONNECTION_STATE_ABORTED) - - if (con->state != CONNECTION_STATE_ABORTED) { - connection_abort(con); - } - } -} - -static int listen_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct listen_instance *o = vo; - - if (name == NCD_STRING_IS_ERROR) { - *out = ncd_make_boolean(mem, o->have_error, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "sys.connect", - .base_type = "sys.socket", - .func_new2 = connect_func_new, - .func_die = connect_func_die, - .func_getvar2 = connect_func_getvar, - .alloc_size = sizeof(struct connection), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.socket::read", - .func_new2 = read_func_new, - .func_die = read_func_die, - .func_getvar2 = read_func_getvar, - .alloc_size = sizeof(struct read_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.socket::write", - .func_new2 = write_func_new, - .func_die = write_func_die, - .alloc_size = sizeof(struct write_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.socket::close", - .func_new2 = close_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.listen", - .func_new2 = listen_func_new, - .func_die = listen_func_die, - .func_getvar2 = listen_func_getvar, - .alloc_size = sizeof(struct listen_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_socket = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/spawn.c b/external/badvpn_dns/ncd/modules/spawn.c deleted file mode 100644 index 4f68670..0000000 --- a/external/badvpn_dns/ncd/modules/spawn.c +++ /dev/null @@ -1,410 +0,0 @@ -/** - * @file spawn.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module which starts a process from a process template on initialization, and - * stops it on deinitialization. - * - * Synopsis: - * spawn(string template_name, list args) - * - * Description: - * On initialization, creates a new process from the template named - * 'template_name', with arguments 'args'. On deinitialization, initiates termination - * of the process and waits for it to terminate. The process can access objects - * as seen from 'spawn' via the _caller special object. - * - * Synopsis: - * spawn::join() - * - * Description: - * A join() on a spawn() is like a depend() on a provide() which is located at the - * end of the spawned process. - * - * Variables: - * Exposes objects from the spawned process. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/LinkedList0.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_spawn.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_WORKING 1 -#define STATE_UP 2 -#define STATE_WAITING 3 -#define STATE_WAITING_TERMINATING 4 -#define STATE_TERMINATING 5 - -struct instance { - NCDModuleInst *i; - NCDModuleProcess process; - LinkedList0 clean_list; - LinkedList0 dirty_list; - int state; -}; - -struct join_instance { - NCDModuleInst *i; - struct instance *spawn; - LinkedList0Node list_node; - int is_dirty; -}; - -static void assert_dirty_state (struct instance *o); -static void process_handler_event (NCDModuleProcess *process, int event); -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static void bring_joins_down (struct instance *o); -static void continue_working (struct instance *o); -static void continue_terminating (struct instance *o); -static void instance_free (struct instance *o); - -static void assert_dirty_state (struct instance *o) -{ - ASSERT(!LinkedList0_IsEmpty(&o->dirty_list) == (o->state == STATE_WAITING || o->state == STATE_WAITING_TERMINATING)) -} - -static void process_handler_event (NCDModuleProcess *process, int event) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - assert_dirty_state(o); - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == STATE_WORKING) - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // set state up - o->state = STATE_UP; - - // bring joins up - for (LinkedList0Node *ln = LinkedList0_GetFirst(&o->clean_list); ln; ln = LinkedList0Node_Next(ln)) { - struct join_instance *join = UPPER_OBJECT(ln, struct join_instance, list_node); - ASSERT(join->spawn == o) - ASSERT(!join->is_dirty) - NCDModuleInst_Backend_Up(join->i); - } - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(o->state == STATE_UP) - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // bring joins down, moving them to the dirty list - bring_joins_down(o); - - // set state waiting - o->state = STATE_WAITING; - - // if we have no joins, continue immediately - if (LinkedList0_IsEmpty(&o->dirty_list)) { - continue_working(o); - return; - } - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == STATE_TERMINATING) - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // die finally - instance_free(o); - return; - } break; - - default: ASSERT(0); - } -} - -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj); - return 1; - } - - return 0; -} - -static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = NCDObject_DataPtr(obj); - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static void bring_joins_down (struct instance *o) -{ - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&o->clean_list)) { - struct join_instance *join = UPPER_OBJECT(ln, struct join_instance, list_node); - ASSERT(join->spawn == o) - ASSERT(!join->is_dirty) - NCDModuleInst_Backend_Down(join->i); - LinkedList0_Remove(&o->clean_list, &join->list_node); - LinkedList0_Prepend(&o->dirty_list, &join->list_node); - join->is_dirty = 1; - } -} - -static void continue_working (struct instance *o) -{ - ASSERT(o->state == STATE_WAITING) - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // continue process - NCDModuleProcess_Continue(&o->process); - - // set state working - o->state = STATE_WORKING; -} - -static void continue_terminating (struct instance *o) -{ - ASSERT(o->state == STATE_WAITING_TERMINATING) - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // request process to terminate - NCDModuleProcess_Terminate(&o->process); - - // set state terminating - o->state = STATE_TERMINATING; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef template_name_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 2, &template_name_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(template_name_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // signal up. - // Do it before creating the process so that the process starts initializing before our own process continues. - NCDModuleInst_Backend_Up(o->i); - - // create process - if (!NCDModuleProcess_InitValue(&o->process, o->i, template_name_arg, args_arg, process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set object resolution function - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj); - - // init lists - LinkedList0_Init(&o->clean_list); - LinkedList0_Init(&o->dirty_list); - - // set state working - o->state = STATE_WORKING; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o) -{ - ASSERT(LinkedList0_IsEmpty(&o->dirty_list)) - - // unlink joins - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&o->clean_list)) { - struct join_instance *join = UPPER_OBJECT(ln, struct join_instance, list_node); - ASSERT(join->spawn == o) - ASSERT(!join->is_dirty) - LinkedList0_Remove(&o->clean_list, &join->list_node); - join->spawn = NULL; - } - - // free process - NCDModuleProcess_Free(&o->process); - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(o->state != STATE_WAITING_TERMINATING) - ASSERT(o->state != STATE_TERMINATING) - assert_dirty_state(o); - - // bring joins down - if (o->state == STATE_UP) { - bring_joins_down(o); - } - - // set state waiting terminating - o->state = STATE_WAITING_TERMINATING; - - // start terminating now if possible - if (LinkedList0_IsEmpty(&o->dirty_list)) { - continue_terminating(o); - return; - } -} - -static void join_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct join_instance *o = vo; - o->i = i; - - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - o->spawn = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - assert_dirty_state(o->spawn); - - LinkedList0_Prepend(&o->spawn->clean_list, &o->list_node); - o->is_dirty = 0; - - if (o->spawn->state == STATE_UP) { - NCDModuleInst_Backend_Up(i); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void join_func_die (void *vo) -{ - struct join_instance *o = vo; - - if (o->spawn) { - assert_dirty_state(o->spawn); - - // remove from list - if (o->is_dirty) { - LinkedList0_Remove(&o->spawn->dirty_list, &o->list_node); - } else { - LinkedList0_Remove(&o->spawn->clean_list, &o->list_node); - } - - if (o->is_dirty && LinkedList0_IsEmpty(&o->spawn->dirty_list)) { - ASSERT(o->spawn->state == STATE_WAITING || o->spawn->state == STATE_WAITING_TERMINATING) - - if (o->spawn->state == STATE_WAITING) { - continue_working(o->spawn); - } else { - continue_terminating(o->spawn); - } - } - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int join_func_getobj (void *vo, NCD_string_id_t name, NCDObject *out) -{ - struct join_instance *o = vo; - - if (!o->spawn) { - return 0; - } - - return NCDModuleProcess_GetObj(&o->spawn->process, name, out); -} - -static void join_func_clean (void *vo) -{ - struct join_instance *o = vo; - - if (!(o->spawn && o->is_dirty)) { - return; - } - - assert_dirty_state(o->spawn); - ASSERT(o->spawn->state == STATE_WAITING || o->spawn->state == STATE_WAITING_TERMINATING) - - LinkedList0_Remove(&o->spawn->dirty_list, &o->list_node); - LinkedList0_Prepend(&o->spawn->clean_list, &o->list_node); - o->is_dirty = 0; - - if (LinkedList0_IsEmpty(&o->spawn->dirty_list)) { - if (o->spawn->state == STATE_WAITING) { - continue_working(o->spawn); - } else { - continue_terminating(o->spawn); - } - } -} - -static struct NCDModule modules[] = { - { - .type = "spawn", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "synchronous_process", // deprecated name - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "spawn::join", - .func_new2 = join_func_new, - .func_die = join_func_die, - .func_getobj = join_func_getobj, - .func_clean = join_func_clean, - .alloc_size = sizeof(struct join_instance), - .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_spawn = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/strcmp.c b/external/badvpn_dns/ncd/modules/strcmp.c deleted file mode 100644 index e648719..0000000 --- a/external/badvpn_dns/ncd/modules/strcmp.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file strcmp.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * String comparison module. - * - * Synopsis: strcmp(string str1, string str2) - * Variables: - * string (empty) - "true" if str1 and str2 are equal, "false" if not - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_strcmp.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - int result; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef str1_arg; - NCDValRef str2_arg; - if (!NCDVal_ListRead(params->args, 2, &str1_arg, &str2_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str1_arg) || !NCDVal_IsString(str2_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // compare - o->result = (NCDVal_Compare(str1_arg, str2_arg) == 0); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = ncd_make_boolean(mem, o->result, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "strcmp", - .func_new2 = func_new, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_strcmp = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/substr.c b/external/badvpn_dns/ncd/modules/substr.c deleted file mode 100644 index 6a50b0c..0000000 --- a/external/badvpn_dns/ncd/modules/substr.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file substr.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * substr(string str, string start [, string max]) - * - * Description: - * Extracts a substring from a string. The result is the longest substring which - * starts at the offset 'start' bytes into 'str', and is no longer than 'max' bytes. - * If 'max' is not provided, the result is the substring from the offset 'start' to - * the end. In any case, 'start' must not be greater than the length of 'str'. - */ - -#include <stddef.h> -#include <string.h> -#include <limits.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_substr.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct substr_instance { - NCDModuleInst *i; - const char *data; - size_t length; - int is_external; - BRefTarget *external_ref_target; -}; - -static void substr_func_new_common (void *vo, NCDModuleInst *i, const char *data, size_t length, int is_external, BRefTarget *external_ref_target) -{ - struct substr_instance *o = vo; - o->i = i; - - o->data = data; - o->length = length; - o->is_external = is_external; - o->external_ref_target = external_ref_target; - - NCDModuleInst_Backend_Up(i); -} - -static int substr_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct substr_instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - if (o->is_external) { - *out = NCDVal_NewExternalString(mem, o->data, o->length, o->external_ref_target); - } else { - *out = NCDVal_NewStringBin(mem, (const uint8_t *)o->data, o->length); - } - return 1; - } - - return 0; -} - -static void func_new_substr (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef str_arg; - NCDValRef start_arg; - NCDValRef max_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &str_arg, &start_arg) && - !NCDVal_ListRead(params->args, 3, &str_arg, &start_arg, &max_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(str_arg) || !NCDVal_IsString(start_arg) || - (!NCDVal_IsInvalid(max_arg) && !NCDVal_IsString(max_arg)) - ) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - uintmax_t start; - if (!ncd_read_uintmax(start_arg, &start) || start > SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "wrong size"); - goto fail0; - } - - uintmax_t max = SIZE_MAX; - if (!NCDVal_IsInvalid(max_arg)) { - if (!ncd_read_uintmax(max_arg, &max) || max > SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "wrong max"); - goto fail0; - } - } - - const char *str_data = NCDVal_StringData(str_arg); - size_t str_length = NCDVal_StringLength(str_arg); - - if (start > str_length) { - ModuleLog(i, BLOG_ERROR, "start is beyond the end of the string"); - goto fail0; - } - - const char *sub_data = str_data + start; - size_t sub_length = str_length - start; - if (sub_length > max) { - sub_length = max; - } - - int is_external = 0; - BRefTarget *external_ref_target = NULL; - - if (NCDVal_IsExternalString(str_arg)) { - is_external = 1; - external_ref_target = NCDVal_ExternalStringTarget(str_arg); - } - else if (NCDVal_IsIdString(str_arg)) { - is_external = 1; - } - - substr_func_new_common(vo, i, sub_data, sub_length, is_external, external_ref_target); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "substr", - .func_new2 = func_new_substr, - .func_getvar2 = substr_func_getvar, - .alloc_size = sizeof(struct substr_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_substr = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/sys_evdev.c b/external/badvpn_dns/ncd/modules/sys_evdev.c deleted file mode 100644 index d848a89..0000000 --- a/external/badvpn_dns/ncd/modules/sys_evdev.c +++ /dev/null @@ -1,348 +0,0 @@ -/** - * @file sys_evdev.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Linux event device module. - * - * Synopsis: sys.evdev(string device) - * Description: reports input events from a Linux event device. Transitions up when an event is - * detected, and goes down waiting for the next event when sys.evdev::nextevent() is called. - * Variables: - * string type - symbolic event type (e.g. EV_KEY, EV_REL, EV_ABS), corresponding to - * (struct input_event).type, or "unknown" - * string value - event value (signed integer), equal to (struct input_event).value - * string code_numeric - numeric event code (unsigned integer), equal to - * (struct input_event).code - * string code - symbolic event code (e.g. KEY_ESC. KEY_1, KEY_2, BTN_LEFT), corrresponding - * to (struct input_event).code, or "unknown" - * - * Synopsis: sys.evdev::nextevent() - * Description: makes the evdev module transition down in order to report the next event. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <linux/input.h> - -#include <misc/nonblocking.h> -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_sys_evdev.h> - -#include "linux_input_names.h" - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -struct instance { - NCDModuleInst *i; - int evdev_fd; - BFileDescriptor bfd; - int processing; - struct input_event event; -}; - -static void instance_free (struct instance *o, int is_error); - -enum {STRING_VALUE, STRING_CODE_NUMERIC, STRING_CODE}; - -static const char *strings[] = { - "value", "code_numeric", "code", NULL -}; - -#define MAKE_LOOKUP_FUNC(_name_) \ -static const char * evdev_##_name_##_to_str (uint16_t type) \ -{ \ - if (type >= (sizeof(_name_##_names) / sizeof(_name_##_names[0])) || !_name_##_names[type]) { \ - return "unknown"; \ - } \ - return _name_##_names[type]; \ -} - -MAKE_LOOKUP_FUNC(type) -MAKE_LOOKUP_FUNC(key) -MAKE_LOOKUP_FUNC(rel) -MAKE_LOOKUP_FUNC(abs) -MAKE_LOOKUP_FUNC(sw) -MAKE_LOOKUP_FUNC(msc) -MAKE_LOOKUP_FUNC(led) -MAKE_LOOKUP_FUNC(rep) -MAKE_LOOKUP_FUNC(snd) -MAKE_LOOKUP_FUNC(ffstatus) - -static void device_handler (struct instance *o, int events) -{ - if (o->processing) { - ModuleLog(o->i, BLOG_ERROR, "device error"); - instance_free(o, 1); - return; - } - - int res = read(o->evdev_fd, &o->event, sizeof(o->event)); - if (res < 0) { - ModuleLog(o->i, BLOG_ERROR, "read failed"); - instance_free(o, 1); - return; - } - if (res != sizeof(o->event)) { - ModuleLog(o->i, BLOG_ERROR, "read wrong"); - instance_free(o, 1); - return; - } - - // stop reading - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, 0); - - // set processing - o->processing = 1; - - // signal up - NCDModuleInst_Backend_Up(o->i); -} - -static void device_nextevent (struct instance *o) -{ - ASSERT(o->processing) - - // start reading - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, BREACTOR_READ); - - // set not processing - o->processing = 0; - - // signal down - NCDModuleInst_Backend_Down(o->i); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef device_arg; - if (!NCDVal_ListRead(params->args, 1, &device_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(device_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate device - NCDValNullTermString device_nts; - if (!NCDVal_StringNullTerminate(device_arg, &device_nts)) { - ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // open device - o->evdev_fd = open(device_nts.data, O_RDONLY); - NCDValNullTermString_Free(&device_nts); - if (o->evdev_fd < 0) { - ModuleLog(o->i, BLOG_ERROR, "open failed"); - goto fail0; - } - - // set non-blocking - if (!badvpn_set_nonblocking(o->evdev_fd)) { - ModuleLog(o->i, BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->evdev_fd, (BFileDescriptor_handler)device_handler, o); - if (!BReactor_AddFileDescriptor(o->i->params->iparams->reactor, &o->bfd)) { - ModuleLog(o->i, BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, BREACTOR_READ); - - // set not processing - o->processing = 0; - return; - -fail1: - if (close(o->evdev_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o, int is_error) -{ - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->i->params->iparams->reactor, &o->bfd); - - // close device. - // Ignore close error which happens if the device is removed. - if (close(o->evdev_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - instance_free(o, 0); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->processing) - - if (name == NCD_STRING_TYPE) { - *out = NCDVal_NewString(mem, evdev_type_to_str(o->event.type)); - return 1; - } - - if (name == ModuleString(o->i, STRING_VALUE)) { - char str[50]; - snprintf(str, sizeof(str), "%"PRIi32, o->event.value); - *out = NCDVal_NewString(mem, str); - return 1; - } - - if (name == ModuleString(o->i, STRING_CODE_NUMERIC)) { - *out = ncd_make_uintmax(mem, o->event.code); - return 1; - } - - if (name == ModuleString(o->i, STRING_CODE)) { - const char *str = "unknown"; - - #define MAKE_CASE(_evname_, _name_) \ - case _evname_: \ - str = evdev_##_name_##_to_str(o->event.code); \ - break; - - switch (o->event.type) { - #ifdef EV_KEY - MAKE_CASE(EV_KEY, key) - #endif - #ifdef EV_REL - MAKE_CASE(EV_REL, rel) - #endif - #ifdef EV_ABS - MAKE_CASE(EV_ABS, abs) - #endif - #ifdef EV_SW - MAKE_CASE(EV_SW, sw) - #endif - #ifdef EV_MSC - MAKE_CASE(EV_MSC, msc) - #endif - #ifdef EV_LED - MAKE_CASE(EV_LED, led) - #endif - #ifdef EV_REP - MAKE_CASE(EV_REP, rep) - #endif - #ifdef EV_SND - MAKE_CASE(EV_SND, snd) - #endif - #ifdef EV_FF_STATUS - MAKE_CASE(EV_FF_STATUS, ffstatus) - #endif - } - - *out = NCDVal_NewString(mem, str); - return 1; - } - - return 0; -} - -static void nextevent_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure we are currently reporting an event - if (!mo->processing) { - ModuleLog(i, BLOG_ERROR, "not reporting an event"); - goto fail0; - } - - // signal up. - // Do it before finishing the event so our process does not advance any further if - // we would be killed the event provider going down. - NCDModuleInst_Backend_Up(i); - - // wait for next event - device_nextevent(mo); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.evdev", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.evdev::nextevent", - .func_new2 = nextevent_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_evdev = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/sys_request_client.c b/external/badvpn_dns/ncd/modules/sys_request_client.c deleted file mode 100644 index fe4a54c..0000000 --- a/external/badvpn_dns/ncd/modules/sys_request_client.c +++ /dev/null @@ -1,646 +0,0 @@ -/** - * @file sys_request_client.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * sys.request_client(string connect_addr) - * - * Description: - * Connects to a request server (sys.request_server()). - * Goes up when the connection, and dies with error when it is broken. - * When requested to die, dies immediately, breaking the connection. - * - * The connect address should be in the same format as for the socket module. - * In particular, it must be in one of the following forms: - * - {"tcp", {"ipv4", ipv4_address, port_number}}, - * - {"tcp", {"ipv6", ipv6_address, port_number}}, - * - {"unix", socket_path}. - * - * Synopsis: - * sys.request_client::request(request_data, string reply_handler, string finished_handler, list args) - * - * Description: - * Sends a request to the server and dispatches replies to the provided handlers. - * - * The 'request_data' argument is sent as part of the request and is used by the server - * to determine what to do with the request. - * - * When a reply is received, a new template process is created from 'reply_handler' to process the - * reply. This process can access the reply data sent by the server using '_reply.data'. - * Similarly, if the server finishes the request, a process is created from 'finished_handler'. - * In both cases, the process can access objects as seen from the request statement via "_caller". - * Termination of these processes is initiated immediately after they completes. They are created - * synchronously - if a reply or a finished message arrives before a previous process is has - * finished, it is queued. Once the finished message has been processed by 'finished_handler', no - * more processes will be created. - * - * When the request statement is requested to terminate, it initiates termination of the current - * handler process and waits for it to terminate (if any is running), and then dies. - * If the corresponding client statement dies after being requested to die, or as a result of - * an error, the request statement will not react to this. It will dispatch any pending messages - * and then proceed to do nothing. In this case, if a finished message was not received, it will - * not be dispatched. - * - * The request statement may however die at any time due to errors. In this case, it will - * initiate termination of the current process and wait for it to terminate (if any) before dying. - * - * The request protocol and the server allow the client the abort requests at any time, and to - * have the client notified only after the request has been completely aborted (i.e. the handler - * process of sys.request_server() has deinitialized completely). This client implementation will - * automatically request abortion of active requests when the request statement is requested - * to die. However, the request statement will not wait for the abortion to finish before dying. - * This means, for instance, that if you initialize a request statement right after having - * deinitiazed it, the requests may overlap on the server side. - */ - -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <limits.h> - -#include <misc/offset.h> -#include <structure/LinkedList0.h> -#include <structure/LinkedList1.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/NCDRequestClient.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/address_utils.h> - -#include <generated/blog_channel_ncd_sys_request_client.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -#define CSTATE_CONNECTING 1 -#define CSTATE_CONNECTED 2 - -#define RRSTATE_SENDING_REQUEST 1 -#define RRSTATE_READY 2 -#define RRSTATE_GONE_BAD 3 -#define RRSTATE_GONE_GOOD 4 - -#define RPSTATE_NONE 1 -#define RPSTATE_WORKING 2 -#define RPSTATE_TERMINATING 3 - -#define RDSTATE_NONE 1 -#define RDSTATE_DYING 2 -#define RDSTATE_DYING_ERROR 3 - -struct instance { - NCDModuleInst *i; - NCDRequestClient client; - LinkedList0 requests_list; - int state; -}; - -struct request_instance { - NCDModuleInst *i; - NCDValRef reply_handler; - NCDValRef finished_handler; - NCDValRef args; - struct instance *client; - NCDRequestClientRequest request; - LinkedList0Node requests_list_node; - LinkedList1 replies_list; - NCDModuleProcess process; - int process_is_finished; - NCDValMem process_reply_mem; - NCDValRef process_reply_data; - int rstate; - int pstate; - int dstate; -}; - -struct reply { - LinkedList1Node replies_list_node; - NCDValMem mem; - NCDValRef val; -}; - -static void client_handler_error (struct instance *o); -static void client_handler_connected (struct instance *o); -static void request_handler_sent (struct request_instance *o); -static void request_handler_reply (struct request_instance *o, NCDValMem reply_mem, NCDValRef reply_value); -static void request_handler_finished (struct request_instance *o, int is_error); -static void request_process_handler_event (NCDModuleProcess *process, int event); -static int request_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int request_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static int request_process_reply_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out); -static void request_gone (struct request_instance *o, int is_bad); -static void request_terminate_process (struct request_instance *o); -static void request_die (struct request_instance *o, int is_error); -static void request_free_reply (struct request_instance *o, struct reply *r, int have_value); -static int request_init_reply_process (struct request_instance *o, NCDValMem reply_mem, NCDValSafeRef reply_data); -static int request_init_finished_process (struct request_instance *o); -static void instance_free (struct instance *o, int with_error); -static void request_instance_free (struct request_instance *o, int with_error); - -enum {STRING_REPLY, STRING_DATA}; - -static const char *strings[] = { - "_reply", "data", NULL -}; - -static void client_handler_error (struct instance *o) -{ - ModuleLog(o->i, BLOG_ERROR, "client error"); - - // free instance - instance_free(o, 1); -} - -static void client_handler_connected (struct instance *o) -{ - ASSERT(o->state == CSTATE_CONNECTING) - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state connected - o->state = CSTATE_CONNECTED; -} - -static void request_handler_sent (struct request_instance *o) -{ - ASSERT(o->rstate == RRSTATE_SENDING_REQUEST) - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set rstate ready - o->rstate = RRSTATE_READY; -} - -static void request_handler_reply (struct request_instance *o, NCDValMem reply_mem, NCDValRef reply_value) -{ - ASSERT(o->rstate == RRSTATE_READY) - - // queue reply if process is running - if (o->pstate != RPSTATE_NONE) { - struct reply *r = malloc(sizeof(*r)); - if (!r) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail1; - } - r->mem = reply_mem; - r->val = NCDVal_Moved(&r->mem, reply_value); - LinkedList1_Append(&o->replies_list, &r->replies_list_node); - return; - } - - // start reply process - if (!request_init_reply_process(o, reply_mem, NCDVal_ToSafe(reply_value))) { - goto fail1; - } - - return; - -fail1: - NCDValMem_Free(&reply_mem); - request_die(o, 1); -} - -static void request_handler_finished (struct request_instance *o, int is_error) -{ - ASSERT(o->rstate == RRSTATE_SENDING_REQUEST || o->rstate == RRSTATE_READY) - ASSERT(is_error || o->rstate == RRSTATE_READY) - - if (is_error) { - ModuleLog(o->i, BLOG_ERROR, "received error reply"); - goto fail; - } - - // request gone good - request_gone(o, 0); - - // start process for reporting finished, if possible - if (o->pstate == RPSTATE_NONE) { - if (!request_init_finished_process(o)) { - goto fail; - } - } - - return; - -fail: - request_die(o, 1); -} - -static void request_process_handler_event (NCDModuleProcess *process, int event) -{ - struct request_instance *o = UPPER_OBJECT(process, struct request_instance, process); - ASSERT(o->pstate != RPSTATE_NONE) - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->pstate == RPSTATE_WORKING) - - // request process termination - request_terminate_process(o); - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(0) - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->pstate == RPSTATE_TERMINATING) - ASSERT(o->rstate != RRSTATE_SENDING_REQUEST) - - // free process - NCDModuleProcess_Free(&o->process); - - // free reply data - if (!o->process_is_finished) { - NCDValMem_Free(&o->process_reply_mem); - } - - // set process state none - o->pstate = RPSTATE_NONE; - - // die finally if requested - if (o->dstate == RDSTATE_DYING || o->dstate == RDSTATE_DYING_ERROR) { - request_instance_free(o, o->dstate == RDSTATE_DYING_ERROR); - return; - } - - if (!LinkedList1_IsEmpty(&o->replies_list)) { - // get first reply - struct reply *r = UPPER_OBJECT(LinkedList1_GetFirst(&o->replies_list), struct reply, replies_list_node); - - // start reply process - if (!request_init_reply_process(o, r->mem, NCDVal_ToSafe(r->val))) { - goto fail; - } - - // free reply - request_free_reply(o, r, 0); - } - else if (o->rstate == RRSTATE_GONE_GOOD && !o->process_is_finished) { - // start process for reporting finished - if (!request_init_finished_process(o)) { - goto fail; - } - } - - return; - - fail: - request_die(o, 1); - } break; - } -} - -static int request_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct request_instance *o = UPPER_OBJECT(process, struct request_instance, process); - ASSERT(o->pstate != RPSTATE_NONE) - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, request_process_caller_obj_func_getobj); - return 1; - } - - if (!o->process_is_finished && name == ModuleString(o->i, STRING_REPLY)) { - *out_object = NCDObject_Build(-1, o, request_process_reply_obj_func_getvar, NCDObject_no_getobj); - return 1; - } - - return 0; -} - -static int request_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct request_instance *o = NCDObject_DataPtr(obj); - ASSERT(o->pstate != RPSTATE_NONE) - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static int request_process_reply_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct request_instance *o = NCDObject_DataPtr(obj); - ASSERT(o->pstate != RPSTATE_NONE) - ASSERT(!o->process_is_finished) - - if (name == ModuleString(o->i, STRING_DATA)) { - *out = NCDVal_NewCopy(mem, o->process_reply_data); - return 1; - } - - return 0; -} - -static void request_gone (struct request_instance *o, int is_bad) -{ - ASSERT(o->rstate != RRSTATE_GONE_BAD) - ASSERT(o->rstate != RRSTATE_GONE_GOOD) - - // remove from requests list - LinkedList0_Remove(&o->client->requests_list, &o->requests_list_node); - - // free request - NCDRequestClientRequest_Free(&o->request); - - // set state over - o->rstate = (is_bad ? RRSTATE_GONE_BAD : RRSTATE_GONE_GOOD); -} - -static void request_terminate_process (struct request_instance *o) -{ - ASSERT(o->pstate == RPSTATE_WORKING) - - // request process termination - NCDModuleProcess_Terminate(&o->process); - - // set process state terminating - o->pstate = RPSTATE_TERMINATING; -} - -static void request_die (struct request_instance *o, int is_error) -{ - // if we have no process, die right away, else we have to wait for process to terminate - if (o->pstate == RPSTATE_NONE) { - request_instance_free(o, is_error); - return; - } - - // release request - if (o->rstate != RRSTATE_GONE_BAD && o->rstate != RRSTATE_GONE_GOOD) { - request_gone(o, 1); - } - - // initiate process termination, if needed - if (o->pstate != RPSTATE_TERMINATING) { - request_terminate_process(o); - } - - // set dstate - o->dstate = (is_error ? RDSTATE_DYING_ERROR : RDSTATE_DYING); -} - -static void request_free_reply (struct request_instance *o, struct reply *r, int have_value) -{ - // remove from replies list - LinkedList1_Remove(&o->replies_list, &r->replies_list_node); - - // free value - if (have_value) { - NCDValMem_Free(&r->mem); - } - - // free structure - free(r); -} - -static int request_init_reply_process (struct request_instance *o, NCDValMem reply_mem, NCDValSafeRef reply_data) -{ - ASSERT(o->pstate == RPSTATE_NONE) - - // set parameters - o->process_is_finished = 0; - o->process_reply_mem = reply_mem; - o->process_reply_data = NCDVal_FromSafe(&o->process_reply_mem, reply_data); - - // init process - if (!NCDModuleProcess_InitValue(&o->process, o->i, o->reply_handler, o->args, request_process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set special objects function - NCDModuleProcess_SetSpecialFuncs(&o->process, request_process_func_getspecialobj); - - // set process state working - o->pstate = RPSTATE_WORKING; - return 1; - -fail0: - return 0; -} - -static int request_init_finished_process (struct request_instance *o) -{ - ASSERT(o->pstate == RPSTATE_NONE) - - // set parameters - o->process_is_finished = 1; - - // init process - if (!NCDModuleProcess_InitValue(&o->process, o->i, o->finished_handler, o->args, request_process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set special objects function - NCDModuleProcess_SetSpecialFuncs(&o->process, request_process_func_getspecialobj); - - // set process state working - o->pstate = RPSTATE_WORKING; - return 1; - -fail0: - return 0; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef connect_addr_arg; - if (!NCDVal_ListRead(params->args, 1, &connect_addr_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // read connect address - struct BConnection_addr addr; - if (!ncd_read_bconnection_addr(connect_addr_arg, &addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong connect address"); - goto fail0; - } - - // init client - if (!NCDRequestClient_Init(&o->client, addr, i->params->iparams->reactor, o, - (NCDRequestClient_handler_error)client_handler_error, - (NCDRequestClient_handler_connected)client_handler_connected)) { - ModuleLog(o->i, BLOG_ERROR, "NCDRequestClient_Init failed"); - goto fail0; - } - - // init requests list - LinkedList0_Init(&o->requests_list); - - // set state connecting - o->state = CSTATE_CONNECTING; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o, int with_error) -{ - // deal with requests - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&o->requests_list)) { - struct request_instance *req = UPPER_OBJECT(ln, struct request_instance, requests_list_node); - request_gone(req, 1); - } - - // free client - NCDRequestClient_Free(&o->client); - - if (with_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - instance_free(o, 0); -} - -static void request_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct request_instance *o = vo; - o->i = i; - - // check arguments - NCDValRef request_data_arg; - NCDValRef reply_handler_arg; - NCDValRef finished_handler_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 4, &request_data_arg, &reply_handler_arg, &finished_handler_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(reply_handler_arg) || !NCDVal_IsString(finished_handler_arg) || - !NCDVal_IsList(args_arg) - ) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->reply_handler = reply_handler_arg; - o->finished_handler = finished_handler_arg; - o->args = args_arg; - - // get client - struct instance *client = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - o->client = client; - - // check client state - if (client->state != CSTATE_CONNECTED) { - ModuleLog(o->i, BLOG_ERROR, "client is not connected"); - goto fail0; - } - - // init request - if (!NCDRequestClientRequest_Init(&o->request, &client->client, request_data_arg, o, - (NCDRequestClientRequest_handler_sent)request_handler_sent, - (NCDRequestClientRequest_handler_reply)request_handler_reply, - (NCDRequestClientRequest_handler_finished)request_handler_finished)) { - ModuleLog(o->i, BLOG_ERROR, "NCDRequestClientRequest_Init failed"); - goto fail0; - } - - // add to requests list - LinkedList0_Prepend(&client->requests_list, &o->requests_list_node); - - // init replies list - LinkedList1_Init(&o->replies_list); - - // set state - o->rstate = RRSTATE_SENDING_REQUEST; - o->pstate = RPSTATE_NONE; - o->dstate = RDSTATE_NONE; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void request_instance_free (struct request_instance *o, int with_error) -{ - ASSERT(o->pstate == RPSTATE_NONE) - - // free replies - LinkedList1Node *ln; - while (ln = LinkedList1_GetFirst(&o->replies_list)) { - struct reply *r = UPPER_OBJECT(ln, struct reply, replies_list_node); - request_free_reply(o, r, 1); - } - - // release request - if (o->rstate != RRSTATE_GONE_BAD && o->rstate != RRSTATE_GONE_GOOD) { - request_gone(o, 1); - } - - if (with_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void request_func_die (void *vo) -{ - struct request_instance *o = vo; - - request_die(o, 0); -} - -static struct NCDModule modules[] = { - { - .type = "sys.request_client", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.request_client::request", - .func_new2 = request_func_new, - .func_die = request_func_die, - .alloc_size = sizeof(struct request_instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_request_client = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/sys_request_server.c b/external/badvpn_dns/ncd/modules/sys_request_server.c deleted file mode 100644 index 31bc431..0000000 --- a/external/badvpn_dns/ncd/modules/sys_request_server.c +++ /dev/null @@ -1,792 +0,0 @@ -/** - * @file sys_request_server.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A simple a IPC interface for NCD to talk to other processes over a Unix socket. - * - * Synopsis: - * sys.request_server(listen_address, string request_handler_template, list args) - * - * Description: - * Initializes a request server on the given socket path. Requests are served by - * starting a template process for every request. Multiple such processes may - * exist simultaneously. Termination of these processess may be initiated at - * any time if the request server no longer needs the request in question served. - * The payload of a request is a value, and can be accessed as _request.data - * from within the handler process. Replies to the request can be sent using - * _request->reply(data); replies are values too. Finally, _request->finish() - * should be called to indicate that no further replies will be sent. Calling - * finish() will immediately initiate termination of the handler process. - * Requests can be sent to NCD using the badvpn-ncd-request program. - * - * The listen address should be in the same format as for the socket module. - * In particular, it must be in one of the following forms: - * - {"tcp", {"ipv4", ipv4_address, port_number}}, - * - {"tcp", {"ipv6", ipv6_address, port_number}}, - * - {"unix", socket_path}. - * - * Predefined objects and variables in request_handler_template: - * _caller - provides access to objects as seen from the sys.request_server() - * command - * _request.data - the request payload as sent by the client - * string _request.client_addr - the address of the client. The form is - * like the second part of the sys.request_server() address format, e.g. - * {"ipv4", "1.2.3.4", "4000"}. - * - * Synopsis: - * sys.request_server.request::reply(reply_data) - * - * Synopsis: - * sys.request_server.request::finish() - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <inttypes.h> -#include <errno.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/byteorder.h> -#include <protocol/packetproto.h> -#include <protocol/requestproto.h> -#include <structure/LinkedList0.h> -#include <system/BConnection.h> -#include <system/BConnectionGeneric.h> -#include <system/BAddr.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketPassFifoQueue.h> -#include <ncd/NCDValParser.h> -#include <ncd/NCDValGenerator.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/address_utils.h> - -#include <generated/blog_channel_ncd_sys_request_server.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -#define SEND_PAYLOAD_MTU 32768 -#define RECV_PAYLOAD_MTU 32768 - -#define SEND_MTU (SEND_PAYLOAD_MTU + sizeof(struct requestproto_header)) -#define RECV_MTU (RECV_PAYLOAD_MTU + sizeof(struct requestproto_header)) - -struct instance { - NCDModuleInst *i; - NCDValRef request_handler_template; - NCDValRef args; - BListener listener; - LinkedList0 connections_list; - int dying; -}; - -#define CONNECTION_STATE_RUNNING 1 -#define CONNECTION_STATE_TERMINATING 2 - -struct reply; - -struct connection { - struct instance *inst; - LinkedList0Node connections_list_node; - BConnection con; - BAddr addr; - PacketProtoDecoder recv_decoder; - PacketPassInterface recv_if; - PacketPassFifoQueue send_queue; - PacketStreamSender send_pss; - LinkedList0 requests_list; - LinkedList0 replies_list; - int state; -}; - -struct request { - struct connection *con; - uint32_t request_id; - LinkedList0Node requests_list_node; - NCDValMem request_data_mem; - NCDValRef request_data; - struct reply *end_reply; - NCDModuleProcess process; - int terminating; - int got_finished; -}; - -struct reply { - struct connection *con; - LinkedList0Node replies_list_node; - PacketPassFifoQueueFlow send_qflow; - PacketPassInterface *send_qflow_if; - uint8_t *send_buf; -}; - -static void listener_handler (struct instance *o); -static void connection_free (struct connection *c); -static void connection_free_link (struct connection *c); -static void connection_terminate (struct connection *c); -static void connection_con_handler (struct connection *c, int event); -static void connection_recv_decoder_handler_error (struct connection *c); -static void connection_recv_if_handler_send (struct connection *c, uint8_t *data, int data_len); -static int request_init (struct connection *c, uint32_t request_id, const uint8_t *data, int data_len); -static void request_free (struct request *r); -static struct request * find_request (struct connection *c, uint32_t request_id); -static void request_process_handler_event (NCDModuleProcess *process, int event); -static int request_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int request_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static int request_process_request_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value); -static void request_terminate (struct request *r); -static struct reply * reply_init (struct connection *c, uint32_t request_id, NCDValRef reply_data); -static void reply_start (struct reply *r, uint32_t type); -static void reply_free (struct reply *r); -static void reply_send_qflow_if_handler_done (struct reply *r); -static void instance_free (struct instance *o); - -enum {STRING_REQUEST, STRING_DATA, STRING_CLIENT_ADDR, - STRING_SYS_REQUEST_SERVER_REQUEST}; - -static const char *strings[] = { - "_request", "data", "client_addr", - "sys.request_server.request", NULL -}; - -static void listener_handler (struct instance *o) -{ - ASSERT(!o->dying) - - BReactor *reactor = o->i->params->iparams->reactor; - BPendingGroup *pg = BReactor_PendingGroup(reactor); - - struct connection *c = malloc(sizeof(*c)); - if (!c) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - c->inst = o; - - LinkedList0_Prepend(&o->connections_list, &c->connections_list_node); - - if (!BConnection_Init(&c->con, BConnection_source_listener(&o->listener, &c->addr), reactor, c, (BConnection_handler)connection_con_handler)) { - ModuleLog(o->i, BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - BConnection_SendAsync_Init(&c->con); - BConnection_RecvAsync_Init(&c->con); - StreamPassInterface *con_send_if = BConnection_SendAsync_GetIf(&c->con); - StreamRecvInterface *con_recv_if = BConnection_RecvAsync_GetIf(&c->con); - - PacketPassInterface_Init(&c->recv_if, RECV_MTU, (PacketPassInterface_handler_send)connection_recv_if_handler_send, c, pg); - - if (!PacketProtoDecoder_Init(&c->recv_decoder, con_recv_if, &c->recv_if, pg, c, (PacketProtoDecoder_handler_error)connection_recv_decoder_handler_error)) { - ModuleLog(o->i, BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail2; - } - - PacketStreamSender_Init(&c->send_pss, con_send_if, PACKETPROTO_ENCLEN(SEND_MTU), pg); - - PacketPassFifoQueue_Init(&c->send_queue, PacketStreamSender_GetInput(&c->send_pss), pg); - - LinkedList0_Init(&c->requests_list); - - LinkedList0_Init(&c->replies_list); - - c->state = CONNECTION_STATE_RUNNING; - - ModuleLog(o->i, BLOG_INFO, "connection initialized"); - return; - -fail2: - PacketPassInterface_Free(&c->recv_if); - BConnection_RecvAsync_Free(&c->con); - BConnection_SendAsync_Free(&c->con); - BConnection_Free(&c->con); -fail1: - LinkedList0_Remove(&o->connections_list, &c->connections_list_node); - free(c); -fail0: - return; -} - -static void connection_free (struct connection *c) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_TERMINATING) - ASSERT(LinkedList0_IsEmpty(&c->requests_list)) - ASSERT(LinkedList0_IsEmpty(&c->replies_list)) - - LinkedList0_Remove(&o->connections_list, &c->connections_list_node); - free(c); -} - -static void connection_free_link (struct connection *c) -{ - PacketPassFifoQueue_PrepareFree(&c->send_queue); - - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&c->replies_list)) { - struct reply *r = UPPER_OBJECT(ln, struct reply, replies_list_node); - ASSERT(r->con == c) - reply_free(r); - } - - PacketPassFifoQueue_Free(&c->send_queue); - PacketStreamSender_Free(&c->send_pss); - PacketProtoDecoder_Free(&c->recv_decoder); - PacketPassInterface_Free(&c->recv_if); - BConnection_RecvAsync_Free(&c->con); - BConnection_SendAsync_Free(&c->con); - BConnection_Free(&c->con); -} - -static void connection_terminate (struct connection *c) -{ - ASSERT(c->state == CONNECTION_STATE_RUNNING) - - for (LinkedList0Node *ln = LinkedList0_GetFirst(&c->requests_list); ln; ln = LinkedList0Node_Next(ln)) { - struct request *r = UPPER_OBJECT(ln, struct request, requests_list_node); - - if (!r->terminating) { - request_terminate(r); - } - } - - connection_free_link(c); - - c->state = CONNECTION_STATE_TERMINATING; - - if (LinkedList0_IsEmpty(&c->requests_list)) { - connection_free(c); - return; - } -} - -static void connection_con_handler (struct connection *c, int event) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_RUNNING) - - ModuleLog(o->i, BLOG_INFO, "connection closed"); - - connection_terminate(c); -} - -static void connection_recv_decoder_handler_error (struct connection *c) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_RUNNING) - - ModuleLog(o->i, BLOG_ERROR, "decoder error"); - - connection_terminate(c); -} - -static void connection_recv_if_handler_send (struct connection *c, uint8_t *data, int data_len) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_RUNNING) - ASSERT(data_len >= 0) - ASSERT(data_len <= RECV_MTU) - - PacketPassInterface_Done(&c->recv_if); - - if (data_len < sizeof(struct requestproto_header)) { - ModuleLog(o->i, BLOG_ERROR, "missing requestproto header"); - goto fail; - } - - struct requestproto_header header; - memcpy(&header, data, sizeof(header)); - uint32_t request_id = ltoh32(header.request_id); - uint32_t type = ltoh32(header.type); - - switch (type) { - case REQUESTPROTO_TYPE_CLIENT_REQUEST: { - if (find_request(c, request_id)) { - ModuleLog(o->i, BLOG_ERROR, "request with the same ID already exists"); - goto fail; - } - - if (!request_init(c, request_id, data + sizeof(header), data_len - sizeof(header))) { - goto fail; - } - } break; - - case REQUESTPROTO_TYPE_CLIENT_ABORT: { - struct request *r = find_request(c, request_id); - if (!r) { - // this is expected if we finish before we get the abort - return; - } - - if (!r->terminating) { - request_terminate(r); - } - } break; - - default: - ModuleLog(o->i, BLOG_ERROR, "invalid requestproto type"); - goto fail; - } - - return; - -fail: - connection_terminate(c); -} - -static int request_init (struct connection *c, uint32_t request_id, const uint8_t *data, int data_len) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_RUNNING) - ASSERT(!find_request(c, request_id)) - ASSERT(data_len >= 0) - ASSERT(data_len <= RECV_PAYLOAD_MTU) - - struct request *r = malloc(sizeof(*r)); - if (!r) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - r->con = c; - r->request_id = request_id; - - LinkedList0_Prepend(&c->requests_list, &r->requests_list_node); - - NCDValMem_Init(&r->request_data_mem); - - if (!NCDValParser_Parse((const char *)data, data_len, &r->request_data_mem, &r->request_data)) { - ModuleLog(o->i, BLOG_ERROR, "NCDValParser_Parse failed"); - goto fail1; - } - - if (!(r->end_reply = reply_init(c, request_id, NCDVal_NewInvalid()))) { - goto fail1; - } - - if (!NCDModuleProcess_InitValue(&r->process, o->i, o->request_handler_template, o->args, request_process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail3; - } - - NCDModuleProcess_SetSpecialFuncs(&r->process, request_process_func_getspecialobj); - - r->terminating = 0; - r->got_finished = 0; - - ModuleLog(o->i, BLOG_INFO, "request initialized"); - return 1; - -fail3: - reply_free(r->end_reply); -fail1: - NCDValMem_Free(&r->request_data_mem); - LinkedList0_Remove(&c->requests_list, &r->requests_list_node); - free(r); -fail0: - return 0; -} - -static void request_free (struct request *r) -{ - struct connection *c = r->con; - NCDModuleProcess_AssertFree(&r->process); - - if (c->state != CONNECTION_STATE_TERMINATING) { - uint32_t type = r->got_finished ? REQUESTPROTO_TYPE_SERVER_FINISHED : REQUESTPROTO_TYPE_SERVER_ERROR; - reply_start(r->end_reply, type); - } - - NCDModuleProcess_Free(&r->process); - NCDValMem_Free(&r->request_data_mem); - LinkedList0_Remove(&c->requests_list, &r->requests_list_node); - free(r); -} - -static struct request * find_request (struct connection *c, uint32_t request_id) -{ - for (LinkedList0Node *ln = LinkedList0_GetFirst(&c->requests_list); ln; ln = LinkedList0Node_Next(ln)) { - struct request *r = UPPER_OBJECT(ln, struct request, requests_list_node); - if (!r->terminating && r->request_id == request_id) { - return r; - } - } - - return NULL; -} - -static void request_process_handler_event (NCDModuleProcess *process, int event) -{ - struct request *r = UPPER_OBJECT(process, struct request, process); - struct connection *c = r->con; - struct instance *o = c->inst; - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(!r->terminating) - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(!r->terminating) - - NCDModuleProcess_Continue(&r->process); - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(r->terminating) - - request_free(r); - - if (c->state == CONNECTION_STATE_TERMINATING && LinkedList0_IsEmpty(&c->requests_list)) { - connection_free(c); - - if (o->dying && LinkedList0_IsEmpty(&o->connections_list)) { - instance_free(o); - return; - } - } - } break; - - default: ASSERT(0); - } -} - -static int request_process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct request *r = UPPER_OBJECT(process, struct request, process); - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, r, NCDObject_no_getvar, request_process_caller_obj_func_getobj); - return 1; - } - - if (name == ModuleString(r->con->inst->i, STRING_REQUEST)) { - *out_object = NCDObject_Build(ModuleString(r->con->inst->i, STRING_SYS_REQUEST_SERVER_REQUEST), r, request_process_request_obj_func_getvar, NCDObject_no_getobj); - return 1; - } - - return 0; -} - -static int request_process_caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct request *r = NCDObject_DataPtr(obj); - - return NCDModuleInst_Backend_GetObj(r->con->inst->i, name, out_object); -} - -static int request_process_request_obj_func_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct request *r = NCDObject_DataPtr(obj); - - if (name == ModuleString(r->con->inst->i, STRING_DATA)) { - *out = NCDVal_NewCopy(mem, r->request_data); - return 1; - } - - if (name == ModuleString(r->con->inst->i, STRING_CLIENT_ADDR)) { - *out = ncd_make_baddr(r->con->addr, mem); - return 1; - } - - return 0; -} - -static void request_terminate (struct request *r) -{ - ASSERT(!r->terminating) - - NCDModuleProcess_Terminate(&r->process); - - r->terminating = 1; -} - -static struct reply * reply_init (struct connection *c, uint32_t request_id, NCDValRef reply_data) -{ - struct instance *o = c->inst; - ASSERT(c->state == CONNECTION_STATE_RUNNING) - NCDVal_Assert(reply_data); - - struct reply *r = malloc(sizeof(*r)); - if (!r) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - r->con = c; - - LinkedList0_Prepend(&c->replies_list, &r->replies_list_node); - - PacketPassFifoQueueFlow_Init(&r->send_qflow, &c->send_queue); - - r->send_qflow_if = PacketPassFifoQueueFlow_GetInput(&r->send_qflow); - PacketPassInterface_Sender_Init(r->send_qflow_if, (PacketPassInterface_handler_done)reply_send_qflow_if_handler_done, r); - - ExpString str; - if (!ExpString_Init(&str)) { - ModuleLog(o->i, BLOG_ERROR, "ExpString_Init failed"); - goto fail1; - } - - if (!ExpString_AppendZeros(&str, sizeof(struct packetproto_header) + sizeof(struct requestproto_header))) { - ModuleLog(o->i, BLOG_ERROR, "ExpString_AppendZeros failed"); - goto fail2; - } - - if (!NCDVal_IsInvalid(reply_data) && !NCDValGenerator_AppendGenerate(reply_data, &str)) { - ModuleLog(o->i, BLOG_ERROR, "NCDValGenerator_AppendGenerate failed"); - goto fail2; - } - - size_t len = ExpString_Length(&str); - if (len > INT_MAX || len > PACKETPROTO_ENCLEN(SEND_MTU) || len - sizeof(struct packetproto_header) > UINT16_MAX) { - ModuleLog(o->i, BLOG_ERROR, "reply is too long"); - goto fail2; - } - - r->send_buf = (uint8_t *)ExpString_Get(&str); - - struct packetproto_header pp; - pp.len = htol16(len - sizeof(pp)); - - struct requestproto_header rp; - rp.request_id = htol32(request_id); - - memcpy(r->send_buf, &pp, sizeof(pp)); - memcpy(r->send_buf + sizeof(pp), &rp, sizeof(rp)); - - return r; - -fail2: - ExpString_Free(&str); -fail1: - PacketPassFifoQueueFlow_Free(&r->send_qflow); - LinkedList0_Remove(&c->replies_list, &r->replies_list_node); - free(r); -fail0: - return NULL; -} - -static void reply_start (struct reply *r, uint32_t type) -{ - struct requestproto_header rp; - memcpy(&rp, r->send_buf + sizeof(struct packetproto_header), sizeof(rp)); - rp.type = htol32(type); - memcpy(r->send_buf + sizeof(struct packetproto_header), &rp, sizeof(rp)); - - struct packetproto_header pp; - memcpy(&pp, r->send_buf, sizeof(pp)); - - int len = ltoh16(pp.len) + sizeof(struct packetproto_header); - - PacketPassInterface_Sender_Send(r->send_qflow_if, r->send_buf, len); -} - -static void reply_free (struct reply *r) -{ - struct connection *c = r->con; - PacketPassFifoQueueFlow_AssertFree(&r->send_qflow); - - free(r->send_buf); - PacketPassFifoQueueFlow_Free(&r->send_qflow); - LinkedList0_Remove(&c->replies_list, &r->replies_list_node); - free(r); -} - -static void reply_send_qflow_if_handler_done (struct reply *r) -{ - reply_free(r); -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef listen_addr_arg; - NCDValRef request_handler_template_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 3, &listen_addr_arg, &request_handler_template_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(request_handler_template_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->request_handler_template = request_handler_template_arg; - o->args = args_arg; - - // read listen address - struct BConnection_addr addr; - if (!ncd_read_bconnection_addr(listen_addr_arg, &addr)) { - ModuleLog(o->i, BLOG_ERROR, "wrong listen address"); - goto fail0; - } - - // init listener - if (!BListener_InitGeneric(&o->listener, addr, i->params->iparams->reactor, o, (BListener_handler)listener_handler)) { - ModuleLog(o->i, BLOG_ERROR, "BListener_InitGeneric failed"); - goto fail0; - } - - // init connections list - LinkedList0_Init(&o->connections_list); - - // set not dying - o->dying = 0; - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - ASSERT(o->dying) - ASSERT(LinkedList0_IsEmpty(&o->connections_list)) - - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // free listener - BListener_Free(&o->listener); - - // terminate connections - LinkedList0Node *next_ln; - for (LinkedList0Node *ln = LinkedList0_GetFirst(&o->connections_list); ln && (next_ln = LinkedList0Node_Next(ln)), ln; ln = next_ln) { - struct connection *c = UPPER_OBJECT(ln, struct connection, connections_list_node); - ASSERT(c->inst == o) - - if (c->state != CONNECTION_STATE_TERMINATING) { - connection_terminate(c); - } - } - - // set dying - o->dying = 1; - - // if no connections, die right away - if (LinkedList0_IsEmpty(&o->connections_list)) { - instance_free(o); - return; - } -} - -static void reply_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef reply_data; - if (!NCDVal_ListRead(params->args, 1, &reply_data)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail; - } - - NCDModuleInst_Backend_Up(i); - - struct request *r = params->method_user; - struct connection *c = r->con; - - if (r->terminating) { - ModuleLog(i, BLOG_ERROR, "request is dying, cannot submit reply"); - goto fail; - } - - struct reply *rpl = reply_init(c, r->request_id, reply_data); - if (!rpl) { - ModuleLog(i, BLOG_ERROR, "failed to submit reply"); - goto fail; - } - - reply_start(rpl, REQUESTPROTO_TYPE_SERVER_REPLY); - return; - -fail: - NCDModuleInst_Backend_DeadError(i); -} - -static void finish_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail; - } - - NCDModuleInst_Backend_Up(i); - - struct request *r = params->method_user; - - if (r->terminating) { - ModuleLog(i, BLOG_ERROR, "request is dying, cannot submit finished"); - goto fail; - } - - r->got_finished = 1; - - request_terminate(r); - return; - -fail: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.request_server", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.request_server.request::reply", - .func_new2 = reply_func_new - }, { - .type = "sys.request_server.request::finish", - .func_new2 = finish_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_request_server = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/sys_start_process.c b/external/badvpn_dns/ncd/modules/sys_start_process.c deleted file mode 100644 index f34e7b3..0000000 --- a/external/badvpn_dns/ncd/modules/sys_start_process.c +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * @file sys_start_process.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * sys.start_process(list command, string mode [, map options]) - * - * Options: - * "keep_stdout":"true" - Start the program with the same stdout as the NCD process. - * Must not be present if the process is being opened for reading. - * "keep_stderr":true" - Start the program with the same stderr as the NCD process. - * "do_setsid":"true" - Call setsid() in the child before exec. This is needed to - * start the 'agetty' program. - * "username":username_string - Start the process under the permissions of the - * specified user. - * "term_on_deinit":"false" - do not send SIGTERM to the process when this statement - * is requested to terminate - * "deinit_kill_time":milliseconds - how long to wait for the process to terminate - * after this statement is requested to terminate until we send SIGKILL. If this option - * is not present or is "never", SIGKILL will not be sent. If this option is empty, the - * process will be sent SIGKILL immediately when the statement is requested to terminate. - * - * Variables: - * is_error - "true" if there was an error starting the process, "false" if the process - * has been started successfully - * - * Synopsis: - * sys.start_process::wait() - * - * Variables: - * exit_status - the exit code if the process terminated normally, -1 if it terminated - * with a signal - * - * Synopsis: - * sys.start_process::terminate() - * sys.start_process::kill() - * - * Synopsis: - * sys.start_process::read_pipe() - * - * Description: - * Creates a read interface to the process's standard output. Data is read using the - * read() method on this object. Read errors are reported implicitly by this statement - * going down and the 'is_error' variable changing to "true". - * When read_pipe() is initialized for a process, it takes ownership of the read pipe - * to the process. When read_pipe() is requested to terminate, it will close the pipe. - * Attempting to initialize read_pipe() on a process which was not started with 'r' - * in the mode argument, or where another read_pipe() object has already taken ownership - * of the read pipe, will result in throwing an error to the interpreter. - * - * Variables: - * string is_error - "true" if there was a read error, "false" if not - * - * Synopsis: - * sys.start_process::read_pipe::read() - * - * Description: - * Reads some data. If a read error occurs, it is reported implicitly via the - * read_pipe() object going down. If end of file is reached, this and any future read() - * operations will indicate that via the 'not_eof' variable. It is guaranteed that after - * EOF is reached, the read_pipe() object will not go down to report any errors. - * WARNING: if a read() is requested to terminate before it has completed, the - * read_pipe() will become unusable and any read() invocation after that will - * throw an error to the interpreter. - * - * Variables: - * string (empty) - data that was read, or an empty string on EOF - * string not_eof - "true" is EOF was not reached, "false" if it was - * - * Synopsis: - * sys.start_process::write_pipe() - * - * Description: - * Creates a write interface to the process's standard input. Data is written using the - * write() method on this object. Write errors are reported implicitly by this statement - * going down and the ''is_error variable changing to "true". - * When write_pipe() is initialized for a process, it takes ownership of the write pipe - * to the process. When write_pipe() is requested to terminate, it will close the pipe - * (unless the close() has been used). - * Attempting to initialize write_pipe() on a process which was not started with 'w' - * in the mode argument, or where another write_pipe() object has already taken ownership - * of the write pope, will result in throwing an error to the interpreter. - * - * Variables: - * string is_error - "true" if there was a write error, "false" if not - * - * Synopsis: - * sys.start_process::write_pipe::write(string data) - * - * Description: - * Writes the given data. If a write error occurs, it is reported implicitly via the - * write_pipe() object going down. - * WARNING: if a write() is requested to terminate before it has completed, the - * write_pipe() will become unusable and any write() or close() invocation after - * that will throw an error to the interpreter. - * - * Synopsis: - * sys.start_process::write_pipe::close(string data) - * - * Description: - * Closes the write pipe. This will make whatever is reading the other end of the pipe - * encounter EOF after it has read any pending data. It is guaranteed that after the - * pipe is closed, the write_pipe() object will not go down to report any errors. - * After close() is performed, any further write() or close() calls are disallowed and - * will throw errors to the interpreter. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <inttypes.h> -#include <limits.h> -#include <unistd.h> - -#include <misc/offset.h> -#include <structure/LinkedList0.h> -#include <system/BProcess.h> -#include <system/BConnection.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/NCDBuf.h> -#include <ncd/extra/value_utils.h> -#include <ncd/extra/build_cmdline.h> -#include <ncd/extra/NCDBProcessOpts.h> - -#include <generated/blog_channel_ncd_sys_start_process.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define READ_BUF_SIZE 8192 - -#define PROCESS_STATE_ERROR 1 -#define PROCESS_STATE_RUNNING 2 -#define PROCESS_STATE_TERMINATED 3 -#define PROCESS_STATE_DYING 4 - -#define READER_STATE_RUNNING 1 -#define READER_STATE_EOF 2 -#define READER_STATE_ERROR 3 -#define READER_STATE_ABORTED 4 - -#define WRITER_STATE_RUNNING 1 -#define WRITER_STATE_CLOSED 2 -#define WRITER_STATE_ERROR 3 -#define WRITER_STATE_ABORTED 4 - -struct process_instance { - NCDModuleInst *i; - BProcess process; - BSmallTimer kill_timer; - LinkedList0 waits_list; - btime_t deinit_kill_time; - int term_on_deinit; - int read_fd; - int write_fd; - int exit_status; - int state; -}; - -struct wait_instance { - NCDModuleInst *i; - struct process_instance *pinst; - LinkedList0Node waits_list_node; - int exit_status; -}; - -struct read_pipe_instance { - NCDModuleInst *i; - int state; - int read_fd; - BConnection connection; - NCDBufStore store; - struct read_instance *read_inst; -}; - -struct read_instance { - NCDModuleInst *i; - struct read_pipe_instance *read_pipe_inst; - NCDBuf *buf; - size_t read_size; -}; - -struct write_pipe_instance { - NCDModuleInst *i; - int state; - int write_fd; - BConnection connection; - struct write_instance *write_inst; -}; - -struct write_instance { - NCDModuleInst *i; - struct write_pipe_instance *write_pipe_inst; - b_cstring cstr; - size_t pos; -}; - -static int parse_mode (NCDModuleInst *i, NCDValRef mode_arg, int *out_read, int *out_write) -{ - if (!NCDVal_IsString(mode_arg)) { - ModuleLog(i, BLOG_ERROR, "mode argument must be a string"); - return 0; - } - - *out_read = 0; - *out_write = 0; - - b_cstring cstr = NCDVal_StringCstring(mode_arg); - - B_CSTRING_LOOP_CHARS(cstr, char_pos, ch, { - if (ch == 'r') { - *out_read = 1; - } - else if (ch == 'w') { - *out_write = 1; - } - else { - ModuleLog(i, BLOG_ERROR, "invalid character in mode argument"); - return 0; - } - }) - - return 1; -} - -static void process_free (struct process_instance *o) -{ - // close write fd - if (o->write_fd != -1) { - if (close(o->write_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } - } - - // close read fd - if (o->read_fd != -1) { - if (close(o->read_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void process_handler (void *vo, int normally, uint8_t normally_exit_status) -{ - struct process_instance *o = vo; - ASSERT(o->state == PROCESS_STATE_RUNNING || o->state == PROCESS_STATE_DYING) - - ModuleLog(o->i, BLOG_INFO, "process terminated"); - - // free kill timer - BReactor_RemoveSmallTimer(o->i->params->iparams->reactor, &o->kill_timer); - - // free process - BProcess_Free(&o->process); - - // remember exit code - o->exit_status = (!normally ? -1 : normally_exit_status); - - // finish waits - LinkedList0Node *ln; - while ((ln = LinkedList0_GetFirst(&o->waits_list))) { - struct wait_instance *winst = UPPER_OBJECT(ln, struct wait_instance, waits_list_node); - ASSERT(winst->pinst == o) - LinkedList0_Remove(&o->waits_list, &winst->waits_list_node); - winst->pinst = NULL; - winst->exit_status = o->exit_status; - NCDModuleInst_Backend_Up(winst->i); - } - - // if we have been requested to die, then die now - if (o->state == PROCESS_STATE_DYING) { - process_free(o); - return; - } - - // set state - o->state = PROCESS_STATE_TERMINATED; -} - -static void process_kill_timer_handler (BSmallTimer *kill_timer) -{ - struct process_instance *o = UPPER_OBJECT(kill_timer, struct process_instance, kill_timer); - ASSERT(o->state == PROCESS_STATE_DYING) - - ModuleLog(o->i, BLOG_INFO, "killing process after timeout"); - BProcess_Kill(&o->process); -} - -static int opts_func_unknown (void *user, NCDValRef key, NCDValRef val) -{ - struct process_instance *o = user; - - if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "term_on_deinit")) { - o->term_on_deinit = ncd_read_boolean(val); - return 1; - } - - if (NCDVal_IsString(key) && NCDVal_StringEquals(key, "deinit_kill_time")) { - if (NCDVal_StringEquals(val, "never")) { - o->deinit_kill_time = -2; - } - else if (NCDVal_StringEqualsId(val, NCD_STRING_EMPTY, o->i->params->iparams->string_index)) { - o->deinit_kill_time = -1; - } - else if (!ncd_read_time(val, &o->deinit_kill_time)) { - ModuleLog(o->i, BLOG_ERROR, "wrong value for deinit_kill_time option"); - return 0; - } - return 1; - } - - return 0; -} - -static void process_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct process_instance *o = vo; - o->i = i; - NCDModuleInst_Backend_PassMemToMethods(i); - - // check arguments - NCDValRef command_arg; - NCDValRef mode_arg; - NCDValRef options_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 2, &command_arg, &mode_arg) && - !NCDVal_ListRead(params->args, 3, &command_arg, &mode_arg, &options_arg) - ) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // parse mode - int is_read; - int is_write; - if (!parse_mode(i, mode_arg, &is_read, &is_write)) { - goto fail0; - } - - // parse options - NCDBProcessOpts opts; - int keep_stdout; - int keep_stderr; - o->deinit_kill_time = -2; - o->term_on_deinit = 1; - if (!NCDBProcessOpts_Init2(&opts, options_arg, opts_func_unknown, o, i, BLOG_CURRENT_CHANNEL, &keep_stdout, &keep_stderr)) { - goto fail0; - } - - // keep-stdout option and read mode are not compatible - if (keep_stdout && is_read) { - ModuleLog(i, BLOG_ERROR, "keep-stdout and read mode are not compatible"); - goto fail1; - } - - // prepare for creating pipes - int fds[4]; - int fds_map[3]; - int start_num_fds = opts.nfds; - int num_fds = start_num_fds; - memcpy(fds, opts.fds, num_fds * sizeof(int)); - memcpy(fds_map, opts.fds_map, num_fds * sizeof(int)); - int read_fd = -1; - int write_fd = -1; - - // create read pipe - if (is_read) { - int pipefd[2]; - if (pipe(pipefd) < 0) { - ModuleLog(i, BLOG_ERROR, "pipe failed"); - goto error1; - } - read_fd = pipefd[0]; - fds[num_fds] = pipefd[1]; - fds_map[num_fds++] = STDOUT_FILENO; - } - - // create write pipe - if (is_write) { - int pipefd[2]; - if (pipe(pipefd) < 0) { - ModuleLog(i, BLOG_ERROR, "pipe failed"); - goto error1; - } - write_fd = pipefd[1]; - fds[num_fds] = pipefd[0]; - fds_map[num_fds++] = STDIN_FILENO; - } - - // terminate fds array - fds[num_fds] = -1; - - // build process parameters struct - struct BProcess_params p_params = {}; - p_params.fds = fds; - p_params.fds_map = fds_map; - p_params.do_setsid = opts.do_setsid; - p_params.username = opts.username; - - // build command line - char *exec; - CmdLine cl; - if (!ncd_build_cmdline(i, BLOG_CURRENT_CHANNEL, command_arg, &exec, &cl)) { - goto error1; - } - - // start process - int res = BProcess_Init2(&o->process, i->params->iparams->manager, process_handler, o, exec, CmdLine_Get(&cl), p_params); - CmdLine_Free(&cl); - free(exec); - if (!res) { - ModuleLog(i, BLOG_ERROR, "BProcess_Init failed"); - goto error1; - } - - // init kill timer - BSmallTimer_Init(&o->kill_timer, process_kill_timer_handler); - - // close child fds - while (num_fds-- > start_num_fds) { - if (close(fds[num_fds]) < 0) { - ModuleLog(i, BLOG_ERROR, "close failed"); - } - } - - // free opts - NCDBProcessOpts_Free(&opts); - - // init waits list - LinkedList0_Init(&o->waits_list); - - // remember our fds - o->read_fd = read_fd; - o->write_fd = write_fd; - - // set state - o->state = PROCESS_STATE_RUNNING; - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - NCDBProcessOpts_Free(&opts); -fail0: - NCDModuleInst_Backend_DeadError(i); - return; - -error1: - if (write_fd != -1) { - if (close(write_fd) < 0) { - ModuleLog(i, BLOG_ERROR, "close failed"); - } - } - if (read_fd != -1) { - if (close(read_fd) < 0) { - ModuleLog(i, BLOG_ERROR, "close failed"); - } - } - while (num_fds-- > start_num_fds) { - if (close(fds[num_fds]) < 0) { - ModuleLog(i, BLOG_ERROR, "close failed"); - } - } - NCDBProcessOpts_Free(&opts); - - o->read_fd = -1; - o->write_fd = -1; - o->state = PROCESS_STATE_ERROR; - NCDModuleInst_Backend_Up(i); -} - -static void process_func_die (void *vo) -{ - struct process_instance *o = vo; - ASSERT(o->state != PROCESS_STATE_DYING) - - // if process is not running, die immediately - if (o->state != PROCESS_STATE_RUNNING) { - process_free(o); - return; - } - - if (o->term_on_deinit) { - ModuleLog(o->i, BLOG_INFO, "terminating process"); - - // send termination signal - BProcess_Terminate(&o->process); - } else { - ModuleLog(o->i, BLOG_INFO, "not terminating process as requested"); - } - - if (o->deinit_kill_time == -1) { - // user wants SIGKILL immediately - ModuleLog(o->i, BLOG_INFO, "killing process immediately"); - BProcess_Kill(&o->process); - } else if (o->deinit_kill_time >= 0) { - // user wants SIGKILL after some time - BReactor_SetSmallTimer(o->i->params->iparams->reactor, &o->kill_timer, BTIMER_SET_RELATIVE, o->deinit_kill_time); - } - - // set state - o->state = PROCESS_STATE_DYING; -} - -static int process_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct process_instance *o = vo; - - if (name == NCD_STRING_IS_ERROR) { - int is_error = (o->state == PROCESS_STATE_ERROR); - *out = ncd_make_boolean(mem, is_error, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void wait_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct wait_instance *o = vo; - o->i = i; - - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct process_instance *pinst = params->method_user; - - if (pinst->state == PROCESS_STATE_ERROR) { - ModuleLog(i, BLOG_ERROR, "wait() is disallowed after the process has failed to start"); - goto fail0; - } - - if (pinst->state == PROCESS_STATE_TERMINATED) { - // not waiting, set no pinst - o->pinst = NULL; - - // remember exit code - o->exit_status = pinst->exit_status; - - // go up - NCDModuleInst_Backend_Up(i); - } else { - // waitint, set pinst - o->pinst = pinst; - - // insert to waits list - LinkedList0_Prepend(&pinst->waits_list, &o->waits_list_node); - } - - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void wait_func_die (void *vo) -{ - struct wait_instance *o = vo; - - // remove from waits list - if (o->pinst) { - LinkedList0_Remove(&o->pinst->waits_list, &o->waits_list_node); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int wait_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct wait_instance *o = vo; - ASSERT(!o->pinst) - - if (name == NCD_STRING_EXIT_STATUS) { - if (o->exit_status == -1) { - *out = NCDVal_NewString(mem, "-1"); - } else { - *out = ncd_make_uintmax(mem, o->exit_status); - } - return 1; - } - - return 0; -} - -static void terminate_kill_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_kill) -{ - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct process_instance *pinst = params->method_user; - - if (pinst->state == PROCESS_STATE_ERROR) { - ModuleLog(i, BLOG_ERROR, "terminate()/kill() is disallowed after the process has failed to start"); - goto fail0; - } - - if (pinst->state != PROCESS_STATE_TERMINATED) { - if (is_kill) { - BProcess_Kill(&pinst->process); - } else { - BProcess_Terminate(&pinst->process); - } - } - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void terminate_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - terminate_kill_new_common(vo, i, params, 0); -} - -static void kill_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - terminate_kill_new_common(vo, i, params, 1); -} - -static void read_pipe_free_connection (struct read_pipe_instance *o) -{ - // disconnect read instance - if (o->read_inst) { - ASSERT(o->read_inst->read_pipe_inst == o) - o->read_inst->read_pipe_inst = NULL; - } - - // free store - NCDBufStore_Free(&o->store); - - // free connection read interface - BConnection_RecvAsync_Free(&o->connection); - - // free connection - BConnection_Free(&o->connection); - - // close fd - if (close(o->read_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } -} - -static void read_pipe_abort (struct read_pipe_instance *o) -{ - ASSERT(o->state == READER_STATE_RUNNING) - - // release connection resources - read_pipe_free_connection(o); - - // set state - o->state = READER_STATE_ABORTED; -} - -static void read_pipe_connection_handler (void *vo, int event) -{ - struct read_pipe_instance *o = vo; - ASSERT(o->state == READER_STATE_RUNNING) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - // if we have read operation, make it finish with eof - if (o->read_inst) { - ASSERT(o->read_inst->read_pipe_inst == o) - ASSERT(o->read_inst->buf) - o->read_inst->read_pipe_inst = NULL; - o->read_inst->read_size = 0; - NCDModuleInst_Backend_Up(o->read_inst->i); - o->read_inst = NULL; - } - - // free connection resources - read_pipe_free_connection(o); - - // set state closed - o->state = READER_STATE_EOF; - return; - } - - ModuleLog(o->i, BLOG_ERROR, "read pipe error"); - - // free connection resources - read_pipe_free_connection(o); - - // set state error - o->state = READER_STATE_ERROR; - - // backtrack - NCDModuleInst_Backend_DownUp(o->i); -} - -static void read_pipe_recv_handler_done (void *vo, int data_len) -{ - struct read_pipe_instance *o = vo; - ASSERT(o->state == READER_STATE_RUNNING) - ASSERT(o->read_inst) - ASSERT(o->read_inst->read_pipe_inst == o) - ASSERT(o->read_inst->buf) - ASSERT(data_len > 0) - ASSERT(data_len <= NCDBufStore_BufSize(&o->store)) - - // finish read operation - o->read_inst->read_pipe_inst = NULL; - o->read_inst->read_size = data_len; - NCDModuleInst_Backend_Up(o->read_inst->i); - o->read_inst = NULL; -} - -static void read_pipe_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct read_pipe_instance *o = vo; - o->i = i; - NCDModuleInst_Backend_PassMemToMethods(i); - - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct process_instance *pinst = params->method_user; - - if (pinst->read_fd == -1) { - ModuleLog(i, BLOG_ERROR, "process did not start successfully, was not opened for reading or a read_pipe was already created"); - goto fail0; - } - - // init connection - if (!BConnection_Init(&o->connection, BConnection_source_pipe(pinst->read_fd), i->params->iparams->reactor, o, read_pipe_connection_handler)) { - ModuleLog(i, BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - // init connection read interface - BConnection_RecvAsync_Init(&o->connection); - - // set recv done callback - StreamRecvInterface_Receiver_Init(BConnection_RecvAsync_GetIf(&o->connection), read_pipe_recv_handler_done, o); - - // init store - NCDBufStore_Init(&o->store, READ_BUF_SIZE); - - // set variables - o->state = READER_STATE_RUNNING; - o->read_fd = pinst->read_fd; - o->read_inst = NULL; - - // steal read fd from process instance - pinst->read_fd = -1; - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void read_pipe_func_die (void *vo) -{ - struct read_pipe_instance *o = vo; - - // free connection resources - if (o->state == READER_STATE_RUNNING) { - read_pipe_free_connection(o); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int read_pipe_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct read_pipe_instance *o = vo; - - if (name == NCD_STRING_IS_ERROR) { - int is_error = (o->state == READER_STATE_ERROR); - *out = ncd_make_boolean(mem, is_error, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void read_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct read_instance *o = vo; - o->i = i; - - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct read_pipe_instance *read_pipe_inst = params->method_user; - - // check if a read error has already occured - if (read_pipe_inst->state == READER_STATE_ERROR) { - ModuleLog(i, BLOG_ERROR, "read() is disallowed after a read error has occured"); - goto fail0; - } - - // check if the read_pipe has been aborted - if (read_pipe_inst->state == READER_STATE_ABORTED) { - ModuleLog(i, BLOG_ERROR, "read() is disallowed after a read() has been aborted"); - goto fail0; - } - - // if EOF has already been encountered, complete the read immediately - if (read_pipe_inst->state == READER_STATE_EOF) { - o->buf = NULL; - o->read_pipe_inst = NULL; - o->read_size = 0; - NCDModuleInst_Backend_Up(i); - return; - } - - ASSERT(read_pipe_inst->state == READER_STATE_RUNNING) - - // check if there's already a read in progress - if (read_pipe_inst->read_inst) { - ModuleLog(i, BLOG_ERROR, "read() is disallowed while another read() is in progress"); - goto fail0; - } - - // get buffer - o->buf = NCDBufStore_GetBuf(&read_pipe_inst->store); - if (!o->buf) { - ModuleLog(i, BLOG_ERROR, "NCDBufStore_GetBuf failed"); - goto fail0; - } - - // set read_pipe - o->read_pipe_inst = read_pipe_inst; - - // register read in read_pipe - read_pipe_inst->read_inst = o; - - // receive - size_t buf_size = NCDBufStore_BufSize(&read_pipe_inst->store); - int to_read = (buf_size > INT_MAX ? INT_MAX : buf_size); - StreamRecvInterface_Receiver_Recv(BConnection_RecvAsync_GetIf(&read_pipe_inst->connection), (uint8_t *)NCDBuf_Data(o->buf), to_read); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void read_func_die (void *vo) -{ - struct read_instance *o = vo; - - // if we're receiving, abort read_pipe - if (o->read_pipe_inst) { - ASSERT(o->read_pipe_inst->state == READER_STATE_RUNNING) - ASSERT(o->read_pipe_inst->read_inst == o) - ASSERT(o->buf) - read_pipe_abort(o->read_pipe_inst); - } - - // release buffer - if (o->buf) { - BRefTarget_Deref(NCDBuf_RefTarget(o->buf)); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int read_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct read_instance *o = vo; - ASSERT(!o->read_pipe_inst) - ASSERT(!(o->read_size > 0) || o->buf) - - if (name == NCD_STRING_EMPTY) { - if (o->read_size > 0) { - *out = NCDVal_NewExternalString(mem, NCDBuf_Data(o->buf), o->read_size, NCDBuf_RefTarget(o->buf)); - } else { - *out = NCDVal_NewIdString(mem, NCD_STRING_EMPTY, o->i->params->iparams->string_index); - } - return 1; - } - - if (name == NCD_STRING_NOT_EOF) { - int not_eof = (o->read_size > 0); - *out = ncd_make_boolean(mem, not_eof, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void write_pipe_free_connection (struct write_pipe_instance *o) -{ - // disconnect write instance - if (o->write_inst) { - ASSERT(o->write_inst->write_pipe_inst == o) - o->write_inst->write_pipe_inst = NULL; - } - - // free connection send interface - BConnection_SendAsync_Free(&o->connection); - - // free connection - BConnection_Free(&o->connection); - - // close fd - if (close(o->write_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } -} - -static void write_pipe_abort (struct write_pipe_instance *o) -{ - ASSERT(o->state == WRITER_STATE_RUNNING) - - // release connection resources - write_pipe_free_connection(o); - - // set state - o->state = WRITER_STATE_ABORTED; -} - -static void write_pipe_close (struct write_pipe_instance *o) -{ - ASSERT(o->state == WRITER_STATE_RUNNING) - - // release connection resources - write_pipe_free_connection(o); - - // set state - o->state = WRITER_STATE_CLOSED; -} - -static void write_pipe_connection_handler (void *vo, int event) -{ - struct write_pipe_instance *o = vo; - ASSERT(o->state == WRITER_STATE_RUNNING) - - ModuleLog(o->i, BLOG_ERROR, "write pipe error"); - - // free connection resources - write_pipe_free_connection(o); - - // set state error - o->state = WRITER_STATE_ERROR; - - // backtrack - NCDModuleInst_Backend_DownUp(o->i); -} - -static void write_pipe_send_handler_done (void *vo, int data_len) -{ - struct write_pipe_instance *o = vo; - ASSERT(o->state == WRITER_STATE_RUNNING) - ASSERT(o->write_inst) - ASSERT(o->write_inst->write_pipe_inst == o) - ASSERT(data_len > 0) - ASSERT(data_len <= o->write_inst->cstr.length - o->write_inst->pos) - - struct write_instance *wr = o->write_inst; - - // update write progress - wr->pos += data_len; - - // if there is more data, start another write operation - if (wr->pos < wr->cstr.length) { - size_t chunk_length; - const char *chunk_data = b_cstring_get(wr->cstr, wr->pos, wr->cstr.length - wr->pos, &chunk_length); - size_t to_send = (chunk_length > INT_MAX ? INT_MAX : chunk_length); - StreamPassInterface_Sender_Send(BConnection_SendAsync_GetIf(&o->connection), (uint8_t *)chunk_data, to_send); - return; - } - - // finish write operation - wr->write_pipe_inst = NULL; - NCDModuleInst_Backend_Up(wr->i); - o->write_inst = NULL; -} - -static void write_pipe_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct write_pipe_instance *o = vo; - o->i = i; - NCDModuleInst_Backend_PassMemToMethods(i); - - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct process_instance *pinst = params->method_user; - - if (pinst->write_fd == -1) { - ModuleLog(i, BLOG_ERROR, "process did not start successfully, was not opened for writing or a write_pipe was already created"); - goto fail0; - } - - // init connection - if (!BConnection_Init(&o->connection, BConnection_source_pipe(pinst->write_fd), i->params->iparams->reactor, o, write_pipe_connection_handler)) { - ModuleLog(i, BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - // init connection send interface - BConnection_SendAsync_Init(&o->connection); - - // set send done callback - StreamPassInterface_Sender_Init(BConnection_SendAsync_GetIf(&o->connection), write_pipe_send_handler_done, o); - - // set variables - o->state = WRITER_STATE_RUNNING; - o->write_fd = pinst->write_fd; - o->write_inst = NULL; - - // steal write fd from process instance - pinst->write_fd = -1; - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void write_pipe_func_die (void *vo) -{ - struct write_pipe_instance *o = vo; - - // free connection resources - if (o->state == WRITER_STATE_RUNNING) { - write_pipe_free_connection(o); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static int write_pipe_func_getvar (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct write_pipe_instance *o = vo; - - if (name == NCD_STRING_IS_ERROR) { - int is_error = (o->state == WRITER_STATE_ERROR); - *out = ncd_make_boolean(mem, is_error, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void write_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct write_instance *o = vo; - o->i = i; - - NCDValRef data_arg; - if (!NCDVal_ListRead(params->args, 1, &data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - struct write_pipe_instance *write_pipe_inst = params->method_user; - - // check if a write error has already occured - if (write_pipe_inst->state == WRITER_STATE_ERROR) { - ModuleLog(i, BLOG_ERROR, "write() is disallowed after a write error has occured"); - goto fail0; - } - - // check if the write_pipe has been aborted - if (write_pipe_inst->state == WRITER_STATE_ABORTED) { - ModuleLog(i, BLOG_ERROR, "write() is disallowed after a write() has been aborted"); - goto fail0; - } - - // check if the write_pipe has been aborted - if (write_pipe_inst->state == WRITER_STATE_CLOSED) { - ModuleLog(i, BLOG_ERROR, "write() is disallowed after close() has been called"); - goto fail0; - } - - ASSERT(write_pipe_inst->state == WRITER_STATE_RUNNING) - - // check if there's already a write in progress - if (write_pipe_inst->write_inst) { - ModuleLog(i, BLOG_ERROR, "write() is disallowed while another write() is in progress"); - goto fail0; - } - - // initialize write progress state - o->cstr = NCDVal_StringCstring(data_arg); - o->pos = 0; - - // if there's nothing to send, go up immediately - if (o->cstr.length == 0) { - o->write_pipe_inst = NULL; - NCDModuleInst_Backend_Up(i); - return; - } - - // set write_pipe - o->write_pipe_inst = write_pipe_inst; - - // register write in write_pipe - write_pipe_inst->write_inst = o; - - // start send operation - size_t chunk_length; - const char *chunk_data = b_cstring_get(o->cstr, o->pos, o->cstr.length - o->pos, &chunk_length); - size_t to_send = (chunk_length > INT_MAX ? INT_MAX : chunk_length); - StreamPassInterface_Sender_Send(BConnection_SendAsync_GetIf(&write_pipe_inst->connection), (uint8_t *)chunk_data, to_send); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void write_func_die (void *vo) -{ - struct write_instance *o = vo; - - // if we're sending, abort write_pipe - if (o->write_pipe_inst) { - ASSERT(o->write_pipe_inst->state == WRITER_STATE_RUNNING) - ASSERT(o->write_pipe_inst->write_inst == o) - write_pipe_abort(o->write_pipe_inst); - } - - NCDModuleInst_Backend_Dead(o->i); -} - -static void close_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct write_pipe_instance *write_pipe_inst = params->method_user; - - // check if a write error has already occured - if (write_pipe_inst->state == WRITER_STATE_ERROR) { - ModuleLog(i, BLOG_ERROR, "close() is disallowed after a write error has occured"); - goto fail0; - } - - // check if the write_pipe has been aborted - if (write_pipe_inst->state == WRITER_STATE_ABORTED) { - ModuleLog(i, BLOG_ERROR, "close() is disallowed after a write() has been aborted"); - goto fail0; - } - - // check if the write_pipe has been closed - if (write_pipe_inst->state == WRITER_STATE_CLOSED) { - ModuleLog(i, BLOG_ERROR, "close() is disallowed after close() has been called"); - goto fail0; - } - - // close - write_pipe_close(write_pipe_inst); - - // go up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.start_process", - .func_new2 = process_func_new, - .func_die = process_func_die, - .func_getvar2 = process_func_getvar, - .alloc_size = sizeof(struct process_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::wait", - .func_new2 = wait_func_new, - .func_die = wait_func_die, - .func_getvar2 = wait_func_getvar, - .alloc_size = sizeof(struct wait_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::terminate", - .func_new2 = terminate_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::kill", - .func_new2 = kill_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::read_pipe", - .func_new2 = read_pipe_func_new, - .func_die = read_pipe_func_die, - .func_getvar2 = read_pipe_func_getvar, - .alloc_size = sizeof(struct read_pipe_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::read_pipe::read", - .func_new2 = read_func_new, - .func_die = read_func_die, - .func_getvar2 = read_func_getvar, - .alloc_size = sizeof(struct read_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::write_pipe", - .func_new2 = write_pipe_func_new, - .func_die = write_pipe_func_die, - .func_getvar2 = write_pipe_func_getvar, - .alloc_size = sizeof(struct write_pipe_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::write_pipe::write", - .func_new2 = write_func_new, - .func_die = write_func_die, - .alloc_size = sizeof(struct write_instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "sys.start_process::write_pipe::close", - .func_new2 = close_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_start_process = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/sys_watch_directory.c b/external/badvpn_dns/ncd/modules/sys_watch_directory.c deleted file mode 100644 index 41f7d42..0000000 --- a/external/badvpn_dns/ncd/modules/sys_watch_directory.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @file sys_watch_directory.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Directory watcher. - * - * Synopsis: sys.watch_directory(string dir) - * Description: reports directory entry events. Transitions up when an event is detected, and - * goes down waiting for the next event when sys.watch_directory::nextevent() is called. - * The directory is first scanned and "added" events are reported for all files. - * Variables: - * string event_type - what happened with the file: "added", "removed" or "changed" - * string filename - name of the file in the directory the event refers to - * string filepath - "dir/filename" - * - * Synopsis: sys.watch_directory::nextevent() - * Description: makes the watch_directory module transition down in order to report the next event. - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/inotify.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> - -#include <misc/nonblocking.h> -#include <misc/concat_strings.h> - -#include <ncd/NCDModule.h> - -#include <generated/blog_channel_ncd_sys_watch_directory.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define MAX_INOTIFY_EVENTS 128 - -struct instance { - NCDModuleInst *i; - NCDValNullTermString dir_nts; - DIR *dir_handle; - int inotify_fd; - BFileDescriptor bfd; - struct inotify_event events[MAX_INOTIFY_EVENTS]; - int events_count; - int events_index; - int processing; - const char *processing_file; - const char *processing_type; -}; - -static void instance_free (struct instance *o, int is_error); - -static void next_dir_event (struct instance *o) -{ - ASSERT(!o->processing) - ASSERT(o->dir_handle) - - struct dirent *entry; - - do { - // get next entry - errno = 0; - if (!(entry = readdir(o->dir_handle))) { - if (errno != 0) { - ModuleLog(o->i, BLOG_ERROR, "readdir failed"); - instance_free(o, 1); - return; - } - - // close directory - if (closedir(o->dir_handle) < 0) { - ModuleLog(o->i, BLOG_ERROR, "closedir failed"); - o->dir_handle = NULL; - instance_free(o, 1); - return; - } - - // set no dir handle - o->dir_handle = NULL; - - // start receiving inotify events - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, BREACTOR_READ); - return; - } - } while (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")); - - // set event - o->processing_file = entry->d_name; - o->processing_type = "added"; - o->processing = 1; - - // signal up - NCDModuleInst_Backend_Up(o->i); -} - -static void assert_inotify_event (struct instance *o) -{ - ASSERT(o->events_index < o->events_count) - ASSERT(o->events[o->events_index].len % sizeof(o->events[0]) == 0) - ASSERT(o->events[o->events_index].len / sizeof(o->events[0]) <= o->events_count - (o->events_index + 1)) -} - -static const char * translate_inotify_event (struct instance *o) -{ - assert_inotify_event(o); - - struct inotify_event *event = &o->events[o->events_index]; - - if (strlen(event->name) > 0) { - if ((event->mask & (IN_CREATE | IN_MOVED_TO))) { - return "added"; - } - if ((event->mask & (IN_DELETE | IN_MOVED_FROM))) { - return "removed"; - } - if ((event->mask & IN_MODIFY)) { - return "changed"; - } - } - - return NULL; -} - -static void skip_inotify_event (struct instance *o) -{ - assert_inotify_event(o); - - o->events_index += 1 + o->events[o->events_index].len / sizeof(o->events[0]); -} - -static void next_inotify_event (struct instance *o) -{ - ASSERT(!o->processing) - ASSERT(!o->dir_handle) - - // skip any bad events - while (o->events_index < o->events_count && !translate_inotify_event(o)) { - ModuleLog(o->i, BLOG_ERROR, "unknown inotify event"); - skip_inotify_event(o); - } - - if (o->events_index == o->events_count) { - // wait for more events - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, BREACTOR_READ); - return; - } - - // set event - o->processing_file = o->events[o->events_index].name; - o->processing_type = translate_inotify_event(o); - o->processing = 1; - - // consume this event - skip_inotify_event(o); - - // signal up - NCDModuleInst_Backend_Up(o->i); -} - -static void inotify_fd_handler (struct instance *o, int events) -{ - if (o->processing) { - ModuleLog(o->i, BLOG_ERROR, "file descriptor error"); - instance_free(o, 1); - return; - } - - ASSERT(!o->dir_handle) - - int res = read(o->inotify_fd, o->events, sizeof(o->events)); - if (res < 0) { - ModuleLog(o->i, BLOG_ERROR, "read failed"); - instance_free(o, 1); - return; - } - - // stop waiting for inotify events - BReactor_SetFileDescriptorEvents(o->i->params->iparams->reactor, &o->bfd, 0); - - ASSERT(res <= sizeof(o->events)) - ASSERT(res % sizeof(o->events[0]) == 0) - - // setup buffer state - o->events_count = res / sizeof(o->events[0]); - o->events_index = 0; - - // process inotify events - next_inotify_event(o); -} - -static void next_event (struct instance *o) -{ - ASSERT(o->processing) - - // set not processing - o->processing = 0; - - // signal down - NCDModuleInst_Backend_Down(o->i); - - if (o->dir_handle) { - next_dir_event(o); - return; - } else { - next_inotify_event(o); - return; - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef dir_arg; - if (!NCDVal_ListRead(params->args, 1, &dir_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsStringNoNulls(dir_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // null terminate dir - if (!NCDVal_StringNullTerminate(dir_arg, &o->dir_nts)) { - ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); - goto fail0; - } - - // open inotify - if ((o->inotify_fd = inotify_init()) < 0) { - ModuleLog(o->i, BLOG_ERROR, "inotify_init failed"); - goto fail1; - } - - // add watch - if (inotify_add_watch(o->inotify_fd, o->dir_nts.data, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO) < 0) { - ModuleLog(o->i, BLOG_ERROR, "inotify_add_watch failed"); - goto fail2; - } - - // set non-blocking - if (!badvpn_set_nonblocking(o->inotify_fd)) { - ModuleLog(o->i, BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail2; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->inotify_fd, (BFileDescriptor_handler)inotify_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->i->params->iparams->reactor, &o->bfd)) { - ModuleLog(o->i, BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail2; - } - - // open directory - if (!(o->dir_handle = opendir(o->dir_nts.data))) { - ModuleLog(o->i, BLOG_ERROR, "opendir failed"); - goto fail3; - } - - // set not processing - o->processing = 0; - - // read first directory entry - next_dir_event(o); - return; - -fail3: - BReactor_RemoveFileDescriptor(o->i->params->iparams->reactor, &o->bfd); -fail2: - if (close(o->inotify_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } -fail1: - NCDValNullTermString_Free(&o->dir_nts); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -void instance_free (struct instance *o, int is_error) -{ - // close directory - if (o->dir_handle) { - if (closedir(o->dir_handle) < 0) { - ModuleLog(o->i, BLOG_ERROR, "closedir failed"); - } - } - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->i->params->iparams->reactor, &o->bfd); - - // close inotify - if (close(o->inotify_fd) < 0) { - ModuleLog(o->i, BLOG_ERROR, "close failed"); - } - - // free dir nts - NCDValNullTermString_Free(&o->dir_nts); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - instance_free(o, 0); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->processing) - - if (!strcmp(name, "event_type")) { - *out = NCDVal_NewString(mem, o->processing_type); - return 1; - } - - if (!strcmp(name, "filename")) { - *out = NCDVal_NewString(mem, o->processing_file); - return 1; - } - - if (!strcmp(name, "filepath")) { - char *str = concat_strings(3, o->dir_nts.data, "/", o->processing_file); - if (!str) { - ModuleLog(o->i, BLOG_ERROR, "concat_strings failed"); - goto fail; - } - - *out = NCDVal_NewString(mem, str); - - free(str); - return 1; - } - - return 0; - -fail: - *out = NCDVal_NewInvalid(); - return 1; -} - -static void nextevent_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure we are currently reporting an event - if (!mo->processing) { - ModuleLog(i, BLOG_ERROR, "not reporting an event"); - goto fail0; - } - - // signal up. - // Do it before finishing the event so our process does not advance any further if - // we would be killed the event provider going down. - NCDModuleInst_Backend_Up(i); - - // wait for next event - next_event(mo); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.watch_directory", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.watch_directory::nextevent", - .func_new2 = nextevent_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_watch_directory = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/sys_watch_input.c b/external/badvpn_dns/ncd/modules/sys_watch_input.c deleted file mode 100644 index 6039bee..0000000 --- a/external/badvpn_dns/ncd/modules/sys_watch_input.c +++ /dev/null @@ -1,455 +0,0 @@ -/** - * @file sys_watch_input.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Input device watcher. - * - * Synopsis: sys.watch_input(string devnode_type) - * Description: reports input device events. Transitions up when an event is detected, and - * goes down waiting for the next event when sys.watch_input::nextevent() is called. - * On startup, "added" events are reported for existing input devices. - * Arguments: - * string devnode_type - device node type, for example "event", "mouse" or "js". - * Variables: - * string event_type - what happened with the input device: "added" or "removed" - * string devname - device node path - * string device_type - input device type, "tablet", "joystick", "touchscreen", "mouse", - * "touchpad", "key", "keyboard" or "unknown" - * - * Synopsis: sys.watch_input::nextevent() - * Description: makes the watch_input module transition down in order to report the next event. - */ - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <structure/LinkedList1.h> -#include <udevmonitor/NCDUdevManager.h> -#include <ncd/NCDModule.h> -#include <ncd/modules/event_template.h> - -#include <generated/blog_channel_ncd_sys_watch_input.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct device { - char *devname; - char *devpath; - BStringMap removed_map; - LinkedList1Node devices_list_node; -}; - -struct instance { - NCDModuleInst *i; - const char *devnode_type; - size_t devnode_type_len; - NCDUdevClient client; - LinkedList1 devices_list; - event_template templ; -}; - -static void templ_func_free (struct instance *o, int is_error); - -static struct device * find_device_by_devname (struct instance *o, const char *devname) -{ - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); - while (list_node) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->devname, devname)) { - return device; - } - list_node = LinkedList1Node_Next(list_node); - } - - return NULL; -} - -static struct device * find_device_by_devpath (struct instance *o, const char *devpath) -{ - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); - while (list_node) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->devpath, devpath)) { - return device; - } - list_node = LinkedList1Node_Next(list_node); - } - - return NULL; -} - -static void free_device (struct instance *o, struct device *device, int have_removed_map) -{ - // remove from devices list - LinkedList1_Remove(&o->devices_list, &device->devices_list_node); - - // free removed map - if (have_removed_map) { - BStringMap_Free(&device->removed_map); - } - - // free devpath - free(device->devpath); - - // free devname - free(device->devname); - - // free structure - free(device); -} - -static int make_event_map (struct instance *o, int added, const char *devname, const char *device_type, BStringMap *out_map) -{ - // init map - BStringMap map; - BStringMap_Init(&map); - - // set type - if (!BStringMap_Set(&map, "event_type", (added ? "added" : "removed"))) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set devname - if (!BStringMap_Set(&map, "devname", devname)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set device type - if (!BStringMap_Set(&map, "device_type", device_type)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - *out_map = map; - return 1; - -fail1: - BStringMap_Free(&map); - return 0; -} - -static int devname_is_type (const char *devname, const char *devname_type, size_t devname_type_len) -{ - // skip digits at the end - size_t i; - for (i = strlen(devname); i > 0; i--) { - if (!isdigit(devname[i - 1])) { - break; - } - } - - // check if devname_type precedes skipped digits - for (size_t j = devname_type_len; j > 0; j--) { - if (!(i > 0 && devname[i - 1] == devname_type[j - 1])) { - return 0; - } - i--; - } - - // check if slash precedes devname_type - if (!(i > 0 && devname[i - 1] == '/')) { - return 0; - } - - return 1; -} - -static void queue_event (struct instance *o, BStringMap map) -{ - // pass event to template - int was_empty; - event_template_queue(&o->templ, map, &was_empty); - - // if event queue was empty, stop receiving udev events - if (was_empty) { - NCDUdevClient_Pause(&o->client); - } -} - -static void add_device (struct instance *o, const char *devname, const char *devpath, const char *device_type) -{ - ASSERT(!find_device_by_devname(o, devname)) - ASSERT(!find_device_by_devpath(o, devpath)) - - // allocate structure - struct device *device = malloc(sizeof(*device)); - if (!device) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init devname - if (!(device->devname = strdup(devname))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail1; - } - - // init devpath - if (!(device->devpath = strdup(devpath))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail2; - } - - // init removed map - if (!make_event_map(o, 0, devname, device_type, &device->removed_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail3; - } - - // init added map - BStringMap added_map; - if (!make_event_map(o, 1, devname, device_type, &added_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail4; - } - - // insert to devices list - LinkedList1_Append(&o->devices_list, &device->devices_list_node); - - // queue event - queue_event(o, added_map); - - return; - -fail4: - BStringMap_Free(&device->removed_map); -fail3: - free(device->devpath); -fail2: - free(device->devname); -fail1: - free(device); -fail0: - ModuleLog(o->i, BLOG_ERROR, "failed to add device %s", devname); -} - -static void remove_device (struct instance *o, struct device *device) -{ - queue_event(o, device->removed_map); - free_device(o, device, 0); -} - -static void next_event (struct instance *o) -{ - ASSERT(event_template_is_enabled(&o->templ)) - - // order template to finish the current event - int is_empty; - event_template_dequeue(&o->templ, &is_empty); - - // if template has no events, continue udev events - if (is_empty) { - NCDUdevClient_Continue(&o->client); - } -} - -static void client_handler (struct instance *o, char *devpath, int have_map, BStringMap map) -{ - // lookup existing device with this devpath - struct device *ex_device = find_device_by_devpath(o, devpath); - // lookup cache entry - const BStringMap *cache_map = NCDUdevManager_Query(o->i->params->iparams->umanager, devpath); - - if (!cache_map) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - const char *subsystem = BStringMap_Get(cache_map, "SUBSYSTEM"); - const char *devname = BStringMap_Get(cache_map, "DEVNAME"); - - if (!(subsystem && !strcmp(subsystem, "input") && devname && devname_is_type(devname, o->devnode_type, o->devnode_type_len))) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - if (ex_device && strcmp(ex_device->devname, devname)) { - remove_device(o, ex_device); - ex_device = NULL; - } - - if (!ex_device) { - struct device *ex_devname_device = find_device_by_devname(o, devname); - if (ex_devname_device) { - remove_device(o, ex_devname_device); - } - - // determine type - const char *device_type = "unknown"; - if (BStringMap_Get(cache_map, "ID_INPUT_TABLET")) { - device_type = "tablet"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_JOYSTICK")) { - device_type = "joystick"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_TOUCHSCREEN")) { - device_type = "touchscreen"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_MOUSE")) { - device_type = "mouse"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_TOUCHPAD")) { - device_type = "touchpad"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_KEY")) { - device_type = "key"; - } - else if (BStringMap_Get(cache_map, "ID_INPUT_KEYBOARD")) { - device_type = "keyboard"; - } - - add_device(o, devname, devpath, device_type); - } - -out: - free(devpath); - if (have_map) { - BStringMap_Free(&map); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef devnode_type_arg; - if (!NCDVal_ListRead(params->args, 1, &devnode_type_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(devnode_type_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - o->devnode_type = NCDVal_StringData(devnode_type_arg); - o->devnode_type_len = NCDVal_StringLength(devnode_type_arg); - - // init client - NCDUdevClient_Init(&o->client, o->i->params->iparams->umanager, o, (NCDUdevClient_handler)client_handler); - - // init devices list - LinkedList1_Init(&o->devices_list); - - event_template_new(&o->templ, o->i, BLOG_CURRENT_CHANNEL, 3, o, (event_template_func_free)templ_func_free); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void templ_func_free (struct instance *o, int is_error) -{ - // free devices - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&o->devices_list)) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - free_device(o, device, 1); - } - - // free client - NCDUdevClient_Free(&o->client); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - event_template_die(&o->templ); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - return event_template_getvar(&o->templ, name, mem, out); -} - -static void nextevent_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure we are currently reporting an event - if (!event_template_is_enabled(&mo->templ)) { - ModuleLog(i, BLOG_ERROR, "not reporting an event"); - goto fail0; - } - - // signal up. - // Do it before finishing the event so our process does not advance any further if - // we would be killed the event provider going down. - NCDModuleInst_Backend_Up(i); - - // wait for next event - next_event(mo); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.watch_input", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.watch_input::nextevent", - .func_new2 = nextevent_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_watch_input = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/sys_watch_usb.c b/external/badvpn_dns/ncd/modules/sys_watch_usb.c deleted file mode 100644 index d2e6b1c..0000000 --- a/external/badvpn_dns/ncd/modules/sys_watch_usb.c +++ /dev/null @@ -1,421 +0,0 @@ -/** - * @file sys_watch_usb.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * USB device watcher. - * - * Synopsis: sys.watch_usb() - * Description: reports USB device events. Transitions up when an event is detected, and - * goes down waiting for the next event when ->nextevent() is called. - * On startup, "added" events are reported for existing USB devices. - * - * Variables: - * string event_type - what happened with the USB device: "added" or "removed" - * string devname - device node path, e.g. /dev/bus/usb/XXX/YYY - * string vendor_id - vendor ID, e.g. 046d - * string model_id - model ID, e.g. c03e - * - * Synopsis: sys.watch_usb::nextevent() - * Description: makes the watch_usb module transition down in order to report the next event. - */ - -#include <inttypes.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/parse_number.h> -#include <structure/LinkedList1.h> -#include <udevmonitor/NCDUdevManager.h> -#include <ncd/NCDModule.h> -#include <ncd/modules/event_template.h> - -#include <generated/blog_channel_ncd_sys_watch_usb.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct device { - char *devname; - char *devpath; - uint16_t vendor_id; - uint16_t model_id; - BStringMap removed_map; - LinkedList1Node devices_list_node; -}; - -struct instance { - NCDModuleInst *i; - NCDUdevClient client; - LinkedList1 devices_list; - event_template templ; -}; - -static void templ_func_free (struct instance *o, int is_error); - -static struct device * find_device_by_devname (struct instance *o, const char *devname) -{ - for (LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); list_node; list_node = LinkedList1Node_Next(list_node)) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->devname, devname)) { - return device; - } - } - - return NULL; -} - -static struct device * find_device_by_devpath (struct instance *o, const char *devpath) -{ - for (LinkedList1Node *list_node = LinkedList1_GetFirst(&o->devices_list); list_node; list_node = LinkedList1Node_Next(list_node)) { - struct device *device = UPPER_OBJECT(list_node, struct device, devices_list_node); - if (!strcmp(device->devpath, devpath)) { - return device; - } - } - - return NULL; -} - -static void free_device (struct instance *o, struct device *device, int have_removed_map) -{ - // remove from devices list - LinkedList1_Remove(&o->devices_list, &device->devices_list_node); - - // free removed map - if (have_removed_map) { - BStringMap_Free(&device->removed_map); - } - - // free devpath - free(device->devpath); - - // free devname - free(device->devname); - - // free structure - free(device); -} - -static int make_event_map (struct instance *o, int added, const char *devname, uint16_t vendor_id, uint16_t model_id, BStringMap *out_map) -{ - // init map - BStringMap map; - BStringMap_Init(&map); - - // set type - if (!BStringMap_Set(&map, "event_type", (added ? "added" : "removed"))) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set devname - if (!BStringMap_Set(&map, "devname", devname)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set vendor ID - char vendor_id_str[5]; - sprintf(vendor_id_str, "%04"PRIx16, vendor_id); - if (!BStringMap_Set(&map, "vendor_id", vendor_id_str)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - // set model ID - char model_id_str[5]; - sprintf(model_id_str, "%04"PRIx16, model_id); - if (!BStringMap_Set(&map, "model_id", model_id_str)) { - ModuleLog(o->i, BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - - *out_map = map; - return 1; - -fail1: - BStringMap_Free(&map); - return 0; -} - -static void queue_event (struct instance *o, BStringMap map) -{ - // pass event to template - int was_empty; - event_template_queue(&o->templ, map, &was_empty); - - // if event queue was empty, stop receiving udev events - if (was_empty) { - NCDUdevClient_Pause(&o->client); - } -} - -static void add_device (struct instance *o, const char *devname, const char *devpath, uint16_t vendor_id, uint16_t model_id) -{ - ASSERT(!find_device_by_devname(o, devname)) - ASSERT(!find_device_by_devpath(o, devpath)) - - // allocate structure - struct device *device = malloc(sizeof(*device)); - if (!device) { - ModuleLog(o->i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init devname - if (!(device->devname = strdup(devname))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail1; - } - - // init devpath - if (!(device->devpath = strdup(devpath))) { - ModuleLog(o->i, BLOG_ERROR, "strdup failed"); - goto fail2; - } - - // set vendor and model ID - device->vendor_id = vendor_id; - device->model_id = model_id; - - // init removed map - if (!make_event_map(o, 0, devname, vendor_id, model_id, &device->removed_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail3; - } - - // init added map - BStringMap added_map; - if (!make_event_map(o, 1, devname, vendor_id, model_id, &added_map)) { - ModuleLog(o->i, BLOG_ERROR, "make_event_map failed"); - goto fail4; - } - - // insert to devices list - LinkedList1_Append(&o->devices_list, &device->devices_list_node); - - // queue event - queue_event(o, added_map); - return; - -fail4: - BStringMap_Free(&device->removed_map); -fail3: - free(device->devpath); -fail2: - free(device->devname); -fail1: - free(device); -fail0: - ModuleLog(o->i, BLOG_ERROR, "failed to add device %s", devname); -} - -static void remove_device (struct instance *o, struct device *device) -{ - queue_event(o, device->removed_map); - free_device(o, device, 0); -} - -static void next_event (struct instance *o) -{ - ASSERT(event_template_is_enabled(&o->templ)) - - // order template to finish the current event - int is_empty; - event_template_dequeue(&o->templ, &is_empty); - - // if template has no events, continue udev events - if (is_empty) { - NCDUdevClient_Continue(&o->client); - } -} - -static void client_handler (struct instance *o, char *devpath, int have_map, BStringMap map) -{ - // lookup existing device with this devpath - struct device *ex_device = find_device_by_devpath(o, devpath); - // lookup cache entry - const BStringMap *cache_map = NCDUdevManager_Query(o->i->params->iparams->umanager, devpath); - - if (!cache_map) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - const char *subsystem = BStringMap_Get(cache_map, "SUBSYSTEM"); - const char *devname = BStringMap_Get(cache_map, "DEVNAME"); - const char *devtype = BStringMap_Get(cache_map, "DEVTYPE"); - const char *vendor_id_str = BStringMap_Get(cache_map, "ID_VENDOR_ID"); - const char *model_id_str = BStringMap_Get(cache_map, "ID_MODEL_ID"); - - uintmax_t vendor_id; - uintmax_t model_id; - - if (!(subsystem && !strcmp(subsystem, "usb") && - devname && - devtype && !strcmp(devtype, "usb_device") && - vendor_id_str && parse_unsigned_hex_integer(vendor_id_str, &vendor_id) && - model_id_str && parse_unsigned_hex_integer(model_id_str, &model_id) - )) { - if (ex_device) { - remove_device(o, ex_device); - } - goto out; - } - - if (ex_device && ( - strcmp(ex_device->devname, devname) || - ex_device->vendor_id != vendor_id || ex_device->model_id != model_id - )) { - remove_device(o, ex_device); - ex_device = NULL; - } - - if (!ex_device) { - struct device *ex_devname_device = find_device_by_devname(o, devname); - if (ex_devname_device) { - remove_device(o, ex_devname_device); - } - - add_device(o, devname, devpath, vendor_id, model_id); - } - -out: - free(devpath); - if (have_map) { - BStringMap_Free(&map); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init client - NCDUdevClient_Init(&o->client, o->i->params->iparams->umanager, o, (NCDUdevClient_handler)client_handler); - - // init devices list - LinkedList1_Init(&o->devices_list); - - event_template_new(&o->templ, o->i, BLOG_CURRENT_CHANNEL, 3, o, (event_template_func_free)templ_func_free); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void templ_func_free (struct instance *o, int is_error) -{ - // free devices - while (!LinkedList1_IsEmpty(&o->devices_list)) { - struct device *device = UPPER_OBJECT(LinkedList1_GetFirst(&o->devices_list), struct device, devices_list_node); - free_device(o, device, 1); - } - - // free client - NCDUdevClient_Free(&o->client); - - if (is_error) { - NCDModuleInst_Backend_DeadError(o->i); - } else { - NCDModuleInst_Backend_Dead(o->i); - } -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - event_template_die(&o->templ); -} - -static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - return event_template_getvar(&o->templ, name, mem, out); -} - -static void nextevent_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // make sure we are currently reporting an event - if (!event_template_is_enabled(&mo->templ)) { - ModuleLog(i, BLOG_ERROR, "not reporting an event"); - goto fail0; - } - - // signal up. - // Do it before finishing the event so our process does not advance any further if - // we would be killed the event provider going down. - NCDModuleInst_Backend_Up(i); - - // wait for next event - next_event(mo); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "sys.watch_usb", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar = func_getvar, - .alloc_size = sizeof(struct instance) - }, { - .type = "sys.watch_usb::nextevent", - .func_new2 = nextevent_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_sys_watch_usb = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/timer.c b/external/badvpn_dns/ncd/modules/timer.c deleted file mode 100644 index 6a748f9..0000000 --- a/external/badvpn_dns/ncd/modules/timer.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file timer.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * periodic_timer(string down_time, string up_time) - * - * Description: - * Periodically goes up and down. Starting in the down state, waits 'down_time' - * milliseconds. Then it goes up, and after 'up_time' milliseconds, goes back down, - * and the process repeats. When requested to terminate, terminates immedietely. - */ - -#include <stddef.h> - -#include <misc/debug.h> -#include <ncd/NCDModule.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_timer.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#define STATE_DOWN 1 -#define STATE_UP 2 - -struct instance { - NCDModuleInst *i; - btime_t down_time; - btime_t up_time; - BTimer timer; - int state; -}; - -static void timer_handler (void *vo) -{ - struct instance *o = vo; - - switch (o->state) { - case STATE_DOWN: { - o->state = STATE_UP; - BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, o->up_time); - NCDModuleInst_Backend_Up(o->i); - } break; - - case STATE_UP: { - o->state = STATE_DOWN; - BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, o->down_time); - NCDModuleInst_Backend_Down(o->i); - } break; - - default: ASSERT(0); - } -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef down_time_arg; - NCDValRef up_time_arg; - if (!NCDVal_ListRead(params->args, 2, &down_time_arg, &up_time_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(down_time_arg) || !NCDVal_IsString(up_time_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // read times - if (!ncd_read_time(down_time_arg, &o->down_time)) { - ModuleLog(o->i, BLOG_ERROR, "wrong down time"); - goto fail0; - } - if (!ncd_read_time(up_time_arg, &o->up_time)) { - ModuleLog(o->i, BLOG_ERROR, "wrong up time"); - goto fail0; - } - - // init timer - BTimer_Init(&o->timer, 0, timer_handler, o); - - // set state down - o->state = STATE_DOWN; - - // set timer - BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, o->down_time); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free timer - BReactor_RemoveTimer(o->i->params->iparams->reactor, &o->timer); - - NCDModuleInst_Backend_Dead(o->i); -} - -static struct NCDModule modules[] = { - { - .type = "periodic_timer", - .func_new2 = func_new, - .func_die = func_die, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_timer = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/to_string.c b/external/badvpn_dns/ncd/modules/to_string.c deleted file mode 100644 index 2380c34..0000000 --- a/external/badvpn_dns/ncd/modules/to_string.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file to_string.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * to_string(value) - * Variables: - * string (empty) - value, converted to string - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/NCDValGenerator.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_to_string.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - char *str; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read arguments - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // convert to string - if (!(o->str = NCDValGenerator_Generate(value_arg))) { - ModuleLog(i, BLOG_ERROR, "NCDValGenerator_Generate failed"); - goto fail0; - } - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free string - free(o->str); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewString(mem, o->str); - return 1; - } - - return 0; -} - -static struct NCDModule modules[] = { - { - .type = "to_string", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_to_string = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/try.c b/external/badvpn_dns/ncd/modules/try.c deleted file mode 100644 index 4c4613c..0000000 --- a/external/badvpn_dns/ncd/modules/try.c +++ /dev/null @@ -1,302 +0,0 @@ -/** - * @file try.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * try(string template_name, list args) - * - * Description: - * Does the following: - * 1. Starts a template process from the specified template and arguments. - * 2. Waits for the process to initialize completely, or for a _try->assert() - * assertion to fail. - * 3. Initiates termination of the process and waits for it to terminate. - * 4. Goes to up state. The "succeeded" variable reflects whether the process - * managed to initialize, or an assertion failed. - * If at any point during these steps termination of the try statement is - * requested, requests the process to terminate (if not already), and dies - * when it terminates. - * - * Variables: - * string succeeded - "true" if the template process finished, "false" if assert - * was called. - * - * Synopsis: - * try.try::assert(string cond) - * - * Description: - * Call as _try->assert() from the template process. If cond is "true", - * does nothing. Else, initiates termination of the process (if not already), - * and marks the try operation as not succeeded. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_try.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -struct instance { - NCDModuleInst *i; - NCDModuleProcess process; - int state; - int dying; - int succeeded; -}; - -#define STATE_INIT 1 -#define STATE_DEINIT 2 -#define STATE_FINISHED 3 - -static void process_handler_event (NCDModuleProcess *process, int event); -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); -static int process_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); -static void start_terminating (struct instance *o); -static void instance_free (struct instance *o); - -enum {STRING_TRY, STRING_TRY_TRY}; - -static const char *strings[] = { - "_try", "try.try", NULL -}; - -static void process_handler_event (NCDModuleProcess *process, int event) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - - switch (event) { - case NCDMODULEPROCESS_EVENT_UP: { - ASSERT(o->state == STATE_INIT) - - // start terminating - start_terminating(o); - } break; - - case NCDMODULEPROCESS_EVENT_DOWN: { - ASSERT(o->state == STATE_INIT) - - // continue - NCDModuleProcess_Continue(&o->process); - } break; - - case NCDMODULEPROCESS_EVENT_TERMINATED: { - ASSERT(o->state == STATE_DEINIT) - - // free process - NCDModuleProcess_Free(&o->process); - - // die finally if requested - if (o->dying) { - instance_free(o); - return; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - - // set state finished - o->state = STATE_FINISHED; - } break; - } -} - -static int process_func_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = UPPER_OBJECT(process, struct instance, process); - ASSERT(o->state == STATE_INIT || o->state == STATE_DEINIT) - - if (name == NCD_STRING_CALLER) { - *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, process_caller_object_func_getobj); - return 1; - } - - if (name == ModuleString(o->i, STRING_TRY)) { - *out_object = NCDObject_Build(ModuleString(o->i, STRING_TRY_TRY), o, NCDObject_no_getvar, NCDObject_no_getobj); - return 1; - } - - return 0; -} - -static int process_caller_object_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) -{ - struct instance *o = NCDObject_DataPtr(obj); - ASSERT(o->state == STATE_INIT || o->state == STATE_DEINIT) - - return NCDModuleInst_Backend_GetObj(o->i, name, out_object); -} - -static void start_terminating (struct instance *o) -{ - ASSERT(o->state == STATE_INIT) - - // request process termination - NCDModuleProcess_Terminate(&o->process); - - // set state deinit - o->state = STATE_DEINIT; -} - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // check arguments - NCDValRef template_name_arg; - NCDValRef args_arg; - if (!NCDVal_ListRead(params->args, 2, &template_name_arg, &args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(template_name_arg) || !NCDVal_IsList(args_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - // start process - if (!NCDModuleProcess_InitValue(&o->process, i, template_name_arg, args_arg, process_handler_event)) { - ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); - goto fail0; - } - - // set special object function - NCDModuleProcess_SetSpecialFuncs(&o->process, process_func_getspecialobj); - - // set state init, not dying, assume succeeded - o->state = STATE_INIT; - o->dying = 0; - o->succeeded = 1; - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void instance_free (struct instance *o) -{ - NCDModuleInst_Backend_Dead(o->i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - ASSERT(!o->dying) - - // if we're finished, die immediately - if (o->state == STATE_FINISHED) { - instance_free(o); - return; - } - - // set dying - o->dying = 1; - - // start terminating if not already - if (o->state == STATE_INIT) { - start_terminating(o); - } -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - ASSERT(o->state == STATE_FINISHED) - ASSERT(!o->dying) - - if (name == NCD_STRING_SUCCEEDED) { - *out = ncd_make_boolean(mem, o->succeeded, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void assert_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // check arguments - NCDValRef cond_arg; - if (!NCDVal_ListRead(params->args, 1, &cond_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail1; - } - if (!NCDVal_IsString(cond_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail1; - } - - // get instance - struct instance *mo = params->method_user; - ASSERT(mo->state == STATE_INIT || mo->state == STATE_DEINIT) - - // signal up - NCDModuleInst_Backend_Up(i); - - if (!NCDVal_StringEquals(cond_arg, "true")) { - // mark not succeeded - mo->succeeded = 0; - - // start terminating if not already - if (mo->state == STATE_INIT) { - start_terminating(mo); - } - } - - return; - -fail1: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "try", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "try.try::assert", - .func_new2 = assert_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_try = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/value.c b/external/badvpn_dns/ncd/modules/value.c deleted file mode 100644 index 41ccf35..0000000 --- a/external/badvpn_dns/ncd/modules/value.c +++ /dev/null @@ -1,2102 +0,0 @@ -/** - * @file value.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Synopsis: - * value(value) - * value value::get(where) - * value value::try_get(where) - * value value::getpath(list path) - * value value::insert(where, what) - * value value::insert(what) - * value value::replace(where, what) - * value value::replace_this(value) - * value value::insert_undo(where, what) - * value value::insert_undo(what) - * value value::replace_undo(where, what) - * value value::replace_this_undo(value) - * - * Description: - * Value objects allow examining and manipulating values. - * These value objects are actually references to internal value structures, which - * may be shared between value objects. - * - * value(value) constructs a new value object from the given value. - * - * value::get(where) constructs a value object for the element at position 'where' - * (for a list), or the value corresponding to key 'where' (for a map). It is an - * error if the base value is not a list or a map, the index is out of bounds of - * the list, or the key does not exist in the map. - * The resulting value object is NOT a copy, and shares (part of) the same - * underlying value structure as the base value object. Deleting it will remove - * it from the list or map it is part of. - * - * value::try_get(where) is like get(), except that if any restriction on 'where' - * is violated, no error is triggered; instead, the value object is constructed - * as being deleted; this state is exposed via the 'exists' variable. - * This can be used to check for the presence of a key in a map, and in case it - * exists, allow access to the corresponding value without another get() statement. - * - * value::getpath(path) is like get(), except that it performs multiple - * consecutive resolutions. Also, if the path is an empty list, it performs - * no resulution at all. - * - * value::insert(where, what) constructs a value object by inserting into an - * existing value object. - * For lists, 'where' is the index of the element to insert before, or the length - * of the list to append to it. - * For maps, 'where' is the key to insert under. If the key already exists in the - * map, its value is replaced; any references to the old value however remain valid. - * - * value::insert(what) constructs a value object by appending to a list. An error - * is triggered if the base value is not a list. Assuming 'list' is a list value, - * list->insert(X) is equivalent to list->insert(list.length, X). - * - * value::replace(where, what) is like insert(), exept that, when inserting into a - * list, the value at the specified index is replaced with the new value (unless - * the index is equal to the length of the list). - * - * insert_undo() and replace_undo() are versions of insert() and replace() which - * attempt to revert the modifications when they deinitialize. - * Specifically, they work like that: - * - On initiialization, they take an internal reference to the value being replaced - * (if any; note that insert_undo() into a list never replaces a value). - * - On deinitialization, they remove the the inserted value from its parent (if there - * is one), and insert the old replaced value (to which a reference was kept) in that - * place (if any, and assuming it has not been deleted). - * Note that if the inserted value changes parents in between init and deinit, the - * result of undoing may be unexpected. - * - * Variables: - * (empty) - the value stored in the value object - * type - type of the value; "string", "list" or "map" - * length - number of elements in the list or map, or the number of bytes in a - * string - * keys - a list of keys in the map (only if the value is a map) - * exists - "true" or "false", reflecting whether the value object holds a value - * (is not in deleted state) - * - * Synopsis: - * value::remove(where) - * value::delete() - * - * Description: - * value::remove(where) removes from an existing value object. - * For lists, 'where' is the index of the element to remove, and must be in range. - * For maps, 'where' is the key to remove, and must be an existing key. - * In any case, any references to the removed value remain valid. - * - * value::delete() deletes the underlying value data of this value object. - * After delection, the value object enters a deleted state, which will cause any - * operation on it to fail. Any other value objects which referred to the same value - * or parts of it will too enter deleted state. If the value was an element - * in a list or map, is is removed from it. - * - * Synopsis: - * value value::substr(string start [, string length]) - * - * Description: - * Constructs a string value by extracting a part of a string. - * 'start' specifies the index of the character (from zero) where the substring to - * extract starts, and must be <= the length of the string. - * 'length' specifies the maximum number of characters to extract, if given. - * The newly constructed value is a copy of the extracted substring. - * The value must be a string value. - * - * Synopsis: - * value::reset(what) - * - * Description: - * Effectively deconstructs and reconstructs the value object. More precisely, - * it builds a new value structure from 'what', possibly invokes a scheduled undo - * operation (as scheduled by insert_undo() and replace_undo()), sets up this - * value object to reference the newly built value structure, without any scheduled - * undo operation. - * - * Synopsis: - * value::append(append_val) - * - * Description: - * Only defined when the existing value object is a string or list. If it is a string, - * appends the string 'append_val' to this string value; 'append_val' must be a string. - * If is is a list, inserts 'append_val' to the end of this list value. Unlike insert(), - * the resulting append() object is not itself a value object (which in case of insert() - * serves as a reference to the new value). - */ - -#include <stdlib.h> -#include <string.h> -#include <stddef.h> -#include <limits.h> -#include <inttypes.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <misc/balloc.h> -#include <structure/LinkedList0.h> -#include <structure/IndexedList.h> -#include <structure/SAvl.h> -#include <ncd/NCDModule.h> -#include <ncd/NCDStringIndex.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_value.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define ModuleString(i, id) ((i)->m->group->strings[(id)]) - -#define STOREDSTRING_TYPE (NCDVAL_STRING | (0 << 3)) -#define IDSTRING_TYPE (NCDVAL_STRING | (1 << 3)) -#define EXTERNALSTRING_TYPE (NCDVAL_STRING | (2 << 3)) -#define COMPOSEDSTRING_TYPE (NCDVAL_STRING | (3 << 3)) - -struct value; - -#include "value_maptree.h" -#include <structure/SAvl_decl.h> - -struct valref { - struct value *v; - LinkedList0Node refs_list_node; -}; - -typedef void (*value_deinit_func) (void *deinit_data, NCDModuleInst *i); - -struct instance { - NCDModuleInst *i; - struct valref ref; - value_deinit_func deinit_func; - void *deinit_data; -}; - -struct value { - LinkedList0 refs_list; - - struct value *parent; - union { - struct { - IndexedListNode list_contents_il_node; - } list_parent; - struct { - NCDValMem key_mem; - NCDValRef key; - MapTreeNode maptree_node; - } map_parent; - }; - - int type; - union { - struct { - char *data; - size_t length; - } storedstring; - struct { - NCD_string_id_t id; - NCDStringIndex *string_index; - } idstring; - struct { - const char *data; - size_t length; - BRefTarget *ref_target; - } externalstring; - struct { - NCDValComposedStringResource resource; - size_t offset; - size_t length; - } composedstring; - struct { - IndexedList list_contents_il; - } list; - struct { - MapTree map_tree; - } map; - }; -}; - -static const char * get_type_str (int type); -static void value_cleanup (struct value *v); -static void value_delete (struct value *v); -static struct value * value_init_storedstring (NCDModuleInst *i, const char *str, size_t len); -static struct value * value_init_idstring (NCDModuleInst *i, NCD_string_id_t id, NCDStringIndex *string_index); -static struct value * value_init_externalstring (NCDModuleInst *i, const char *data, size_t length, BRefTarget *ref_target); -static struct value * value_init_composedstring (NCDModuleInst *i, NCDValComposedStringResource resource, size_t offset, size_t length); -static int value_is_string (struct value *v); -static size_t value_string_length (struct value *v); -static void value_string_copy_out (struct value *v, char *dest); -static void value_string_set_allocd (struct value *v, char *data, size_t length); -static struct value * value_init_list (NCDModuleInst *i); -static size_t value_list_len (struct value *v); -static struct value * value_list_at (struct value *v, size_t index); -static size_t value_list_indexof (struct value *v, struct value *ev); -static int value_list_insert (NCDModuleInst *i, struct value *list, struct value *v, size_t index); -static void value_list_remove (struct value *list, struct value *v); -static struct value * value_init_map (NCDModuleInst *i); -static size_t value_map_len (struct value *map); -static struct value * value_map_at (struct value *map, size_t index); -static struct value * value_map_find (struct value *map, NCDValRef key); -static int value_map_insert (struct value *map, struct value *v, NCDValMem mem, NCDValSafeRef key, NCDModuleInst *i); -static void value_map_remove (struct value *map, struct value *v); -static void value_map_remove2 (struct value *map, struct value *v, NCDValMem *out_mem, NCDValSafeRef *out_key); -static struct value * value_init_fromvalue (NCDModuleInst *i, NCDValRef value); -static int value_to_value (NCDModuleInst *i, struct value *v, NCDValMem *mem, NCDValRef *out_value); -static struct value * value_get (NCDModuleInst *i, struct value *v, NCDValRef where, int no_error); -static struct value * value_get_path (NCDModuleInst *i, struct value *v, NCDValRef path); -static struct value * value_insert (NCDModuleInst *i, struct value *v, NCDValRef where, NCDValRef what, int is_replace, struct value **out_oldv); -static struct value * value_insert_simple (NCDModuleInst *i, struct value *v, NCDValRef what); -static int value_remove (NCDModuleInst *i, struct value *v, NCDValRef where); -static int value_append (NCDModuleInst *i, struct value *v, NCDValRef data); -static void valref_init (struct valref *r, struct value *v); -static void valref_free (struct valref *r); -static struct value * valref_val (struct valref *r); -static void valref_break (struct valref *r); - -enum {STRING_EXISTS, STRING_KEYS}; - -static const char *strings[] = { - "exists", "keys", NULL -}; - -#include "value_maptree.h" -#include <structure/SAvl_impl.h> - -static const char * get_type_str (int type) -{ - switch (type) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: - return "string"; - case NCDVAL_LIST: - return "list"; - case NCDVAL_MAP: - return "map"; - } - ASSERT(0) - return NULL; -} - -static void value_cleanup (struct value *v) -{ - if (v->parent || !LinkedList0_IsEmpty(&v->refs_list)) { - return; - } - - switch (v->type) { - case STOREDSTRING_TYPE: { - BFree(v->storedstring.data); - } break; - - case IDSTRING_TYPE: { - } break; - - case EXTERNALSTRING_TYPE: { - if (v->externalstring.ref_target) { - BRefTarget_Deref(v->externalstring.ref_target); - } - } break; - - case COMPOSEDSTRING_TYPE: { - if (v->composedstring.resource.ref_target) { - BRefTarget_Deref(v->composedstring.resource.ref_target); - } - } break; - - case NCDVAL_LIST: { - while (value_list_len(v) > 0) { - struct value *ev = value_list_at(v, 0); - value_list_remove(v, ev); - value_cleanup(ev); - } - } break; - - case NCDVAL_MAP: { - while (value_map_len(v) > 0) { - struct value *ev = value_map_at(v, 0); - value_map_remove(v, ev); - value_cleanup(ev); - } - } break; - - default: ASSERT(0); - } - - free(v); -} - -static void value_delete (struct value *v) -{ - if (v->parent) { - switch (v->parent->type) { - case NCDVAL_LIST: { - value_list_remove(v->parent, v); - } break; - case NCDVAL_MAP: { - value_map_remove(v->parent, v); - } break; - default: ASSERT(0); - } - } - - LinkedList0Node *ln; - while (ln = LinkedList0_GetFirst(&v->refs_list)) { - struct valref *r = UPPER_OBJECT(ln, struct valref, refs_list_node); - ASSERT(r->v == v) - valref_break(r); - } - - switch (v->type) { - case STOREDSTRING_TYPE: { - BFree(v->storedstring.data); - } break; - - case IDSTRING_TYPE: { - } break; - - case EXTERNALSTRING_TYPE: { - if (v->externalstring.ref_target) { - BRefTarget_Deref(v->externalstring.ref_target); - } - } break; - - case COMPOSEDSTRING_TYPE: { - if (v->composedstring.resource.ref_target) { - BRefTarget_Deref(v->composedstring.resource.ref_target); - } - } break; - - case NCDVAL_LIST: { - while (value_list_len(v) > 0) { - struct value *ev = value_list_at(v, 0); - value_delete(ev); - } - } break; - - case NCDVAL_MAP: { - while (value_map_len(v) > 0) { - struct value *ev = value_map_at(v, 0); - value_delete(ev); - } - } break; - - default: ASSERT(0); - } - - free(v); -} - -static struct value * value_init_storedstring (NCDModuleInst *i, const char *str, size_t len) -{ - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = STOREDSTRING_TYPE; - - if (!(v->storedstring.data = BAlloc(len))) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - goto fail1; - } - - if (str) { - memcpy(v->storedstring.data, str, len); - } - - v->storedstring.length = len; - - return v; - -fail1: - free(v); -fail0: - return NULL; -} - -static struct value * value_init_idstring (NCDModuleInst *i, NCD_string_id_t id, NCDStringIndex *string_index) -{ - ASSERT(string_index == i->params->iparams->string_index) - - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = IDSTRING_TYPE; - - v->idstring.id = id; - v->idstring.string_index = string_index; - - return v; - -fail0: - return NULL; -} - -static struct value * value_init_externalstring (NCDModuleInst *i, const char *data, size_t length, BRefTarget *ref_target) -{ - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - if (ref_target) { - if (!BRefTarget_Ref(ref_target)) { - ModuleLog(i, BLOG_ERROR, "BRefTarget_Ref failed"); - goto fail1; - } - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = EXTERNALSTRING_TYPE; - - v->externalstring.data = data; - v->externalstring.length = length; - v->externalstring.ref_target = ref_target; - - return v; - -fail1: - free(v); -fail0: - return NULL; -} - -static struct value * value_init_composedstring (NCDModuleInst *i, NCDValComposedStringResource resource, size_t offset, size_t length) -{ - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - if (resource.ref_target) { - if (!BRefTarget_Ref(resource.ref_target)) { - ModuleLog(i, BLOG_ERROR, "BRefTarget_Ref failed"); - goto fail1; - } - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = COMPOSEDSTRING_TYPE; - - v->composedstring.resource = resource; - v->composedstring.offset = offset; - v->composedstring.length = length; - - return v; - -fail1: - free(v); -fail0: - return NULL; -} - -static int value_is_string (struct value *v) -{ - switch (v->type) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: - return 1; - default: - return 0; - } -} - -static size_t value_string_length (struct value *v) -{ - ASSERT(value_is_string(v)) - - switch (v->type) { - case STOREDSTRING_TYPE: - return v->storedstring.length; - case IDSTRING_TYPE: - return NCDStringIndex_Length(v->idstring.string_index, v->idstring.id); - case EXTERNALSTRING_TYPE: - return v->externalstring.length; - case COMPOSEDSTRING_TYPE: - return v->composedstring.length; - default: - ASSERT(0); - return 0; - } -} - -static void value_string_copy_out (struct value *v, char *dest) -{ - ASSERT(value_is_string(v)) - - switch (v->type) { - case STOREDSTRING_TYPE: - memcpy(dest, v->storedstring.data, v->storedstring.length); - break; - case IDSTRING_TYPE: - memcpy(dest, NCDStringIndex_Value(v->idstring.string_index, v->idstring.id), NCDStringIndex_Length(v->idstring.string_index, v->idstring.id)); - break; - case EXTERNALSTRING_TYPE: - memcpy(dest, v->externalstring.data, v->externalstring.length); - break; - case COMPOSEDSTRING_TYPE: { - b_cstring cstr = NCDValComposedStringResource_Cstring(v->composedstring.resource, v->composedstring.offset, v->composedstring.length); - b_cstring_copy_to_buf(cstr, 0, cstr.length, dest); - } break; - default: - ASSERT(0); - } -} - -static void value_string_set_allocd (struct value *v, char *data, size_t length) -{ - ASSERT(value_is_string(v)) - ASSERT(data) - - switch (v->type) { - case STOREDSTRING_TYPE: { - BFree(v->storedstring.data); - } break; - - case IDSTRING_TYPE: { - } break; - - case EXTERNALSTRING_TYPE: { - if (v->externalstring.ref_target) { - BRefTarget_Deref(v->externalstring.ref_target); - } - } break; - - case COMPOSEDSTRING_TYPE: { - if (v->composedstring.resource.ref_target) { - BRefTarget_Deref(v->composedstring.resource.ref_target); - } - } break; - - default: - ASSERT(0); - } - - v->type = STOREDSTRING_TYPE; - v->storedstring.data = data; - v->storedstring.length = length; -} - -static struct value * value_init_list (NCDModuleInst *i) -{ - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - return NULL; - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = NCDVAL_LIST; - - IndexedList_Init(&v->list.list_contents_il); - - return v; -} - -static size_t value_list_len (struct value *v) -{ - ASSERT(v->type == NCDVAL_LIST) - - return IndexedList_Count(&v->list.list_contents_il); -} - -static struct value * value_list_at (struct value *v, size_t index) -{ - ASSERT(v->type == NCDVAL_LIST) - ASSERT(index < value_list_len(v)) - - IndexedListNode *iln = IndexedList_GetAt(&v->list.list_contents_il, index); - ASSERT(iln) - - struct value *e = UPPER_OBJECT(iln, struct value, list_parent.list_contents_il_node); - ASSERT(e->parent == v) - - return e; -} - -static size_t value_list_indexof (struct value *v, struct value *ev) -{ - ASSERT(v->type == NCDVAL_LIST) - ASSERT(ev->parent == v) - - uint64_t index = IndexedList_IndexOf(&v->list.list_contents_il, &ev->list_parent.list_contents_il_node); - ASSERT(index < value_list_len(v)) - - return index; -} - -static int value_list_insert (NCDModuleInst *i, struct value *list, struct value *v, size_t index) -{ - ASSERT(list->type == NCDVAL_LIST) - ASSERT(!v->parent) - ASSERT(index <= value_list_len(list)) - - if (value_list_len(list) == SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "list has too many elements"); - return 0; - } - - IndexedList_InsertAt(&list->list.list_contents_il, &v->list_parent.list_contents_il_node, index); - v->parent = list; - - return 1; -} - -static void value_list_remove (struct value *list, struct value *v) -{ - ASSERT(list->type == NCDVAL_LIST) - ASSERT(v->parent == list) - - IndexedList_Remove(&list->list.list_contents_il, &v->list_parent.list_contents_il_node); - v->parent = NULL; -} - -static struct value * value_init_map (NCDModuleInst *i) -{ - struct value *v = malloc(sizeof(*v)); - if (!v) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - return NULL; - } - - LinkedList0_Init(&v->refs_list); - v->parent = NULL; - v->type = NCDVAL_MAP; - - MapTree_Init(&v->map.map_tree); - - return v; -} - -static size_t value_map_len (struct value *map) -{ - ASSERT(map->type == NCDVAL_MAP) - - return MapTree_Count(&map->map.map_tree, 0); -} - -static struct value * value_map_at (struct value *map, size_t index) -{ - ASSERT(map->type == NCDVAL_MAP) - ASSERT(index < value_map_len(map)) - - struct value *e = MapTree_GetAt(&map->map.map_tree, 0, index); - ASSERT(e) - ASSERT(e->parent == map) - - return e; -} - -static struct value * value_map_find (struct value *map, NCDValRef key) -{ - ASSERT(map->type == NCDVAL_MAP) - ASSERT(NCDVal_Type(key)) - - struct value *e = MapTree_LookupExact(&map->map.map_tree, 0, key); - ASSERT(!e || e->parent == map) - - return e; -} - -static int value_map_insert (struct value *map, struct value *v, NCDValMem mem, NCDValSafeRef key, NCDModuleInst *i) -{ - ASSERT(map->type == NCDVAL_MAP) - ASSERT(!v->parent) - ASSERT((NCDVal_Type(NCDVal_FromSafe(&mem, key)), 1)) - ASSERT(!value_map_find(map, NCDVal_FromSafe(&mem, key))) - - if (value_map_len(map) == SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "map has too many elements"); - return 0; - } - - v->map_parent.key_mem = mem; - v->map_parent.key = NCDVal_FromSafe(&v->map_parent.key_mem, key); - int res = MapTree_Insert(&map->map.map_tree, 0, v, NULL); - ASSERT_EXECUTE(res) - v->parent = map; - - return 1; -} - -static void value_map_remove (struct value *map, struct value *v) -{ - ASSERT(map->type == NCDVAL_MAP) - ASSERT(v->parent == map) - - MapTree_Remove(&map->map.map_tree, 0, v); - NCDValMem_Free(&v->map_parent.key_mem); - v->parent = NULL; -} - -static void value_map_remove2 (struct value *map, struct value *v, NCDValMem *out_mem, NCDValSafeRef *out_key) -{ - ASSERT(map->type == NCDVAL_MAP) - ASSERT(v->parent == map) - ASSERT(out_mem) - ASSERT(out_key) - - MapTree_Remove(&map->map.map_tree, 0, v); - *out_mem = v->map_parent.key_mem; - *out_key = NCDVal_ToSafe(v->map_parent.key); - v->parent = NULL; -} - -static struct value * value_init_fromvalue (NCDModuleInst *i, NCDValRef value) -{ - ASSERT((NCDVal_Type(value), 1)) - - struct value *v; - - switch (NCDVal_Type(value)) { - case NCDVAL_STRING: { - if (NCDVal_IsStoredString(value)) { - v = value_init_storedstring(i, NCDVal_StringData(value), NCDVal_StringLength(value)); - } else if (NCDVal_IsIdString(value)) { - v = value_init_idstring(i, NCDVal_IdStringId(value), NCDVal_IdStringStringIndex(value)); - } else if (NCDVal_IsExternalString(value)) { - v = value_init_externalstring(i, NCDVal_StringData(value), NCDVal_StringLength(value), NCDVal_ExternalStringTarget(value)); - } else if (NCDVal_IsComposedString(value)) { - v = value_init_composedstring(i, NCDVal_ComposedStringResource(value), NCDVal_ComposedStringOffset(value), NCDVal_StringLength(value)); - } else { - size_t length = NCDVal_StringLength(value); - v = value_init_storedstring(i, NULL, length); - if (v) { - NCDVal_StringCopyOut(value, 0, length, v->storedstring.data); - } - } - if (!v) { - goto fail0; - } - } break; - - case NCDVAL_LIST: { - if (!(v = value_init_list(i))) { - goto fail0; - } - - size_t count = NCDVal_ListCount(value); - - for (size_t j = 0; j < count; j++) { - struct value *ev = value_init_fromvalue(i, NCDVal_ListGet(value, j)); - if (!ev) { - goto fail1; - } - - if (!value_list_insert(i, v, ev, value_list_len(v))) { - value_cleanup(ev); - goto fail1; - } - } - } break; - - case NCDVAL_MAP: { - if (!(v = value_init_map(i))) { - goto fail0; - } - - for (NCDValMapElem e = NCDVal_MapFirst(value); !NCDVal_MapElemInvalid(e); e = NCDVal_MapNext(value, e)) { - NCDValRef ekey = NCDVal_MapElemKey(value, e); - NCDValRef eval = NCDVal_MapElemVal(value, e); - - NCDValMem key_mem; - NCDValMem_Init(&key_mem); - - NCDValRef key = NCDVal_NewCopy(&key_mem, ekey); - if (NCDVal_IsInvalid(key)) { - NCDValMem_Free(&key_mem); - goto fail1; - } - - struct value *ev = value_init_fromvalue(i, eval); - if (!ev) { - NCDValMem_Free(&key_mem); - goto fail1; - } - - if (!value_map_insert(v, ev, key_mem, NCDVal_ToSafe(key), i)) { - NCDValMem_Free(&key_mem); - value_cleanup(ev); - goto fail1; - } - } - } break; - - default: - ASSERT(0); - return NULL; - } - - return v; - -fail1: - value_cleanup(v); -fail0: - return NULL; -} - -static int value_to_value (NCDModuleInst *i, struct value *v, NCDValMem *mem, NCDValRef *out_value) -{ - ASSERT(mem) - ASSERT(out_value) - - switch (v->type) { - case STOREDSTRING_TYPE: { - *out_value = NCDVal_NewStringBin(mem, (const uint8_t *)v->storedstring.data, v->storedstring.length); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - } break; - - case IDSTRING_TYPE: { - *out_value = NCDVal_NewIdString(mem, v->idstring.id, v->idstring.string_index); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - } break; - - case EXTERNALSTRING_TYPE: { - *out_value = NCDVal_NewExternalString(mem, v->externalstring.data, v->externalstring.length, v->externalstring.ref_target); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - } break; - - case COMPOSEDSTRING_TYPE: { - *out_value = NCDVal_NewComposedString(mem, v->composedstring.resource, v->composedstring.offset, v->composedstring.length); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - } break; - - case NCDVAL_LIST: { - *out_value = NCDVal_NewList(mem, value_list_len(v)); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - - for (size_t index = 0; index < value_list_len(v); index++) { - NCDValRef eval; - if (!value_to_value(i, value_list_at(v, index), mem, &eval)) { - goto fail; - } - - if (!NCDVal_ListAppend(*out_value, eval)) { - goto fail; - } - } - } break; - - case NCDVAL_MAP: { - *out_value = NCDVal_NewMap(mem, value_map_len(v)); - if (NCDVal_IsInvalid(*out_value)) { - goto fail; - } - - for (size_t index = 0; index < value_map_len(v); index++) { - struct value *ev = value_map_at(v, index); - - NCDValRef key = NCDVal_NewCopy(mem, ev->map_parent.key); - if (NCDVal_IsInvalid(key)) { - goto fail; - } - - NCDValRef val; - if (!value_to_value(i, ev, mem, &val)) { - goto fail; - } - - int inserted; - if (!NCDVal_MapInsert(*out_value, key, val, &inserted)) { - goto fail; - } - ASSERT_EXECUTE(inserted) - } - } break; - - default: ASSERT(0); - } - - return 1; - -fail: - return 0; -} - -static struct value * value_get (NCDModuleInst *i, struct value *v, NCDValRef where, int no_error) -{ - ASSERT((NCDVal_Type(where), 1)) - - switch (v->type) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: { - if (!no_error) ModuleLog(i, BLOG_ERROR, "cannot resolve into a string"); - goto fail; - } break; - - case NCDVAL_LIST: { - uintmax_t index; - if (!NCDVal_IsString(where) || !ncd_read_uintmax(where, &index)) { - if (!no_error) ModuleLog(i, BLOG_ERROR, "index is not a valid number (resolving into list)"); - goto fail; - } - - if (index >= value_list_len(v)) { - if (!no_error) ModuleLog(i, BLOG_ERROR, "index is out of bounds (resolving into list)"); - goto fail; - } - - v = value_list_at(v, index); - } break; - - case NCDVAL_MAP: { - v = value_map_find(v, where); - if (!v) { - if (!no_error) ModuleLog(i, BLOG_ERROR, "key does not exist (resolving into map)"); - goto fail; - } - } break; - - default: ASSERT(0); - } - - return v; - -fail: - return NULL; -} - -static struct value * value_get_path (NCDModuleInst *i, struct value *v, NCDValRef path) -{ - ASSERT(NCDVal_IsList(path)) - - size_t count = NCDVal_ListCount(path); - - for (size_t j = 0; j < count; j++) { - if (!(v = value_get(i, v, NCDVal_ListGet(path, j), 0))) { - goto fail; - } - } - - return v; - -fail: - return NULL; -} - -static struct value * value_insert (NCDModuleInst *i, struct value *v, NCDValRef where, NCDValRef what, int is_replace, struct value **out_oldv) -{ - ASSERT(v) - ASSERT((NCDVal_Type(where), 1)) - ASSERT((NCDVal_Type(what), 1)) - ASSERT(is_replace == !!is_replace) - - struct value *nv = value_init_fromvalue(i, what); - if (!nv) { - goto fail0; - } - - struct value *oldv = NULL; - - switch (v->type) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: { - ModuleLog(i, BLOG_ERROR, "cannot insert into a string"); - goto fail1; - } break; - - case NCDVAL_LIST: { - uintmax_t index; - if (!NCDVal_IsString(where) || !ncd_read_uintmax(where, &index)) { - ModuleLog(i, BLOG_ERROR, "index is not a valid number (inserting into list)"); - goto fail1; - } - - if (index > value_list_len(v)) { - ModuleLog(i, BLOG_ERROR, "index is out of bounds (inserting into list)"); - goto fail1; - } - - if (is_replace && index < value_list_len(v)) { - oldv = value_list_at(v, index); - - value_list_remove(v, oldv); - - int res = value_list_insert(i, v, nv, index); - ASSERT_EXECUTE(res) - } else { - if (!value_list_insert(i, v, nv, index)) { - goto fail1; - } - } - } break; - - case NCDVAL_MAP: { - oldv = value_map_find(v, where); - - if (!oldv && value_map_len(v) == SIZE_MAX) { - ModuleLog(i, BLOG_ERROR, "map has too many elements"); - goto fail1; - } - - NCDValMem key_mem; - NCDValMem_Init(&key_mem); - - NCDValRef key = NCDVal_NewCopy(&key_mem, where); - if (NCDVal_IsInvalid(key)) { - NCDValMem_Free(&key_mem); - goto fail1; - } - - if (oldv) { - value_map_remove(v, oldv); - } - - int res = value_map_insert(v, nv, key_mem, NCDVal_ToSafe(key), i); - ASSERT_EXECUTE(res) - } break; - - default: ASSERT(0); - } - - if (out_oldv) { - *out_oldv = oldv; - } - else if (oldv) { - value_cleanup(oldv); - } - - return nv; - -fail1: - value_cleanup(nv); -fail0: - return NULL; -} - -static struct value * value_insert_simple (NCDModuleInst *i, struct value *v, NCDValRef what) -{ - ASSERT(v) - ASSERT((NCDVal_Type(what), 1)) - - struct value *nv = value_init_fromvalue(i, what); - if (!nv) { - goto fail0; - } - - switch (v->type) { - case NCDVAL_LIST: { - if (!value_list_insert(i, v, nv, value_list_len(v))) { - goto fail1; - } - } break; - - default: - ModuleLog(i, BLOG_ERROR, "one-argument insert is only defined for lists"); - return NULL; - } - - return nv; - -fail1: - value_cleanup(nv); -fail0: - return NULL; -} - -static int value_remove (NCDModuleInst *i, struct value *v, NCDValRef where) -{ - ASSERT(v) - ASSERT((NCDVal_Type(where), 1)) - - switch (v->type) { - case STOREDSTRING_TYPE: - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: { - ModuleLog(i, BLOG_ERROR, "cannot remove from a string"); - goto fail; - } break; - - case NCDVAL_LIST: { - uintmax_t index; - if (!NCDVal_IsString(where) || !ncd_read_uintmax(where, &index)) { - ModuleLog(i, BLOG_ERROR, "index is not a valid number (removing from list)"); - goto fail; - } - - if (index >= value_list_len(v)) { - ModuleLog(i, BLOG_ERROR, "index is out of bounds (removing from list)"); - goto fail; - } - - struct value *ov = value_list_at(v, index); - - value_list_remove(v, ov); - value_cleanup(ov); - } break; - - case NCDVAL_MAP: { - struct value *ov = value_map_find(v, where); - if (!ov) { - ModuleLog(i, BLOG_ERROR, "key does not exist (removing from map)"); - goto fail; - } - - value_map_remove(v, ov); - value_cleanup(ov); - } break; - - default: ASSERT(0); - } - - return 1; - -fail: - return 0; -} - -static int value_append (NCDModuleInst *i, struct value *v, NCDValRef data) -{ - ASSERT(v) - ASSERT((NCDVal_Type(data), 1)) - - switch (v->type) { - case STOREDSTRING_TYPE: { - if (!NCDVal_IsString(data)) { - ModuleLog(i, BLOG_ERROR, "cannot append non-string to string"); - return 0; - } - - size_t append_length = NCDVal_StringLength(data); - - if (append_length > SIZE_MAX - v->storedstring.length) { - ModuleLog(i, BLOG_ERROR, "too much data to append"); - return 0; - } - size_t new_length = v->storedstring.length + append_length; - - char *new_string = BRealloc(v->storedstring.data, new_length); - if (!new_string) { - ModuleLog(i, BLOG_ERROR, "BRealloc failed"); - return 0; - } - - NCDVal_StringCopyOut(data, 0, append_length, new_string + v->storedstring.length); - - v->storedstring.data = new_string; - v->storedstring.length = new_length; - } break; - - case IDSTRING_TYPE: - case EXTERNALSTRING_TYPE: - case COMPOSEDSTRING_TYPE: { - if (!NCDVal_IsString(data)) { - ModuleLog(i, BLOG_ERROR, "cannot append non-string to string"); - return 0; - } - - size_t length = value_string_length(v); - size_t append_length = NCDVal_StringLength(data); - - if (append_length > SIZE_MAX - length) { - ModuleLog(i, BLOG_ERROR, "too much data to append"); - return 0; - } - size_t new_length = length + append_length; - - char *new_string = BAlloc(new_length); - if (!new_string) { - ModuleLog(i, BLOG_ERROR, "BAlloc failed"); - return 0; - } - - value_string_copy_out(v, new_string); - NCDVal_StringCopyOut(data, 0, append_length, new_string + length); - - value_string_set_allocd(v, new_string, new_length); - } break; - - case NCDVAL_LIST: { - struct value *nv = value_init_fromvalue(i, data); - if (!nv) { - return 0; - } - - if (!value_list_insert(i, v, nv, value_list_len(v))) { - value_cleanup(nv); - return 0; - } - } break; - - default: - ModuleLog(i, BLOG_ERROR, "append is only defined for strings and lists"); - return 0; - } - - return 1; -} - -static void valref_init (struct valref *r, struct value *v) -{ - r->v = v; - - if (v) { - LinkedList0_Prepend(&v->refs_list, &r->refs_list_node); - } -} - -static void valref_free (struct valref *r) -{ - if (r->v) { - LinkedList0_Remove(&r->v->refs_list, &r->refs_list_node); - value_cleanup(r->v); - } -} - -static struct value * valref_val (struct valref *r) -{ - return r->v; -} - -static void valref_break (struct valref *r) -{ - ASSERT(r->v) - - LinkedList0_Remove(&r->v->refs_list, &r->refs_list_node); - r->v = NULL; -} - -static void func_new_common (void *vo, NCDModuleInst *i, struct value *v, value_deinit_func deinit_func, void *deinit_data) -{ - struct instance *o = vo; - o->i = i; - - // init value references - valref_init(&o->ref, v); - - // remember deinit - o->deinit_func = deinit_func; - o->deinit_data = deinit_data; - - NCDModuleInst_Backend_Up(i); - return; -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // deinit - if (o->deinit_func) { - o->deinit_func(o->deinit_data, o->i); - } - - // free value reference - valref_free(&o->ref); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - struct value *v = valref_val(&o->ref); - - if (name == ModuleString(o->i, STRING_EXISTS)) { - *out = ncd_make_boolean(mem, !!v, o->i->params->iparams->string_index); - return 1; - } - - if (name != NCD_STRING_TYPE && name != NCD_STRING_LENGTH && - name != ModuleString(o->i, STRING_KEYS) && name != NCD_STRING_EMPTY) { - return 0; - } - - if (!v) { - ModuleLog(o->i, BLOG_ERROR, "value was deleted"); - return 0; - } - - if (name == NCD_STRING_TYPE) { - *out = NCDVal_NewString(mem, get_type_str(v->type)); - } - else if (name == NCD_STRING_LENGTH) { - size_t len = 0; // to remove warning - switch (v->type) { - case NCDVAL_LIST: - len = value_list_len(v); - break; - case NCDVAL_MAP: - len = value_map_len(v); - break; - default: - ASSERT(value_is_string(v)) - len = value_string_length(v); - break; - } - - *out = ncd_make_uintmax(mem, len); - } - else if (name == ModuleString(o->i, STRING_KEYS)) { - if (v->type != NCDVAL_MAP) { - ModuleLog(o->i, BLOG_ERROR, "value is not a map (reading keys variable)"); - return 0; - } - - *out = NCDVal_NewList(mem, value_map_len(v)); - if (NCDVal_IsInvalid(*out)) { - goto fail; - } - - for (size_t j = 0; j < value_map_len(v); j++) { - struct value *ev = value_map_at(v, j); - - NCDValRef key = NCDVal_NewCopy(mem, ev->map_parent.key); - if (NCDVal_IsInvalid(key)) { - goto fail; - } - - if (!NCDVal_ListAppend(*out, key)) { - goto fail; - } - } - } - else if (name == NCD_STRING_EMPTY) { - if (!value_to_value(o->i, v, mem, out)) { - return 0; - } - } - else { - ASSERT(0); - } - - return 1; - -fail: - *out = NCDVal_NewInvalid(); - return 1; -} - -static void func_new_value (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct value *v = value_init_fromvalue(i, value_arg); - if (!v) { - goto fail0; - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_get (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef where_arg; - if (!NCDVal_ListRead(params->args, 1, &where_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v = value_get(i, mov, where_arg, 0); - if (!v) { - goto fail0; - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_try_get (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef where_arg; - if (!NCDVal_ListRead(params->args, 1, &where_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v = value_get(i, mov, where_arg, 1); - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_getpath (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef path_arg; - if (!NCDVal_ListRead(params->args, 1, &path_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsList(path_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v = value_get_path(i, mov, path_arg); - if (!v) { - goto fail0; - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_insert_replace_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_replace) -{ - NCDValRef where_arg = NCDVal_NewInvalid(); - NCDValRef what_arg; - if (!(!is_replace && NCDVal_ListRead(params->args, 1, &what_arg)) && - !NCDVal_ListRead(params->args, 2, &where_arg, &what_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v; - - if (NCDVal_IsInvalid(where_arg)) { - v = value_insert_simple(i, mov, what_arg); - } else { - v = value_insert(i, mov, where_arg, what_arg, is_replace, NULL); - } - if (!v) { - goto fail0; - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_insert (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_insert_replace_common(vo, i, params, 0); -} - -static void func_new_replace (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_insert_replace_common(vo, i, params, 1); -} - -struct insert_undo_deinit_data { - struct valref val_ref; - struct valref oldval_ref; -}; - -static void undo_deinit_func (struct insert_undo_deinit_data *data, NCDModuleInst *i) -{ - struct value *val = valref_val(&data->val_ref); - struct value *oldval = valref_val(&data->oldval_ref); - - if (val && val->parent && (!oldval || !oldval->parent)) { - // get parent - struct value *parent = val->parent; - - // remove this value from parent and restore saved one (or none) - switch (parent->type) { - case NCDVAL_LIST: { - size_t index = value_list_indexof(parent, val); - value_list_remove(parent, val); - if (oldval) { - int res = value_list_insert(i, parent, oldval, index); - ASSERT_EXECUTE(res) - } - } break; - - case NCDVAL_MAP: { - NCDValMem key_mem; - NCDValSafeRef key; - value_map_remove2(parent, val, &key_mem, &key); - if (oldval) { - int res = value_map_insert(parent, oldval, key_mem, key, i); - ASSERT_EXECUTE(res) - } else { - NCDValMem_Free(&key_mem); - } - } break; - - default: ASSERT(0); - } - } - - valref_free(&data->oldval_ref); - valref_free(&data->val_ref); - free(data); -} - -static void func_new_insert_replace_undo_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_replace) -{ - NCDValRef where_arg = NCDVal_NewInvalid(); - NCDValRef what_arg; - if (!(!is_replace && NCDVal_ListRead(params->args, 1, &what_arg)) && - !NCDVal_ListRead(params->args, 2, &where_arg, &what_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct insert_undo_deinit_data *data = malloc(sizeof(*data)); - if (!data) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - struct value *oldv; - struct value *v; - - if (NCDVal_IsInvalid(where_arg)) { - oldv = NULL; - v = value_insert_simple(i, mov, what_arg); - } else { - v = value_insert(i, mov, where_arg, what_arg, is_replace, &oldv); - } - if (!v) { - goto fail1; - } - - valref_init(&data->val_ref, v); - valref_init(&data->oldval_ref, oldv); - - func_new_common(vo, i, v, (value_deinit_func)undo_deinit_func, data); - return; - -fail1: - free(data); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_insert_undo (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_insert_replace_undo_common(vo, i, params, 0); -} - -static void func_new_replace_undo (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - func_new_insert_replace_undo_common(vo, i, params, 1); -} - -static void func_new_replace_this (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v = value_init_fromvalue(i, value_arg); - if (!v) { - goto fail0; - } - - if (mov->parent) { - struct value *parent = mov->parent; - - switch (parent->type) { - case NCDVAL_LIST: { - size_t index = value_list_indexof(parent, mov); - value_list_remove(parent, mov); - int res = value_list_insert(i, parent, v, index); - ASSERT_EXECUTE(res) - } break; - - case NCDVAL_MAP: { - NCDValMem key_mem; - NCDValSafeRef key; - value_map_remove2(parent, mov, &key_mem, &key); - int res = value_map_insert(parent, v, key_mem, key, i); - ASSERT_EXECUTE(res) - } break; - - default: ASSERT(0); - } - - value_cleanup(mov); - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_replace_this_undo (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - struct value *v = value_init_fromvalue(i, value_arg); - if (!v) { - goto fail0; - } - - struct insert_undo_deinit_data *data = malloc(sizeof(*data)); - if (!data) { - ModuleLog(i, BLOG_ERROR, "malloc failed"); - goto fail1; - } - - valref_init(&data->val_ref, v); - valref_init(&data->oldval_ref, mov); - - if (mov->parent) { - struct value *parent = mov->parent; - - switch (parent->type) { - case NCDVAL_LIST: { - size_t index = value_list_indexof(parent, mov); - value_list_remove(parent, mov); - int res = value_list_insert(i, parent, v, index); - ASSERT_EXECUTE(res) - } break; - - case NCDVAL_MAP: { - NCDValMem key_mem; - NCDValSafeRef key; - value_map_remove2(parent, mov, &key_mem, &key); - int res = value_map_insert(parent, v, key_mem, key, i); - ASSERT_EXECUTE(res) - } break; - - default: ASSERT(0); - } - } - - func_new_common(vo, i, v, (value_deinit_func)undo_deinit_func, data); - return; - -fail1: - value_cleanup(v); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_new_substr (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef start_arg; - NCDValRef length_arg = NCDVal_NewInvalid(); - if (!NCDVal_ListRead(params->args, 1, &start_arg) && - !NCDVal_ListRead(params->args, 2, &start_arg, &length_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - if (!NCDVal_IsString(start_arg) || (!NCDVal_IsInvalid(length_arg) && !NCDVal_IsString(length_arg))) { - ModuleLog(i, BLOG_ERROR, "wrong type"); - goto fail0; - } - - uintmax_t start; - if (!ncd_read_uintmax(start_arg, &start)) { - ModuleLog(i, BLOG_ERROR, "start is not a number"); - goto fail0; - } - - uintmax_t length = UINTMAX_MAX; - if (!NCDVal_IsInvalid(length_arg) && !ncd_read_uintmax(length_arg, &length)) { - ModuleLog(i, BLOG_ERROR, "length is not a number"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - if (!value_is_string(mov)) { - ModuleLog(i, BLOG_ERROR, "value is not a string"); - goto fail0; - } - - size_t string_len = value_string_length(mov); - - if (start > string_len) { - ModuleLog(i, BLOG_ERROR, "start is out of range"); - goto fail0; - } - - size_t remain = string_len - start; - size_t amount = length < remain ? length : remain; - - struct value *v = NULL; - switch (mov->type) { - case STOREDSTRING_TYPE: { - v = value_init_storedstring(i, mov->storedstring.data + start, amount); - } break; - case IDSTRING_TYPE: { - v = value_init_storedstring(i, NCDStringIndex_Value(mov->idstring.string_index, mov->idstring.id) + start, amount); - } break; - case EXTERNALSTRING_TYPE: { - v = value_init_externalstring(i, mov->externalstring.data + start, amount, mov->externalstring.ref_target); - } break; - case COMPOSEDSTRING_TYPE: { - v = value_init_composedstring(i, mov->composedstring.resource, mov->composedstring.offset + start, amount); - } break; - default: - ASSERT(0); - } - - if (!v) { - goto fail0; - } - - func_new_common(vo, i, v, NULL, NULL); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void remove_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef where_arg; - if (!NCDVal_ListRead(params->args, 1, &where_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - if (!value_remove(i, mov, where_arg)) { - goto fail0; - } - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void delete_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - if (!NCDVal_ListRead(params->args, 0)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - value_delete(mov); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void reset_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef what_arg; - if (!NCDVal_ListRead(params->args, 1, &what_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // build value from argument - struct value *newv = value_init_fromvalue(i, what_arg); - if (!newv) { - goto fail0; - } - - // deinit - if (mo->deinit_func) { - mo->deinit_func(mo->deinit_data, i); - } - - // free value reference - valref_free(&mo->ref); - - // set up value reference - valref_init(&mo->ref, newv); - - // set no deinit function - mo->deinit_func = NULL; - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void append_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - NCDValRef data_arg; - if (!NCDVal_ListRead(params->args, 1, &data_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - struct value *mov = valref_val(&mo->ref); - - if (!mov) { - ModuleLog(i, BLOG_ERROR, "value was deleted"); - goto fail0; - } - - if (!value_append(i, mov, data_arg)) { - goto fail0; - } - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "value", - .func_new2 = func_new_value, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::get", - .base_type = "value", - .func_new2 = func_new_get, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::try_get", - .base_type = "value", - .func_new2 = func_new_try_get, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::getpath", - .base_type = "value", - .func_new2 = func_new_getpath, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::insert", - .base_type = "value", - .func_new2 = func_new_insert, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::replace", - .base_type = "value", - .func_new2 = func_new_replace, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::replace_this", - .base_type = "value", - .func_new2 = func_new_replace_this, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::insert_undo", - .base_type = "value", - .func_new2 = func_new_insert_undo, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::replace_undo", - .base_type = "value", - .func_new2 = func_new_replace_undo, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::replace_this_undo", - .base_type = "value", - .func_new2 = func_new_replace_this_undo, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::remove", - .func_new2 = remove_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::delete", - .func_new2 = delete_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::reset", - .func_new2 = reset_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::substr", - .base_type = "value", - .func_new2 = func_new_substr, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance), - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = "value::append", - .func_new2 = append_func_new, - .flags = NCDMODULE_FLAG_ACCEPT_NON_CONTINUOUS_STRINGS - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_value = { - .modules = modules, - .strings = strings -}; diff --git a/external/badvpn_dns/ncd/modules/value_maptree.h b/external/badvpn_dns/ncd/modules/value_maptree.h deleted file mode 100644 index e6f69f9..0000000 --- a/external/badvpn_dns/ncd/modules/value_maptree.h +++ /dev/null @@ -1,11 +0,0 @@ -#define SAVL_PARAM_NAME MapTree -#define SAVL_PARAM_FEATURE_COUNTS 1 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct value -#define SAVL_PARAM_TYPE_KEY NCDValRef -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_TYPE_COUNT size_t -#define SAVL_PARAM_VALUE_COUNT_MAX SIZE_MAX -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) NCDVal_Compare((entry1)->map_parent.key, (entry2)->map_parent.key) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) NCDVal_Compare((key1), (entry2)->map_parent.key) -#define SAVL_PARAM_MEMBER_NODE map_parent.maptree_node diff --git a/external/badvpn_dns/ncd/modules/valuemetic.c b/external/badvpn_dns/ncd/modules/valuemetic.c deleted file mode 100644 index a87f73b..0000000 --- a/external/badvpn_dns/ncd/modules/valuemetic.c +++ /dev/null @@ -1,219 +0,0 @@ -/** - * @file valuemetic.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Comparison functions for values. - * - * Synopsis: - * val_lesser(v1, v2) - * val_greater(v1, v2) - * val_lesser_equal(v1, v2) - * val_greater_equal(v1, v2) - * val_equal(v1, v2) - * val_different(v1, v2) - * - * Variables: - * (empty) - "true" or "false", reflecting the value of the relation in question - * - * Description: - * These statements perform comparisons of values. Order of values is defined by the - * following rules: - * 1. Values of different types have the following order: strings, lists, maps. - * 2. String values are ordered lexicographically, with respect to the numeric values - * of their bytes. - * 3. List values are ordered lexicographically, where the order of the elements is - * defined by recursive application of these rules. - * 4. Map values are ordered lexicographically, as if a map was a list of (key, value) - * pairs ordered by key, where the order of both keys and values is defined by - * recursive application of these rules. - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> -#include <ncd/extra/value_utils.h> - -#include <generated/blog_channel_ncd_valuemetic.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - int result; -}; - -typedef int (*compute_func) (NCDValRef v1, NCDValRef v2); - -static int compute_lesser (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) < 0; -} - -static int compute_greater (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) > 0; -} - -static int compute_lesser_equal (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) <= 0; -} - -static int compute_greater_equal (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) >= 0; -} - -static int compute_equal (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) == 0; -} - -static int compute_different (NCDValRef v1, NCDValRef v2) -{ - return NCDVal_Compare(v1, v2) != 0; -} - -static void new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, compute_func cfunc) -{ - struct instance *o = vo; - o->i = i; - - NCDValRef v1_arg; - NCDValRef v2_arg; - if (!NCDVal_ListRead(params->args, 2, &v1_arg, &v2_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - o->result = cfunc(v1_arg, v2_arg); - - NCDModuleInst_Backend_Up(i); - return; - -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = ncd_make_boolean(mem, o->result, o->i->params->iparams->string_index); - return 1; - } - - return 0; -} - -static void func_new_lesser (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_lesser); -} - -static void func_new_greater (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_greater); -} - -static void func_new_lesser_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_lesser_equal); -} - -static void func_new_greater_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_greater_equal); -} - -static void func_new_equal (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_equal); -} - -static void func_new_different (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - new_templ(vo, i, params, compute_different); -} - -static struct NCDModule modules[] = { - { - .type = "val_lesser", - .func_new2 = func_new_lesser, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "val_greater", - .func_new2 = func_new_greater, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "val_lesser_equal", - .func_new2 = func_new_lesser_equal, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "val_greater_equal", - .func_new2 = func_new_greater_equal, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "val_equal", - .func_new2 = func_new_equal, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "val_different", - .func_new2 = func_new_different, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_valuemetic = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/modules/var.c b/external/badvpn_dns/ncd/modules/var.c deleted file mode 100644 index 83abd44..0000000 --- a/external/badvpn_dns/ncd/modules/var.c +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @file var.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Variable module. - * - * Synopsis: var(value) - * Variables: - * (empty) - value - * - * Synopsis: var::set(value) - */ - -#include <stdlib.h> -#include <string.h> - -#include <ncd/NCDModule.h> -#include <ncd/static_strings.h> - -#include <generated/blog_channel_ncd_var.h> - -#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -struct instance { - NCDModuleInst *i; - NCDValMem mem; - NCDValRef value; -}; - -static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - struct instance *o = vo; - o->i = i; - - // read argument - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(o->i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // init mem - NCDValMem_Init(&o->mem); - - // copy value - o->value = NCDVal_NewCopy(&o->mem, value_arg); - if (NCDVal_IsInvalid(o->value)) { - goto fail1; - } - - // signal up - NCDModuleInst_Backend_Up(o->i); - return; - -fail1: - NCDValMem_Free(&o->mem); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static void func_die (void *vo) -{ - struct instance *o = vo; - - // free mem - NCDValMem_Free(&o->mem); - - NCDModuleInst_Backend_Dead(o->i); -} - -static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out) -{ - struct instance *o = vo; - - if (name == NCD_STRING_EMPTY) { - *out = NCDVal_NewCopy(mem, o->value); - return 1; - } - - return 0; -} - -static void set_func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) -{ - // read arguments - NCDValRef value_arg; - if (!NCDVal_ListRead(params->args, 1, &value_arg)) { - ModuleLog(i, BLOG_ERROR, "wrong arity"); - goto fail0; - } - - // get method object - struct instance *mo = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); - - // allocate new mem - NCDValMem mem; - NCDValMem_Init(&mem); - - // copy value - NCDValRef copy = NCDVal_NewCopy(&mem, value_arg); - if (NCDVal_IsInvalid(copy)) { - goto fail1; - } - - // replace value in var - NCDValMem_Free(&mo->mem); - mo->mem = mem; - mo->value = NCDVal_Moved(&mo->mem, copy); - - // signal up - NCDModuleInst_Backend_Up(i); - return; - -fail1: - NCDValMem_Free(&mem); -fail0: - NCDModuleInst_Backend_DeadError(i); -} - -static struct NCDModule modules[] = { - { - .type = "var", - .func_new2 = func_new, - .func_die = func_die, - .func_getvar2 = func_getvar2, - .alloc_size = sizeof(struct instance) - }, { - .type = "var::set", - .func_new2 = set_func_new - }, { - .type = NULL - } -}; - -const struct NCDModuleGroup ncdmodule_var = { - .modules = modules -}; diff --git a/external/badvpn_dns/ncd/ncd.c b/external/badvpn_dns/ncd/ncd.c deleted file mode 100644 index b3270fc..0000000 --- a/external/badvpn_dns/ncd/ncd.c +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @file ncd.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include <misc/version.h> -#include <misc/loglevel.h> -#include <misc/open_standard_streams.h> -#include <misc/string_begins_with.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BProcess.h> -#include <udevmonitor/NCDUdevManager.h> -#include <random/BRandom2.h> -#include <ncd/NCDInterpreter.h> -#include <ncd/NCDBuildProgram.h> - -#ifdef BADVPN_USE_SYSLOG -#include <base/BLog_syslog.h> -#endif - -#include "ncd.h" - -#include <generated/blog_channel_ncd.h> - -#define LOGGER_STDOUT 1 -#define LOGGER_STDERR 2 -#define LOGGER_SYSLOG 3 - -// command-line options -static struct { - int help; - int version; - int logger; -#ifdef BADVPN_USE_SYSLOG - char *logger_syslog_facility; - char *logger_syslog_ident; -#endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - char *config_file; - int syntax_only; - int retry_time; - int no_udev; - char **extra_args; - int num_extra_args; -} options; - -// reactor -static BReactor reactor; - -// process manager -static BProcessManager manager; - -// udev manager -static NCDUdevManager umanager; - -// random number generator -static BRandom2 random2; - -// interpreter -static NCDInterpreter interpreter; - -// forward declarations of functions -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static void signal_handler (void *unused); -static void interpreter_handler_finished (void *user, int exit_code); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - int main_exit_code = 1; - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - case LOGGER_STDERR: - BLog_InitStderr(); - break; -#ifdef BADVPN_USE_SYSLOG - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; -#endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } else { - BLog_SetChannelLoglevel(i, DEFAULT_LOGLEVEL); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&reactor)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // init process manager - if (!BProcessManager_Init(&manager, &reactor)) { - BLog(BLOG_ERROR, "BProcessManager_Init failed"); - goto fail2; - } - - // init udev manager - NCDUdevManager_Init(&umanager, options.no_udev, &reactor, &manager); - - // init random number generator - if (!BRandom2_Init(&random2, BRANDOM2_INIT_LAZY)) { - BLog(BLOG_ERROR, "BRandom2_Init failed"); - goto fail3; - } - - // setup signal handler - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail4; - } - - // build program - NCDProgram program; - if (!NCDBuildProgram_Build(options.config_file, &program)) { - BLog(BLOG_ERROR, "failed to build program"); - goto fail5; - } - - // setup interpreter parameters - struct NCDInterpreter_params params; - params.handler_finished = interpreter_handler_finished; - params.user = NULL; - params.retry_time = options.retry_time; - params.extra_args = options.extra_args; - params.num_extra_args = options.num_extra_args; - params.reactor = &reactor; - params.manager = &manager; - params.umanager = &umanager; - params.random2 = &random2; - - // initialize interpreter - if (!NCDInterpreter_Init(&interpreter, program, params)) { - goto fail5; - } - - // don't enter event loop if syntax check is requested - if (options.syntax_only) { - main_exit_code = 0; - goto fail6; - } - - BLog(BLOG_NOTICE, "entering event loop"); - - // enter event loop - main_exit_code = BReactor_Exec(&reactor); - -fail6: - // free interpreter - NCDInterpreter_Free(&interpreter); -fail5: - // remove signal handler - BSignal_Finish(); -fail4: - // free random number generator - BRandom2_Free(&random2); -fail3: - // free udev manager - NCDUdevManager_Free(&umanager); - - // free process manager - BProcessManager_Free(&manager); -fail2: - // free reactor - BReactor_Free(&reactor); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish objects - DebugObjectGlobal_Finish(); - - return main_exit_code; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <stdout/stderr/syslog>]\n" - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--retry-time <ms>]\n" - " [--no-udev]\n" - " [--config-file <ncd_program_file>]\n" - " [--syntax-only]\n" - " [-- program_args...]\n" - " [<ncd_program_file> program_args...]\n" , - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDERR; -#ifdef BADVPN_USE_SYSLOG - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; -#endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.config_file = NULL; - options.syntax_only = 0; - options.retry_time = DEFAULT_RETRY_TIME; - options.no_udev = 0; - options.extra_args = NULL; - options.num_extra_args = 0; - - for (int i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - else if (!strcmp(arg2, "stderr")) { - options.logger = LOGGER_STDERR; - } -#ifdef BADVPN_USE_SYSLOG - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } -#endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } -#ifdef BADVPN_USE_SYSLOG - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } -#endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--config-file")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.config_file = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syntax-only")) { - options.syntax_only = 1; - } - else if (!strcmp(arg, "--retry-time")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.retry_time = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--no-udev")) { - options.no_udev = 1; - } - else if (!strcmp(arg, "--")) { - options.extra_args = &argv[i + 1]; - options.num_extra_args = argc - i - 1; - i += options.num_extra_args; - } - else if (!string_begins_with(arg, "--")) { - if (options.config_file) { - fprintf(stderr, "%s: program is already specified (did you mean to use -- ?)\n", arg); - return 0; - } - options.config_file = argv[i]; - options.extra_args = &argv[i + 1]; - options.num_extra_args = argc - i - 1; - i += options.num_extra_args; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.config_file) { - fprintf(stderr, "No program is specified.\n"); - return 0; - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - NCDInterpreter_RequestShutdown(&interpreter, 1); -} - -void interpreter_handler_finished (void *user, int exit_code) -{ - BReactor_Quit(&reactor, exit_code); -} diff --git a/external/badvpn_dns/ncd/ncd.h b/external/badvpn_dns/ncd/ncd.h deleted file mode 100644 index 88c4070..0000000 --- a/external/badvpn_dns/ncd/ncd.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file ncd.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// name of the program -#define PROGRAM_NAME "ncd" - -// how long to wait after an error before retrying -#define DEFAULT_RETRY_TIME 5000 - -// default loglevel -#define DEFAULT_LOGLEVEL BLOG_WARNING diff --git a/external/badvpn_dns/ncd/parse_linux_input.sh b/external/badvpn_dns/ncd/parse_linux_input.sh deleted file mode 100755 index f277484..0000000 --- a/external/badvpn_dns/ncd/parse_linux_input.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -INPUT=$1 -OUTPUT=$2 - -types="" -keys="" -rels="" -abss="" -sws="" -mscs="" -leds="" -reps="" -snds="" -ffstatuss="" - -while read LINE; do - tab=$'\t' - space="[ ${tab}]" - regex="^#define ((EV|KEY|BTN|REL|ABS|SW|MSC|LED|REP|SND|FF_STATUS)_[A-Z0-9_]+)${space}" - if [[ $LINE =~ $regex ]]; then - type=${BASH_REMATCH[2]} - name=${BASH_REMATCH[1]} - if [[ $type = "EV" ]]; then - if [[ $name != "EV_VERSION" ]]; then - types="${types} [${name}] = "${name}", -" - fi - elif [[ $type = "KEY" ]] || [[ $type = "BTN" ]]; then - if [[ $name != "KEY_MIN_INTERESTING" ]]; then - keys="${keys} [${name}] = "${name}", -" - fi - elif [[ $type = "REL" ]]; then - rels="${rels} [${name}] = "${name}", -" - elif [[ $type = "ABS" ]]; then - abss="${abss} [${name}] = "${name}", -" - elif [[ $type = "SW" ]]; then - sws="${sws} [${name}] = "${name}", -" - elif [[ $type = "MSC" ]]; then - mscs="${mscs} [${name}] = "${name}", -" - elif [[ $type = "LED" ]]; then - leds="${leds} [${name}] = "${name}", -" - elif [[ $type = "REP" ]]; then - reps="${reps} [${name}] = "${name}", -" - elif [[ $type = "SND" ]]; then - snds="${snds} [${name}] = "${name}", -" - elif [[ $type = "FF_STATUS" ]]; then - ffstatuss="${ffstatuss} [${name}] = "${name}", -" - fi - fi -done < "${INPUT}" - -( -echo " -static const char *type_names[] = { -${types}}; - -static const char *key_names[] = { -${keys}}; - -static const char *rel_names[] = { -${rels}}; - -static const char *abs_names[] = { -${abss}}; - -static const char *sw_names[] = { -${sws}}; - -static const char *msc_names[] = { -${mscs}}; - -static const char *led_names[] = { -${leds}}; - -static const char *rep_names[] = { -${reps}}; - -static const char *snd_names[] = { -${snds}}; - -static const char *ffstatus_names[] = { -${ffstatuss}}; -" -) >"${OUTPUT}" diff --git a/external/badvpn_dns/ncd/static_strings.h b/external/badvpn_dns/ncd/static_strings.h deleted file mode 100644 index a823224..0000000 --- a/external/badvpn_dns/ncd/static_strings.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file static_strings.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STATIC_STRINGS_H -#define BADVPN_STATIC_STRINGS_H - -// NOTE: keep synchronized with NCDStringIndex.c -enum { - NCD_STRING_EMPTY, - NCD_STRING_ARGS, - NCD_STRING_ARG0, - NCD_STRING_ARG1, - NCD_STRING_ARG2, - NCD_STRING_ARG3, - NCD_STRING_ARG4, - NCD_STRING_ARG5, - NCD_STRING_ARG6, - NCD_STRING_ARG7, - NCD_STRING_ARG8, - NCD_STRING_ARG9, - NCD_STRING_ARG10, - NCD_STRING_ARG11, - NCD_STRING_ARG12, - NCD_STRING_ARG13, - NCD_STRING_ARG14, - NCD_STRING_ARG15, - NCD_STRING_ARG16, - NCD_STRING_ARG17, - NCD_STRING_ARG18, - NCD_STRING_ARG19, - NCD_STRING_TRUE, - NCD_STRING_FALSE, - NCD_STRING_NONE, - NCD_STRING_CALLER, - NCD_STRING_SUCCEEDED, - NCD_STRING_IS_ERROR, - NCD_STRING_NOT_EOF, - NCD_STRING_LENGTH, - NCD_STRING_TYPE, - NCD_STRING_EXIT_STATUS, - NCD_STRING_SIZE -}; - -#endif diff --git a/external/badvpn_dns/ncd/tests/addr_in_network.ncd b/external/badvpn_dns/ncd/tests/addr_in_network.ncd deleted file mode 100644 index fc53292..0000000 --- a/external/badvpn_dns/ncd/tests/addr_in_network.ncd +++ /dev/null @@ -1,60 +0,0 @@ -process main { - net.ipv4.addr_in_network("192.168.6.0", "192.168.6.0", "24") r; - assert(r); - - net.ipv4.addr_in_network("192.168.6.0", "192.168.6.0/24") r; - assert(r); - - net.ipv4.addr_in_network("192.168.6.1", "192.168.6.0", "24") r; - assert(r); - - net.ipv4.addr_in_network("192.168.6.255", "192.168.6.0", "24") r; - assert(r); - - net.ipv4.addr_in_network("192.168.5.255", "192.168.6.0", "24") r; - not(r) r; - assert(r); - - net.ipv4.addr_in_network("192.168.7.0", "192.168.6.0", "24") r; - not(r) r; - assert(r); - - net.ipv4.addr_in_network("192.168.7.0", "192.168.6.0/24") r; - not(r) r; - assert(r); - - net.ipv4.addr_in_network("0.0.0.0", "192.168.6.0", "0") r; - assert(r); - - net.ipv4.addr_in_network("0.0.0.0", "0.0.0.0", "0") r; - assert(r); - - net.ipv4.addr_in_network("255.255.255.255", "0.0.0.0", "0") r; - assert(r); - - net.ipv6.addr_in_network("::123:0", "::123:0/112") r; - assert(r); - - net.ipv6.addr_in_network("::123:1", "::123:0/112") r; - assert(r); - - net.ipv6.addr_in_network("::123:ffff", "::123:0/112") r; - assert(r); - - net.ipv6.addr_in_network("::123:ffff", "::123:ffff/128") r; - assert(r); - - net.ipv6.addr_in_network("::122:ffff", "::123:0/112") r; - not(r) r; - assert(r); - - net.ipv6.addr_in_network("::124:0", "::123:0/112") r; - not(r) r; - assert(r); - - net.ipv6.addr_in_network("::123:fffe", "::123:ffff/128") r; - not(r) r; - assert(r); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/alias.ncd b/external/badvpn_dns/ncd/tests/alias.ncd deleted file mode 100644 index 624a4ed..0000000 --- a/external/badvpn_dns/ncd/tests/alias.ncd +++ /dev/null @@ -1,48 +0,0 @@ -process foo { - var("hello") x; - alias("x") y; - val_equal(y, "hello") a; - assert(a); - - var("hello") x; - alias("x") y; - y->set("world"); - val_equal(y, "world") a; - assert(a); - - var("hello") x; - alias("x") y; - alias("y") z; - z->set("world"); - val_equal(x, "world") a; - assert(a); - - call("test", {"hello"}) c; - alias("c.x") x; - val_equal(x, "hello") a; - assert(a); - - call("test", {"hello"}) c; - alias("c") x; - alias("x") y; - alias("y.x") z; - c.x->set("world"); - val_equal(z, "world") a; - assert(a); - - var("hello") x; - call("test2", {"_caller.x"}) c; - c.x->set("world"); - val_equal(x, "world") a; - assert(a); - - exit("0"); -} - -template test { - var(_arg0) x; -} - -template test2 { - alias(_arg0) x; -} diff --git a/external/badvpn_dns/ncd/tests/arithmetic.ncd b/external/badvpn_dns/ncd/tests/arithmetic.ncd deleted file mode 100644 index 8f82bcc..0000000 --- a/external/badvpn_dns/ncd/tests/arithmetic.ncd +++ /dev/null @@ -1,69 +0,0 @@ -process main { - num_lesser("6", "7") r; - assert(r); - - num_lesser("7", "7") r; - not(r) a; - assert(a); - - num_greater("7", "6") r; - assert(r); - - num_greater("7", "7") r; - not(r) a; - assert(a); - - num_lesser_equal("7", "7") r; - assert(r); - - num_lesser_equal("8", "7") r; - not(r) a; - assert(a); - - num_greater_equal("7", "7") r; - assert(r); - - num_greater_equal("7", "8") r; - not(r) a; - assert(a); - - num_equal("7", "7") r; - assert(r); - - num_equal("6", "7") r; - not(r) a; - assert(a); - - num_equal("7", "6") r; - not(r) a; - assert(a); - - num_different("7", "6") a; - assert(a); - - num_different("7", "007") a; - not(a) a; - assert(a); - - num_add("4", "7") r; - strcmp(r, "11") a; - assert(a); - - num_subtract("4", "3") r; - strcmp(r, "1") a; - assert(a); - - num_multiply("4", "5") r; - strcmp(r, "20") a; - assert(a); - - num_divide("7", "3") r; - strcmp(r, "2") a; - assert(a); - - num_modulo("7", "3") r; - strcmp(r, "1") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/backtracking.ncd b/external/badvpn_dns/ncd/tests/backtracking.ncd deleted file mode 100644 index 1faf3b7..0000000 --- a/external/badvpn_dns/ncd/tests/backtracking.ncd +++ /dev/null @@ -1,31 +0,0 @@ -process main { - value({}) list; - var("0") i; - backtrack_point() point; - num_lesser(i, "100") do_more; - If (do_more) { - list->insert(i); - num_add(i, "1") new_i; - i->set(new_i); - point->go(); - }; - val_equal(list.length, "100") a; - assert(a); - - value({}) list; - var("0") i; - blocker() blk; - blk->up(); - blk->use(); - num_lesser(i, "100") do_more; - If (do_more) { - list->insert(i); - num_add(i, "1") new_i; - i->set(new_i); - blk->downup(); - }; - val_equal(list.length, "100") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/buffer.ncd b/external/badvpn_dns/ncd/tests/buffer.ncd deleted file mode 100644 index 1af0ea7..0000000 --- a/external/badvpn_dns/ncd/tests/buffer.ncd +++ /dev/null @@ -1,54 +0,0 @@ -process main { - buffer() buf; - val_equal(buf, "") a; - assert(a); - - buf->append("12"); - val_equal(buf, "12") a; - assert(a); - - buf->append("345"); - val_equal(buf, "12345") a; - assert(a); - - buf->consume("1"); - val_equal(buf, "2345") a; - assert(a); - - buf->consume("1"); - val_equal(buf, "345") a; - assert(a); - - buf->consume("3"); - val_equal(buf, "") a; - assert(a); - - buf->append("6"); - val_equal(buf, "6") a; - assert(a); - - buf->append("7890"); - val_equal(buf, "67890") a; - assert(a); - - buf->append(""); - val_equal(buf, "67890") a; - assert(a); - - buf->consume("4"); - val_equal(buf, "0") a; - assert(a); - - buf->append("1234567890"); - val_equal(buf, "01234567890") a; - assert(a); - - val_equal(buf.length, "11") a; - assert(a); - - buffer("hello") buf2; - val_equal(buf2, "hello") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/call.ncd b/external/badvpn_dns/ncd/tests/call.ncd deleted file mode 100644 index 273ed68..0000000 --- a/external/badvpn_dns/ncd/tests/call.ncd +++ /dev/null @@ -1,18 +0,0 @@ -process main { - var("bad_x") x; - var("good_x") y; - call("helper_func", {}) helper; - call_with_caller_target("func1", {}, "helper") c; - val_equal(c.x, "good_x") a; - assert(a); - - exit("0"); -} - -template helper_func { - var(_caller.y) x; -} - -template func1 { - var(_caller.x) x; -} diff --git a/external/badvpn_dns/ncd/tests/concat.ncd b/external/badvpn_dns/ncd/tests/concat.ncd deleted file mode 100644 index 72b256e..0000000 --- a/external/badvpn_dns/ncd/tests/concat.ncd +++ /dev/null @@ -1,19 +0,0 @@ -process main { - concat("Hello", "", "World") x; - strcmp(x, "HelloWorld") a; - assert(a); - - concat("\x00\x00", "\x00") x; - strcmp(x, "\x00\x00\x00") a; - assert(a); - - concatv({"Hello", "", "World"}) x; - strcmp(x, "HelloWorld") a; - assert(a); - - concatv({"\x00\x00", "\x00"}) x; - strcmp(x, "\x00\x00\x00") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/depend.ncd b/external/badvpn_dns/ncd/tests/depend.ncd deleted file mode 100644 index c1a34b6..0000000 --- a/external/badvpn_dns/ncd/tests/depend.ncd +++ /dev/null @@ -1,64 +0,0 @@ -process main { - var("hello") x; - provide("A"); - depend("A") d; - val_equal(d.x, "hello") a; - assert(a); - d.x->set("world"); - val_equal(d.x, "world") a; - assert(a); - - var("hello") x; - provide("B"); - val_equal(x, "world") a; - assert(a); - - var("hello") x; - provide("C"); - val_equal(x, "hello") a; - assert(a); - depend("C_done"); - val_equal(x, "world") a; - assert(a); - - var("hello") x; - blocker() blk; - provide("D"); - val_equal(x, "hello") a; - assert(a); - blk->up(); - val_equal(x, "0") a; - assert(a); - blk->down(); - blk->up(); - val_equal(x, "1") a; - assert(a); - - exit("0"); -} - -process proc1 { - depend("B") dep; - dep.x->set("world"); -} - -process proc2 { - depend("C") dep; - sleep("0", "0"); - dep.x->set("world"); - provide("C_done"); -} - -process proc3 { - depend("D") dep; - dep.blk->use(); - provide("E"); -} - -process proc4 { - var("0") i; - depend("E") dep; - dep.dep.x->set(i); - num_add(i, "1") j; - i->set(j); -} diff --git a/external/badvpn_dns/ncd/tests/depend_scope.ncd b/external/badvpn_dns/ncd/tests/depend_scope.ncd deleted file mode 100644 index a29a9a6..0000000 --- a/external/badvpn_dns/ncd/tests/depend_scope.ncd +++ /dev/null @@ -1,31 +0,0 @@ -process main { - depend_scope() scope; - var("0") x; - process_manager() mgr; - - var("false") backtrack_check; - backtrack_point() point; - If (backtrack_check) { - val_equal(x, "2") a; # must not have rebound temporarily to A during backtracking - assert(a); - exit("0"); - }; - - scope->provide("A"); - mgr->start("t1", "t1", {}); - val_equal(x, "1") a; # must have bound to A immediately - assert(a); - - scope->provide("B") mgr; - val_equal(x, "2") a; # must have rebound to B immediately - assert(a); - - backtrack_check->set("true"); - point->go(); -} - -template t1 { - _caller.scope->depend({"B", "A"}) dep; - num_add(dep.x, "1") new_x; - dep.x->set(new_x); -} diff --git a/external/badvpn_dns/ncd/tests/escape_and_nulls.ncd b/external/badvpn_dns/ncd/tests/escape_and_nulls.ncd deleted file mode 100644 index 741bf8d..0000000 --- a/external/badvpn_dns/ncd/tests/escape_and_nulls.ncd +++ /dev/null @@ -1,38 +0,0 @@ -process main { - value("ab\0") str1; - value("ab") str2; - - strcmp(str1.length, "3") a; - assert(a); - - strcmp(str2.length, "2") a; - assert(a); - - strcmp(str1, str2) a; - not(a) a; - assert(a); - - concat(str1, str2) strc; - strcmp(strc, "ab\0ab") a; - assert(a); - - concat(str2, str1) strc; - strcmp(strc, "abab\0") a; - assert(a); - - value("") str1; - value("\x00\x00") str2; - value("\x00\x01") str3; - value("\x01") str4; - - val_lesser(str1, str2) a; - assert(a); - - val_lesser(str2, str3) a; - assert(a); - - val_lesser(str3, str4) a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/explode.ncd b/external/badvpn_dns/ncd/tests/explode.ncd deleted file mode 100644 index 20913a8..0000000 --- a/external/badvpn_dns/ncd/tests/explode.ncd +++ /dev/null @@ -1,23 +0,0 @@ -process main { - explode("FOO", "aaaFOObbbFOOcccFOOddd") l; - val_equal(l, {"aaa", "bbb", "ccc", "ddd"}) a; - assert(a); - - explode("FOO", "FOObbbFOOFOO") l; - val_equal(l, {"", "bbb", "", ""}) a; - assert(a); - - explode("FOO", "foo") l; - val_equal(l, {"foo"}) a; - assert(a); - - explode("FOO", "FOO") l; - val_equal(l, {"", ""}) a; - assert(a); - - explode("participate in parachute", "parachute in participation of participate in parachuteparparticipate in parachute participate in parachut") l; - val_equal(l, {"parachute in participation of ", "par", " participate in parachut"}) a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/foreach.ncd b/external/badvpn_dns/ncd/tests/foreach.ncd deleted file mode 100644 index 33ad042..0000000 --- a/external/badvpn_dns/ncd/tests/foreach.ncd +++ /dev/null @@ -1,35 +0,0 @@ -process main { - var({"a", "b", "c", "d"}) list; - value(["a":"1", "b":"2", "c":"3", "d":"4"]) map; - - value({}) new; - Foreach (list As value) { - new->insert(new.length, value); - }; - val_equal(new, list) a; - assert(a); - - value({}) new; - Foreach (list As index:value) { - new->insert(index, value); - }; - val_equal(new, list) a; - assert(a); - - value([]) new; - Foreach (map As key) { - map->get(key) value; - new->insert(key, value); - }; - val_equal(new, map) a; - assert(a); - - value([]) new; - Foreach (map As key:value) { - new->insert(key, value); - }; - val_equal(new, map) a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/if.ncd b/external/badvpn_dns/ncd/tests/if.ncd deleted file mode 100644 index 4597adc..0000000 --- a/external/badvpn_dns/ncd/tests/if.ncd +++ /dev/null @@ -1,38 +0,0 @@ -process foo { - If ("true") { - If ("truee") { - var("A1") y; - } else { - If ("true") { - var("A11") q; - } else { - var("A22") q; - } t; - var(t.q) y; - } s; - var(s.y) x; - } elif ("true") { - var("B") x; - } else { - var("C") x; - } ifs; - - val_equal(ifs.x, "A11") a; - assert(a); - - var("a") v; - If ("false") { - v->set("b"); - }; - val_equal(v, "a") a; - assert(a); - - var("a") v; - If ("true") { - v->set("b"); - }; - val_equal(v, "b") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/implode.ncd b/external/badvpn_dns/ncd/tests/implode.ncd deleted file mode 100644 index 2197c17..0000000 --- a/external/badvpn_dns/ncd/tests/implode.ncd +++ /dev/null @@ -1,15 +0,0 @@ -process main { - implode("X", {"a", "bb", "", "c"}) str; - strcmp(str, "aXbbXXc") a; - assert(a); - - implode("", {"a", "b"}) str; - strcmp(str, "ab") a; - assert(a); - - implode("X", {}) str; - strcmp(str, "") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/include.ncd b/external/badvpn_dns/ncd/tests/include.ncd deleted file mode 100644 index eccb76d..0000000 --- a/external/badvpn_dns/ncd/tests/include.ncd +++ /dev/null @@ -1,16 +0,0 @@ -include "include_included.ncdi" -include "include_included.ncdi" -include "include_included2.ncdi" -include "include_included2.ncdi" - -process main { - call("incl_tmpl", {}) c; - val_equal(c.x, "good") a; - assert(a); - - call("incl_tmpl2", {}) c; - val_equal(c.x, "good2") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/include_included.ncdi b/external/badvpn_dns/ncd/tests/include_included.ncdi deleted file mode 100644 index 5fbfd62..0000000 --- a/external/badvpn_dns/ncd/tests/include_included.ncdi +++ /dev/null @@ -1,5 +0,0 @@ -include_guard "include_included" - -template incl_tmpl { - var("good") x; -} diff --git a/external/badvpn_dns/ncd/tests/include_included2.ncdi b/external/badvpn_dns/ncd/tests/include_included2.ncdi deleted file mode 100644 index d765301..0000000 --- a/external/badvpn_dns/ncd/tests/include_included2.ncdi +++ /dev/null @@ -1,5 +0,0 @@ -include_guard "include_included2" - -template incl_tmpl2 { - var("good2") x; -} diff --git a/external/badvpn_dns/ncd/tests/logical.ncd b/external/badvpn_dns/ncd/tests/logical.ncd deleted file mode 100644 index e8956ec..0000000 --- a/external/badvpn_dns/ncd/tests/logical.ncd +++ /dev/null @@ -1,46 +0,0 @@ -process main { - var("true") t; - var("Faalse") f; - - and(t, f) r; - strcmp(r, "false") a; - assert(a); - - and(f, t) r; - strcmp(r, "false") a; - assert(a); - - and(f, f) r; - strcmp(r, "false") a; - assert(a); - - and(t, t) r; - strcmp(r, "true") a; - assert(a); - - or(t, f) r; - strcmp(r, "true") a; - assert(a); - - or(f, t) r; - strcmp(r, "true") a; - assert(a); - - or(t, t) r; - strcmp(r, "true") a; - assert(a); - - or(f, f) r; - strcmp(r, "false") a; - assert(a); - - not(f) r; - strcmp(r, "true") a; - assert(a); - - not(t) r; - strcmp(r, "false") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/multidepend.ncd b/external/badvpn_dns/ncd/tests/multidepend.ncd deleted file mode 100644 index b641f39..0000000 --- a/external/badvpn_dns/ncd/tests/multidepend.ncd +++ /dev/null @@ -1,30 +0,0 @@ -process main { - var("0") x; - process_manager() mgr; - - var("false") backtrack_check; - backtrack_point() point; - If (backtrack_check) { - val_equal(x, "2") a; # must not have rebound temporarily to A during backtracking - assert(a); - exit("0"); - }; - - multiprovide("A"); - mgr->start("t1", "t1", {}); - val_equal(x, "1") a; # must have bound to A immediately - assert(a); - - multiprovide("B") mgr; - val_equal(x, "2") a; # must have rebound to B immediately - assert(a); - - backtrack_check->set("true"); - point->go(); -} - -template t1 { - multidepend({"B", "A"}) dep; - num_add(dep.x, "1") new_x; - dep.x->set(new_x); -} diff --git a/external/badvpn_dns/ncd/tests/netmask.ncd b/external/badvpn_dns/ncd/tests/netmask.ncd deleted file mode 100644 index 90cd744..0000000 --- a/external/badvpn_dns/ncd/tests/netmask.ncd +++ /dev/null @@ -1,15 +0,0 @@ -process main { - ipv4_prefix_to_mask("16") mask; - strcmp(mask, "255.255.0.0") a; - assert(a); - - ipv4_mask_to_prefix("128.0.0.0") prefix; - strcmp(prefix, "1") a; - assert(a); - - ipv4_net_from_addr_and_prefix("192.168.1.4", "24") net; - strcmp(net, "192.168.1.0") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/parse.ncd b/external/badvpn_dns/ncd/tests/parse.ncd deleted file mode 100644 index ae4820c..0000000 --- a/external/badvpn_dns/ncd/tests/parse.ncd +++ /dev/null @@ -1,85 +0,0 @@ -process main { - parse_number("awfa") x; - not(x.succeeded) a; - assert(a); - - parse_number("023182") x; - assert(x.succeeded); - val_equal(x, "23182") a; - assert(a); - - parse_ipv4_addr("192.168.61.007") x; - assert(x.succeeded); - val_equal(x, "192.168.61.7") a; - assert(a); - - parse_ipv6_addr("1234:0000::abcd") x; - assert(x.succeeded); - val_equal(x, "1234::abcd") a; - assert(a); - - parse_value("{"Hello World", {}}") x; - assert(x.succeeded); - val_equal(x, {"Hello World", {}}) a; - assert(a); - - var({"Hello", "fw", {}, {}, ["key":{{}}, [[]:[]]:["k":"v"]], {"st", {"ri", {"ng", [[{}:{}]:[]]}}}}) v; - to_string(v) str; - from_string(str) v2; - to_string(v2) str2; - val_equal(v, v2) a; - assert(a); - val_equal(str, str2) a; - assert(a); - - parse_value("{"Hello", "fw", {}, {}, ["key":{{}}, [[]:[]]:["k":"v"]], {"st", {"ri", {"ng", [[{}:{}]:[]]}}}}") x; - assert(x.succeeded); - - parse_value("{"Hello", "fw", {}, {}, "key":{{}}, [[]:[]]:["k":"v"]], {"st, {"ri", {"ng", [[{}:{}]:[]]}}}}") x; - not(x.succeeded) a; - assert(a); - - parse_value("{"Hello", "fw", {}, {}, ["key":{{}}, [[]:[]]:["k":"v"]], {"st", "ri", "ng", [[{}:{}]:[]]}}}}") x; - not(x.succeeded) a; - assert(a); - - parse_value("{"Hello", "fw", {}, {}, ["key":{{}}, [[]:[]]:["k":"v"]], {"st", {"ri", {"ng", [[{}:{}]:[]]}}}}}") x; - not(x.succeeded) a; - assert(a); - - parse_value("{"Hello", "fw", {}, {}, ["key":{{}}, [[]:[]]:["k":"v"]], {"st", {"ri", {"ng", [[{}:{}]:[]]}}}") x; - not(x.succeeded) a; - assert(a); - - parse_value("{syntax error") x; - not(x.succeeded) a; - assert(a); - - parse_ipv4_cidr_addr("192.168.61.007/24") x; - assert(x.succeeded); - val_equal(x, "192.168.61.7/24") a; - assert(a); - val_equal(x.addr, "192.168.61.7") a; - assert(a); - val_equal(x.prefix, "24") a; - assert(a); - - parse_ipv4_cidr_addr("192.168.61.007/33") x; - not(x.succeeded) a; - assert(a); - - parse_ipv6_cidr_addr("1234:0000::abcd/41") x; - assert(x.succeeded); - val_equal(x, "1234::abcd/41") a; - assert(a); - val_equal(x.addr, "1234::abcd") a; - assert(a); - val_equal(x.prefix, "41") a; - assert(a); - - parse_ipv6_cidr_addr("1234:0000::abcd/129") x; - not(x.succeeded) a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/process_manager.ncd b/external/badvpn_dns/ncd/tests/process_manager.ncd deleted file mode 100644 index 98f0819..0000000 --- a/external/badvpn_dns/ncd/tests/process_manager.ncd +++ /dev/null @@ -1,112 +0,0 @@ -process main { - var("0") x; - - var("false") backtrack_check; - backtrack_point() point; - If (backtrack_check) { - val_equal(x, "10") a; - assert(a); - call("phase2", {}); - }; - - process_manager() mgr; - - mgr->start("name", "increment", {"1", "2", "false"}); - val_equal(x, "1") a; - assert(a); - - mgr->stop("name"); - val_equal(x, "3") a; - assert(a); - - mgr->start("name", "increment", {"3", "4", "true"}); - val_equal(x, "6") a; - assert(a); - - mgr->stop("name"); - val_equal(x, "6") a; - assert(a); - - mgr->start("name", "increment", {"5", "6", "false"}); - val_equal(x, "6") a; - assert(a); - - backtrack_check->set("true"); - point->go(); -} - -template phase2 { - var("0") x; - - var("false") backtrack_check; - backtrack_point() point; - If (backtrack_check) { - val_equal(x, "10") a; - assert(a); - call("phase3", {}); - }; - - process_manager() mgr; - - mgr->start("name", "increment", {"1", "2", "true"}); - val_equal(x, "1") a; - assert(a); - - mgr->stop("name"); - val_equal(x, "1") a; - assert(a); - - mgr->start("name", "increment", {"3", "4", "true"}); - val_equal(x, "1") a; - assert(a); - - depend("INC_DONE"); - val_equal(x, "6") a; - assert(a); - - backtrack_check->set("true"); - point->go(); -} - -template phase3 { - var("0") x; - - var("false") backtrack_check; - backtrack_point() point; - If (backtrack_check) { - val_equal(x, "10") a; - assert(a); - exit("0"); - }; - - process_manager() mgr; - - mgr->start("increment", {"1", "2", "false"}); - val_equal(x, "1") a; - assert(a); - - mgr->start("increment", {"3", "4", "false"}); - val_equal(x, "4") a; - assert(a); - - backtrack_check->set("true"); - point->go(); -} - -template increment { - var(_arg0) amount; - var(_arg1) amount_deinit; - var(_arg2) do_sleep; - imperative("<none>", {}, "increment_deinit_inc", {}, "10000"); - num_add(_caller.x, amount) new_x; - _caller.x->set(new_x); - If (do_sleep) { - sleep("0", "0"); - }; - provide("INC_DONE"); -} - -template increment_deinit_inc { - num_add(_caller._caller.x, _caller.amount_deinit) new_x; - _caller._caller.x->set(new_x); -} diff --git a/external/badvpn_dns/ncd/tests/regex.ncd b/external/badvpn_dns/ncd/tests/regex.ncd deleted file mode 100644 index 3175ebe..0000000 --- a/external/badvpn_dns/ncd/tests/regex.ncd +++ /dev/null @@ -1,48 +0,0 @@ -process main { - var("FOO BAR BAZ QUX goo") x; - regex_replace(x, {"FOO", "BAR", "goo"}, {"BAR", "bar", "GOO"}) y; - strcmp(y, "BAR bar BAZ QUX GOO") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"^hello"}, {"Hello,"}) y; - strcmp(y, "Hello, world") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"goodbye"}, {"hello"}) y; - strcmp(y, "hello world") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"hello world"}, {"hello NCD"}) y; - strcmp(y, "hello NCD") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"wor"}, {"Wor"}) y; - strcmp(y, "hello World") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"ell", "llo"}, {"ELL", "LLO"}) y; - strcmp(y, "hELLo world") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"ell", "el"}, {"ELL", "EL"}) y; - strcmp(y, "hELLo world") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"el", "lo"}, {"EL", "LO"}) y; - strcmp(y, "hELLO world") a; - assert(a); - - var("hello world") x; - regex_replace(x, {"ell", "ll"}, {"ELL", "LL"}) y; - strcmp(y, "hELLo world") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/ncd/tests/run_tests b/external/badvpn_dns/ncd/tests/run_tests deleted file mode 100755 index 071fd20..0000000 --- a/external/badvpn_dns/ncd/tests/run_tests +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -NCD=$1 -USE_VALGRIND=$2 - -if [[ -z $NCD ]] || [[ -n $USE_VALGRIND && $USE_VALGRIND != use_valgrind ]]; then - echo "Usage: $0 <ncd_command> [use_valgrind]" - exit 1 -fi - -if [[ ! -e ./run_tests ]]; then - echo "Must run from the tests directory" - exit 1 -fi - -failed=0 - -for file in ./*.ncd; do - echo "Running: $file" - if [[ $USE_VALGRIND = use_valgrind ]]; then - valgrind --error-exitcode=1 --leak-check=full "$NCD" --loglevel none --config-file "$file" - else - "$NCD" --loglevel none --config-file "$file" - fi - res=$? - if [[ ! $res -eq 0 ]]; then - echo "FAILED" - let failed+=1 - fi -done - -if [[ $failed -gt 0 ]]; then - echo "$failed tests FAILED" - exit 1 -fi - -echo "all tests passed" -exit 0 diff --git a/external/badvpn_dns/ncd/tests/strings.ncd b/external/badvpn_dns/ncd/tests/strings.ncd deleted file mode 100644 index 7be031b..0000000 --- a/external/badvpn_dns/ncd/tests/strings.ncd +++ /dev/null @@ -1,47 +0,0 @@ -process main { - buffer() buf; - buf->append("12"); - buf->append("345"); - buf->append("6"); - num_equal(buf, "123456") a; - assert(a); - - var("false") check; - call("test_func", {}); - assert(check); - - buffer() buf; - buf->append("test_func"); - var("false") check; - call(buf, {}); - assert(check); - - concat("test_func") cnc; - var("false") check; - call(cnc, {}); - assert(check); - - buffer() buf; - buf->append("test_func"); - var("false") check; - process_manager() mgr; - mgr->start(buf, {}); - assert(check); - - buffer() buf; - buf->append("/bin/echo"); - runonce({buf, buf}); - - buffer() buf; - buf->append("12"); - buf->append("345"); - to_string(buf) str; - val_equal(str, ""12345"") a; - assert(a); - - exit("0"); -} - -template test_func { - _caller.check->set("true"); -} diff --git a/external/badvpn_dns/ncd/tests/substr.ncd b/external/badvpn_dns/ncd/tests/substr.ncd deleted file mode 100644 index a3b07b1..0000000 --- a/external/badvpn_dns/ncd/tests/substr.ncd +++ /dev/null @@ -1,37 +0,0 @@ -process main { - var("0123456789") str; - concat(str) external_str; - - call("do_test", {"_caller.str"}); - call("do_test", {"_caller.external_str"}); - - exit("0"); -} - -template do_test { - alias(_arg0) str; - - substr(str, "0") sub; - val_equal(sub, "0123456789") a; - assert(a); - - substr(str, "2") sub; - val_equal(sub, "23456789") a; - assert(a); - - substr(str, "3", "0") sub; - val_equal(sub, "") a; - assert(a); - - substr(str, "3", "6") sub; - val_equal(sub, "345678") a; - assert(a); - - substr(str, "3", "7") sub; - val_equal(sub, "3456789") a; - assert(a); - - substr(str, "3", "8") sub; - val_equal(sub, "3456789") a; - assert(a); -} diff --git a/external/badvpn_dns/ncd/tests/turing.ncd b/external/badvpn_dns/ncd/tests/turing.ncd deleted file mode 100644 index 4e764f1..0000000 --- a/external/badvpn_dns/ncd/tests/turing.ncd +++ /dev/null @@ -1,138 +0,0 @@ -process main { - # Turing machine specification. - var("B") blank; - var([ - {"0", "0"}:{"0", "0", "right"}, - {"0", "1"}:{"1", "x", "right"}, - {"1", "1"}:{"1", "1", "right"}, - {"1", "0"}:{"2", "0", "right"}, - {"2", "0"}:{"2", "0", "right"}, - {"2", "1"}:{"3", "1", "right"}, - {"3", "1"}:{"3", "1", "right"}, - {"3", "0"}:{"4", "1", "left"}, - {"3", "B"}:{"4", "1", "left"}, - {"4", "1"}:{"4", "1", "left"}, - {"4", "0"}:{"5", "0", "left"}, - {"5", "0"}:{"5", "0", "left"}, - {"5", "1"}:{"6", "1", "left"}, - {"5", "x"}:{"h", "x", "stay"}, - {"6", "1"}:{"6", "1", "left"}, - {"6", "x"}:{"0", "x", "right"}, - {"6", "0"}:{"0", "0", "right"} - ]) rules; - var("0") initial_state; - var({}) initial_tape_left; - var({ - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "0", "0", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" - }) initial_tape_right; - - # Perform the computation, stopping when no rule matches. - call("turing", {blank, rules, initial_state, initial_tape_left, initial_tape_right}) results; - - # Check results. - - val_equal(results.tape_left, {"B"}) a; - assert(a); - - val_equal(results.tape_right, - {"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", - "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", - "0", "0", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "1", "1"} - ) a; - assert(a); - - val_equal({results.side, results.pos}, {"right", "55"}) a; - assert(a); - - val_equal(results.state, "h") a; - assert(a); - - exit("0"); -} - -template turing { - alias("_arg0") blank; - value(_arg1) rules; - alias("_arg2") initial_state; - alias("_arg3") initial_tape_left; - alias("_arg4") initial_tape_right; - - # Head state. - var(initial_state) state; - - # Tape. Positions go like this: ... L2 L1 L0 R0 R1 R2 ... - value(initial_tape_left) tape_left; - value(initial_tape_right) tape_right; - - # Make sure each side of the tape has at least one symbol so we can flip easily. - tape_left->insert(tape_left.length, blank); - tape_right->insert(tape_right.length, blank); - - # Head position. - var("right") side; - var("0") pos; - - # Enter loop. - blocker() loop_blk; - loop_blk->up(); - loop_blk->use(); - - # Get symbol under head. - concat("tape_", side) tape_name; - alias(tape_name) cur_tape; - cur_tape->get(pos) symbol; - - # Look for a matching rule. - rules->try_get({state, symbol}) rule; - - If (rule.exists) { - # Extract directions from rule. - rule->get("0") new_state; - rule->get("1") new_symbol; - rule->get("2") move; - - # Change head state. - state->set(new_state); - - # Replace symbol under head. - cur_tape->remove(pos); - cur_tape->insert(pos, new_symbol); - - # Branch based on how we move. - strcmp(move, side) is_outside; - strcmp(move, "stay") is_stay; - strcmp(pos, "0") is_zero; - If (is_outside) { - # Increment position. - num_add(pos, "1") new_pos; - pos->set(new_pos); - - # If the new position is out of range, extend tape. - strcmp(pos, cur_tape.length) need_extend; - If (need_extend) { - cur_tape->insert(pos, blank); - }; - } elif (is_stay) { - # Nop. - getargs(); - } elif (is_zero) { - # Flip side, leave pos at zero. - side->set(move); - } else { - # Decrement position. - num_subtract(pos, "1") new_pos; - pos->set(new_pos); - }; - - # Continue loop. - loop_blk->downup(); - }; -} diff --git a/external/badvpn_dns/ncd/tests/value.ncd b/external/badvpn_dns/ncd/tests/value.ncd deleted file mode 100644 index e483b3f..0000000 --- a/external/badvpn_dns/ncd/tests/value.ncd +++ /dev/null @@ -1,258 +0,0 @@ -process main { - value({"A", {"B", "C"}, {{"D"}, "E"}}) v; - val_equal(v, {"A", {"B", "C"}, {{"D"}, "E"}}) a; - assert(a); - - v->get("1") w; - val_equal(w, {"B", "C"}) a; - assert(a); - - w->delete(); - val_equal(v, {"A", {{"D"}, "E"}}) a; - assert(a); - - v->getpath({"1", "1"}) f; - val_equal(f, "E") a; - assert(a); - - value(["hello":{"Hello", "Good evening!"}, "goodbye":{"Bye", "See you"}]) v; - val_equal(v, ["hello":{"Hello", "Good evening!"}, "goodbye":{"Bye", "See you"}]) a; - assert(a); - - val_equal(v.keys, {"goodbye", "hello"}) a; - assert(a); - - v->get("hello") h; - val_equal(h, {"Hello", "Good evening!"}) a; - assert(a); - - v->get("goodbye") g; - val_equal(g, {"Bye", "See you"}) a; - assert(a); - - g->delete(); - val_equal(v, ["hello":{"Hello", "Good evening!"}]) a; - assert(a); - - h->delete(); - val_equal(v, []); - assert(a); - - v->delete(); - strcmp(v.exists, "false") a; - assert(a); - - value({"D", "F", "H"}) v; - v->insert("0", "A") a; # ADFH - v->insert("1", "B") b; # ABDFH - v->insert("5", "I") i; # ABDFHI - val_equal(v, {"A", "B", "D", "F", "H", "I"}) a; - assert(a); - - value(["k1":"v1", "k2":"v2", "k3":"v3"]) v; - v->insert("k0", "v0") v0; # k0=v0 k1=v1 k2=v2 k3=v3 - v->insert("k0", "V0") V0; # k0=V0 k1=v1 k2=v2 k3=v3 - val_equal(v0, "v0") a; - assert(a); - val_equal(V0, "V0") a; - assert(a); - - value({"D", "F", "H"}) v; - v->remove("0"); # FH - v->remove("1"); # F - val_equal(v, {"F"}) a; - assert(a); - - value(["k1":"v1", "k2":"v2", "k3":"v3"]) v; - v->remove("k1"); - v->remove("k3"); - val_equal(v, ["k2":"v2"]) a; - assert(a); - - value(["k1":"v1", "k2":"v2", "k3":"v3"]) v; - v->try_get("k1") v1; - v->try_get("k7") v7; - val_equal(v1.exists, "true") a; - assert(a); - val_equal(v7.exists, "false") a; - assert(a); - - value(["k1":"v1", "k2":"v2", "k3":"v3"]) v; - imperative("<none>", {}, "check1", {}, "10000"); - v->insert_undo("k1", "V1") V1; - strcmp(V1, "V1") a; - assert(a); - v->insert_undo("k4", "V4"); - v->remove("k2"); - val_equal(v, ["k1":"V1", "k3":"v3", "k4":"V4"]) a; - assert(a); - - value({"a", "b", "c"}) v; - v->replace("0", "A"); - v->replace("1", "B"); - v->replace("2", "C"); - v->replace("3", "D"); - val_equal(v, {"A", "B", "C", "D"}) a; - assert(a); - - value({"a", "b", "c"}) v; - imperative("<none>", {}, "check2", {}, "10000"); - v->replace_undo("0", "A"); - v->replace_undo("1", "B"); - v->replace_undo("2", "C"); - v->replace_undo("3", "D"); - val_equal(v, {"A", "B", "C", "D"}) a; - assert(a); - - value("A") v; - v->reset("B"); - val_equal(v, "B") a; - assert(a); - - value({"a", "c"}) v; - v->insert_undo("1", "b") vb; - val_equal(v, {"a", "b", "c"}) a; - assert(a); - val_equal(vb, "b") a; - assert(a); - vb->reset("B"); - val_equal(v, {"a", "c"}) a; - assert(a); - val_equal(vb, "B") a; - assert(a); - - value({"a", "b", "c"}) v; - v->get("1") vb; - vb->replace_this("B") vB; - val_equal(vb, "b") a; - assert(a); - val_equal(vB, "B") a; - assert(a); - v->get("1") vB2; - val_equal(vB2, "B") a; - assert(a); - - value(["a":"va", "b":"vb", "c":"vc"]) v; - v->get("b") vb; - vb->replace_this("vB") vB; - val_equal(vB, "vB") a; - assert(a); - val_equal(vb, "vb") a; - assert(a); - v->get("b") vB2; - val_equal(vB2, "vB") a; - assert(a); - - value({"a", "b", "c"}) v; - v->get("1") vb; - imperative("<none>", {}, "check3", {}, "10000"); - vb->replace_this_undo("B") vB; - val_equal(vb, "b") a; - assert(a); - val_equal(vB, "B") a; - assert(a); - v->get("1") vB2; - val_equal(vB2, "B") a; - assert(a); - - value(["a":"va", "b":"vb", "c":"vc"]) v; - v->get("b") vb; - imperative("<none>", {}, "check4", {}, "10000"); - vb->replace_this_undo("vB") vB; - val_equal(vB, "vB") a; - assert(a); - val_equal(vb, "vb") a; - assert(a); - v->get("b") vB2; - val_equal(vB2, "vB") a; - assert(a); - - value("") v; - v->append("ab"); - v->append("cde"); - v->append(v); - v->append(""); - v->append("f"); - val_equal(v, "abcdeabcdef") a; - assert(a); - - value({}) v; - v->insert("1") ins_v; - v->insert("2"); - v->insert("3"); - v->insert("4"); - v->append("5"); - v->append("6"); - val_equal(v, {"1", "2", "3", "4", "5", "6"}) a; - assert(a); - val_equal(ins_v, "1") a; - assert(a); - - value({}) v; - imperative("<none>", {}, "check5", {}, "10000"); - v->insert_undo("1"); - v->insert_undo("2"); - v->insert_undo("3"); - v->insert_undo("4"); - val_equal(v, {"1", "2", "3", "4"}) a; - assert(a); - - buffer() buf; - buf->append("123"); - value(buf) v; - val_equal(v, "123") a; - assert(a); - v->substr("2") sub_v; - val_equal(sub_v, "3") a; - assert(a); - v->append("456789012345"); - val_equal(v, "123456789012345") a; - assert(a); - buffer() numbuf; - numbuf->append("1"); - numbuf->append("2"); - v->substr(numbuf) sub_v; - val_equal(sub_v, "345") a; - assert(a); - - concat("hello", "world") cnc; - value(cnc) v; - val_equal(v, "helloworld") a; - assert(a); - v->substr("2") sub_v; - val_equal(sub_v, "lloworld") a; - assert(a); - v->append("!!"); - val_equal(v, "helloworld!!") a; - assert(a); - v->substr("1") sub_v; - val_equal(sub_v, "elloworld!!") a; - assert(a); - - exit("0"); -} - -template check1 { - val_equal(_caller.v, ["k1":"v1", "k3":"v3"]) a; - assert(a); -} - -template check2 { - val_equal(_caller.v, {"a", "b", "c"}) a; - assert(a); -} - -template check3 { - val_equal(_caller.v, {"a", "b", "c"}) a; - assert(a); -} - -template check4 { - val_equal(_caller.v, ["a":"va", "b":"vb", "c":"vc"]) a; - assert(a); -} - -template check5 { - val_equal(_caller.v, {}) a; - assert(a); -} diff --git a/external/badvpn_dns/ncd/tests/value_substr.ncd b/external/badvpn_dns/ncd/tests/value_substr.ncd deleted file mode 100644 index ea46e8a..0000000 --- a/external/badvpn_dns/ncd/tests/value_substr.ncd +++ /dev/null @@ -1,25 +0,0 @@ -process foo { - value("0123456789") str; - - str->substr("0") sub; - strcmp(sub, str) a; - assert(a); - - str->substr("1") sub; - strcmp(sub, "123456789") a; - assert(a); - - str->substr("1", "0") sub; - strcmp(sub, "") a; - assert(a); - - str->substr("1", "9") sub; - strcmp(sub, "123456789") a; - assert(a); - - str->substr("1", "8") sub; - strcmp(sub, "12345678") a; - assert(a); - - exit("0"); -} diff --git a/external/badvpn_dns/nspr_support/BSSLConnection.c b/external/badvpn_dns/nspr_support/BSSLConnection.c deleted file mode 100644 index fea9c94..0000000 --- a/external/badvpn_dns/nspr_support/BSSLConnection.c +++ /dev/null @@ -1,1024 +0,0 @@ -/** - * @file BSSLConnection.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <prerror.h> -#include <ssl.h> - -#include <string.h> -#include <stdlib.h> - -#include <misc/print_macros.h> -#include <base/BLog.h> - -#include "BSSLConnection.h" - -#include <generated/blog_channel_BSSLConnection.h> - -#define THREADWORK_STATE_NONE 0 -#define THREADWORK_STATE_HANDSHAKE 1 -#define THREADWORK_STATE_READ 2 -#define THREADWORK_STATE_WRITE 3 - -static void backend_threadwork_start (struct BSSLConnection_backend *b, int op); -static int backend_threadwork_do_io (struct BSSLConnection_backend *b); -static void connection_init_job_handler (BSSLConnection *o); -static void connection_init_up (BSSLConnection *o); -static void connection_try_io (BSSLConnection *o); -static void connection_threadwork_func_work (void *user); -static void connection_threadwork_handler_done (void *user); -static void connection_recv_job_handler (BSSLConnection *o); -static void connection_try_handshake (BSSLConnection *o); -static void connection_try_send (BSSLConnection *o); -static void connection_try_recv (BSSLConnection *o); -static void connection_send_if_handler_send (BSSLConnection *o, uint8_t *data, int data_len); -static void connection_recv_if_handler_recv (BSSLConnection *o, uint8_t *data, int data_len); - -int bprconnection_initialized = 0; -PRDescIdentity bprconnection_identity; - -static PRFileDesc * get_bottom (PRFileDesc *layer) -{ - while (layer->lower) { - layer = layer->lower; - } - - return layer; -} - -static PRStatus method_close (PRFileDesc *fd) -{ - struct BSSLConnection_backend *b = (struct BSSLConnection_backend *)fd->secret; - ASSERT(!b->con) - ASSERT(b->threadwork_state == THREADWORK_STATE_NONE) - - // free mutexes - if ((b->flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE) || (b->flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) { - BMutex_Free(&b->recv_buf_mutex); - BMutex_Free(&b->send_buf_mutex); - } - - // free backend - free(b); - - // set no secret - fd->secret = NULL; - - return PR_SUCCESS; -} - -static PRInt32 method_read (PRFileDesc *fd, void *buf, PRInt32 amount) -{ - struct BSSLConnection_backend *b = (struct BSSLConnection_backend *)fd->secret; - ASSERT(amount > 0) - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Lock(&b->recv_buf_mutex); - } - - // if we are receiving into buffer or buffer has no data left, refuse recv - if (b->recv_busy || b->recv_pos == b->recv_len) { - if (b->threadwork_state != THREADWORK_STATE_NONE) { - b->threadwork_want_recv = 1; - BMutex_Unlock(&b->recv_buf_mutex); - } else { - // start receiving if not already - if (!b->recv_busy) { - // set recv busy - b->recv_busy = 1; - - // receive into buffer - StreamRecvInterface_Receiver_Recv(b->recv_if, b->recv_buf, BSSLCONNECTION_BUF_SIZE); - } - } - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - // limit amount to available data - if (amount > b->recv_len - b->recv_pos) { - amount = b->recv_len - b->recv_pos; - } - - // copy data - memcpy(buf, b->recv_buf + b->recv_pos, amount); - - // update buffer - b->recv_pos += amount; - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Unlock(&b->recv_buf_mutex); - } - - return amount; -} - -static PRInt32 method_write (PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - struct BSSLConnection_backend *b = (struct BSSLConnection_backend *)fd->secret; - ASSERT(amount > 0) - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Lock(&b->send_buf_mutex); - } - - ASSERT(!b->send_busy || b->send_pos < b->send_len) - - // if there is data in buffer, refuse send - if (b->send_pos < b->send_len) { - if (b->threadwork_state != THREADWORK_STATE_NONE) { - b->threadwork_want_send = 1; - BMutex_Unlock(&b->send_buf_mutex); - } - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - // limit amount to buffer size - if (amount > BSSLCONNECTION_BUF_SIZE) { - amount = BSSLCONNECTION_BUF_SIZE; - } - - // init buffer - memcpy(b->send_buf, buf, amount); - b->send_pos = 0; - b->send_len = amount; - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Unlock(&b->send_buf_mutex); - } else { - // start sending - b->send_busy = 1; - StreamPassInterface_Sender_Send(b->send_if, b->send_buf + b->send_pos, b->send_len - b->send_pos); - } - - return amount; -} - -static PRStatus method_shutdown (PRFileDesc *fd, PRIntn how) -{ - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return PR_FAILURE; -} - -static PRInt32 method_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) -{ - ASSERT(flags == 0) - - return method_read(fd, buf, amount); -} - -static PRInt32 method_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) -{ - ASSERT(flags == 0) - - return method_write(fd, buf, amount); -} - -static PRInt16 method_poll (PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - *out_flags = 0; - return in_flags; -} - -static PRStatus method_getpeername (PRFileDesc *fd, PRNetAddr *addr) -{ - memset(addr, 0, sizeof(*addr)); - addr->raw.family = PR_AF_INET; - return PR_SUCCESS; -} - -static PRStatus method_getsocketoption (PRFileDesc *fd, PRSocketOptionData *data) -{ - switch (data->option) { - case PR_SockOpt_Nonblocking: - data->value.non_blocking = PR_TRUE; - return PR_SUCCESS; - } - - PR_SetError(PR_UNKNOWN_ERROR, 0); - return PR_FAILURE; -} - -static PRStatus method_setsocketoption (PRFileDesc *fd, const PRSocketOptionData *data) -{ - PR_SetError(PR_UNKNOWN_ERROR, 0); - return PR_FAILURE; -} - -static PRIntn _PR_InvalidIntn (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRInt32 _PR_InvalidInt32 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRInt64 _PR_InvalidInt64 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PROffset32 _PR_InvalidOffset32 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PROffset64 _PR_InvalidOffset64 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRStatus _PR_InvalidStatus (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return PR_FAILURE; -} - -static PRFileDesc *_PR_InvalidDesc (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return NULL; -} - -static PRIOMethods methods = { - (PRDescType)0, - method_close, - method_read, - method_write, - (PRAvailableFN)_PR_InvalidInt32, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidOffset32, - (PRSeek64FN)_PR_InvalidOffset64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt32, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - method_shutdown, - method_recv, - method_send, - (PRRecvfromFN)_PR_InvalidInt32, - (PRSendtoFN)_PR_InvalidInt32, - method_poll, - (PRAcceptreadFN)_PR_InvalidInt32, - (PRTransmitfileFN)_PR_InvalidInt32, - (PRGetsocknameFN)_PR_InvalidStatus, - method_getpeername, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - method_getsocketoption, - method_setsocketoption, - (PRSendfileFN)_PR_InvalidInt32, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn -}; - -static void backend_send_if_handler_done (struct BSSLConnection_backend *b, int data_len) -{ - ASSERT(b->send_busy) - ASSERT(b->send_len > 0) - ASSERT(b->send_pos < b->send_len) - ASSERT(data_len > 0) - ASSERT(data_len <= b->send_len - b->send_pos) - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Lock(&b->send_buf_mutex); - } - - // update buffer - b->send_pos += data_len; - - // send more if needed - if (b->send_pos < b->send_len) { - StreamPassInterface_Sender_Send(b->send_if, b->send_buf + b->send_pos, b->send_len - b->send_pos); - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Unlock(&b->send_buf_mutex); - } - return; - } - - // set send not busy - b->send_busy = 0; - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Unlock(&b->send_buf_mutex); - } - - // notify connection - if (b->con && !b->con->have_error) { - connection_try_io(b->con); - return; - } -} - -static void backend_recv_if_handler_done (struct BSSLConnection_backend *b, int data_len) -{ - ASSERT(b->recv_busy) - ASSERT(data_len > 0) - ASSERT(data_len <= BSSLCONNECTION_BUF_SIZE) - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Lock(&b->recv_buf_mutex); - } - - // init buffer - b->recv_busy = 0; - b->recv_pos = 0; - b->recv_len = data_len; - - if (b->threadwork_state != THREADWORK_STATE_NONE) { - BMutex_Unlock(&b->recv_buf_mutex); - } - - // notify connection - if (b->con && !b->con->have_error) { - connection_try_io(b->con); - return; - } -} - -static void backend_threadwork_start (struct BSSLConnection_backend *b, int op) -{ - ASSERT(b->con) - ASSERT(b->threadwork_state == THREADWORK_STATE_NONE) - ASSERT(op == THREADWORK_STATE_HANDSHAKE || op == THREADWORK_STATE_READ || op == THREADWORK_STATE_WRITE) - - b->threadwork_state = op; - b->threadwork_want_recv = 0; - b->threadwork_want_send = 0; - BThreadWork_Init(&b->threadwork, b->twd, connection_threadwork_handler_done, b->con, connection_threadwork_func_work, b->con); -} - -static int backend_threadwork_do_io (struct BSSLConnection_backend *b) -{ - ASSERT(b->con) - ASSERT(b->threadwork_state == THREADWORK_STATE_NONE) - - int io_ready = (b->threadwork_want_recv && !b->recv_busy && b->recv_pos < b->recv_len) || - (b->threadwork_want_send && b->send_pos == b->send_len); - - if (b->threadwork_want_recv && b->recv_pos == b->recv_len && !b->recv_busy) { - b->recv_busy = 1; - StreamRecvInterface_Receiver_Recv(b->recv_if, b->recv_buf, BSSLCONNECTION_BUF_SIZE); - } - - if (b->send_pos < b->send_len && !b->send_busy) { - b->send_busy = 1; - StreamPassInterface_Sender_Send(b->send_if, b->send_buf + b->send_pos, b->send_len - b->send_pos); - } - - return io_ready; -} - -static void connection_report_error (BSSLConnection *o) -{ - ASSERT(!o->have_error) - - // set error - o->have_error = 1; - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BSSLCONNECTION_EVENT_ERROR)); -} - -static void connection_init_job_handler (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_error) - ASSERT(!o->up) - - connection_try_handshake(o); -} - -static void connection_init_up (BSSLConnection *o) -{ - // unset init job - // (just in the impossible case that handshake completed before the init job executed) - BPending_Unset(&o->init_job); - - // init send interface - StreamPassInterface_Init(&o->send_if, (StreamPassInterface_handler_send)connection_send_if_handler_send, o, o->pg); - - // init recv interface - StreamRecvInterface_Init(&o->recv_if, (StreamRecvInterface_handler_recv)connection_recv_if_handler_recv, o, o->pg); - - // init recv job - BPending_Init(&o->recv_job, o->pg, (BPending_handler)connection_recv_job_handler, o); - - // set no send data - o->send_len = -1; - - // set no recv data - o->recv_avail = -1; - - // set up - o->up = 1; -} - -static void connection_try_io (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_error) - - if (!o->up) { - connection_try_handshake(o); - return; - } - - if (o->send_len > 0) { - if (o->recv_avail > 0) { - BPending_Set(&o->recv_job); - } - - connection_try_send(o); - return; - } - - if (o->recv_avail > 0) { - connection_try_recv(o); - return; - } -} - -static void connection_threadwork_func_work (void *user) -{ - BSSLConnection *o = (BSSLConnection *)user; - struct BSSLConnection_backend *b = o->backend; - ASSERT(b->threadwork_state != THREADWORK_STATE_NONE) - - switch (b->threadwork_state) { - case THREADWORK_STATE_HANDSHAKE: - b->threadwork_result_sec = SSL_ForceHandshake(o->prfd); - break; - case THREADWORK_STATE_WRITE: - b->threadwork_result_pr = PR_Write(o->prfd, o->send_data, o->send_len); - break; - case THREADWORK_STATE_READ: - b->threadwork_result_pr = PR_Read(o->prfd, o->recv_data, o->recv_avail); - break; - default: - ASSERT(0); - } - - b->threadwork_error = PR_GetError(); -} - -static void connection_threadwork_handler_done (void *user) -{ - BSSLConnection *o = (BSSLConnection *)user; - struct BSSLConnection_backend *b = o->backend; - ASSERT(b->threadwork_state != THREADWORK_STATE_NONE) - - // remember what operation the threadwork was performing - int op = b->threadwork_state; - - // free threadwork - BThreadWork_Free(&b->threadwork); - b->threadwork_state = THREADWORK_STATE_NONE; - - // start any necessary backend I/O operations, and determine if any of the requested - // backend I/O that was not available at the time is now available - int io_ready = backend_threadwork_do_io(b); - - switch (op) { - case THREADWORK_STATE_HANDSHAKE: { - ASSERT(!o->up) - ASSERT((b->flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE)) - - if (b->threadwork_result_sec == SECFailure) { - if (b->threadwork_error == PR_WOULD_BLOCK_ERROR) { - if (io_ready) { - // requested backend I/O got ready, try again - backend_threadwork_start(o->backend, THREADWORK_STATE_HANDSHAKE); - } - return; - } - BLog(BLOG_ERROR, "SSL_ForceHandshake failed (%"PRIi32")", b->threadwork_error); - connection_report_error(o); - return; - } - - // init up - connection_init_up(o); - - // report up - o->handler(o->user, BSSLCONNECTION_EVENT_UP); - return; - } break; - - case THREADWORK_STATE_WRITE: { - ASSERT(o->up) - ASSERT((b->flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) - ASSERT(o->send_len > 0) - - PRInt32 result = b->threadwork_result_pr; - PRErrorCode error = b->threadwork_error; - - if (result < 0) { - if (error == PR_WOULD_BLOCK_ERROR) { - if (io_ready) { - // requested backend I/O got ready, try again - backend_threadwork_start(o->backend, THREADWORK_STATE_WRITE); - } else if (o->recv_avail > 0) { - // don't forget about receiving - backend_threadwork_start(o->backend, THREADWORK_STATE_READ); - } - return; - } - BLog(BLOG_ERROR, "PR_Write failed (%"PRIi32")", error); - connection_report_error(o); - return; - } - - ASSERT(result > 0) - ASSERT(result <= o->send_len) - - // set no send data - o->send_len = -1; - - // don't forget about receiving - if (o->recv_avail > 0) { - backend_threadwork_start(o->backend, THREADWORK_STATE_READ); - } - - // finish send operation - StreamPassInterface_Done(&o->send_if, result); - } break; - - case THREADWORK_STATE_READ: { - ASSERT(o->up) - ASSERT((b->flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) - ASSERT(o->recv_avail > 0) - - PRInt32 result = b->threadwork_result_pr; - PRErrorCode error = b->threadwork_error; - - if (result < 0) { - if (error == PR_WOULD_BLOCK_ERROR) { - if (io_ready) { - // requested backend I/O got ready, try again - backend_threadwork_start(o->backend, THREADWORK_STATE_READ); - } else if (o->send_len > 0) { - // don't forget about sending - backend_threadwork_start(o->backend, THREADWORK_STATE_WRITE); - } - return; - } - BLog(BLOG_ERROR, "PR_Read failed (%"PRIi32")", error); - connection_report_error(o); - return; - } - - if (result == 0) { - BLog(BLOG_ERROR, "PR_Read returned 0"); - connection_report_error(o); - return; - } - - ASSERT(result > 0) - ASSERT(result <= o->recv_avail) - - // set no recv data - o->recv_avail = -1; - - // don't forget about sending - if (o->send_len > 0) { - backend_threadwork_start(o->backend, THREADWORK_STATE_WRITE); - } - - // finish receive operation - StreamRecvInterface_Done(&o->recv_if, result); - } break; - - default: - ASSERT(0); - } - - return; -} - -static void connection_recv_job_handler (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_error) - ASSERT(o->up) - ASSERT(o->recv_avail > 0) - - connection_try_recv(o); - return; -} - -static void connection_try_handshake (BSSLConnection *o) -{ - ASSERT(!o->have_error) - ASSERT(!o->up) - - // continue in threadwork if requested - if ((o->backend->flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE)) { - if (o->backend->threadwork_state == THREADWORK_STATE_NONE) { - backend_threadwork_start(o->backend, THREADWORK_STATE_HANDSHAKE); - } - return; - } - - // try handshake - SECStatus res = SSL_ForceHandshake(o->prfd); - if (res == SECFailure) { - PRErrorCode error = PR_GetError(); - if (error == PR_WOULD_BLOCK_ERROR) { - return; - } - BLog(BLOG_ERROR, "SSL_ForceHandshake failed (%"PRIi32")", error); - connection_report_error(o); - return; - } - - // init up - connection_init_up(o); - - // report up - o->handler(o->user, BSSLCONNECTION_EVENT_UP); - return; -} - -static void connection_try_send (BSSLConnection *o) -{ - ASSERT(!o->have_error) - ASSERT(o->up) - ASSERT(o->send_len > 0) - - // continue in threadwork if requested - if ((o->backend->flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) { - if (o->backend->threadwork_state == THREADWORK_STATE_NONE) { - backend_threadwork_start(o->backend, THREADWORK_STATE_WRITE); - } - return; - } - - // send - PRInt32 res = PR_Write(o->prfd, o->send_data, o->send_len); - if (res < 0) { - PRErrorCode error = PR_GetError(); - if (error == PR_WOULD_BLOCK_ERROR) { - return; - } - BLog(BLOG_ERROR, "PR_Write failed (%"PRIi32")", error); - connection_report_error(o); - return; - } - - ASSERT(res > 0) - ASSERT(res <= o->send_len) - - // set no send data - o->send_len = -1; - - // done - StreamPassInterface_Done(&o->send_if, res); -} - -static void connection_try_recv (BSSLConnection *o) -{ - ASSERT(!o->have_error) - ASSERT(o->up) - ASSERT(o->recv_avail > 0) - - // unset recv job - BPending_Unset(&o->recv_job); - - // continue in threadwork if requested - if ((o->backend->flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) { - if (o->backend->threadwork_state == THREADWORK_STATE_NONE) { - backend_threadwork_start(o->backend, THREADWORK_STATE_READ); - } - return; - } - - // recv - PRInt32 res = PR_Read(o->prfd, o->recv_data, o->recv_avail); - if (res < 0) { - PRErrorCode error = PR_GetError(); - if (error == PR_WOULD_BLOCK_ERROR) { - return; - } - BLog(BLOG_ERROR, "PR_Read failed (%"PRIi32")", error); - connection_report_error(o); - return; - } - - if (res == 0) { - BLog(BLOG_ERROR, "PR_Read returned 0"); - connection_report_error(o); - return; - } - - ASSERT(res > 0) - ASSERT(res <= o->recv_avail) - - // set no recv data - o->recv_avail = -1; - - // done - StreamRecvInterface_Done(&o->recv_if, res); -} - -static void connection_send_if_handler_send (BSSLConnection *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_error) - ASSERT(o->up) - ASSERT(o->send_len == -1) - ASSERT(data_len > 0) - -#ifndef NDEBUG - ASSERT(!o->releasebuffers_called) - o->user_io_started = 1; -#endif - - // limit amount for PR_Write - if (data_len > INT32_MAX) { - data_len = INT32_MAX; - } - - // set send data - o->send_data = data; - o->send_len = data_len; - - // start sending - connection_try_send(o); -} - -static void connection_recv_if_handler_recv (BSSLConnection *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_error) - ASSERT(o->up) - ASSERT(o->recv_avail == -1) - ASSERT(data_len > 0) - -#ifndef NDEBUG - ASSERT(!o->releasebuffers_called) - o->user_io_started = 1; -#endif - - // limit amount for PR_Read - if (data_len > INT32_MAX) { - data_len = INT32_MAX; - } - - // set recv data - o->recv_data = data; - o->recv_avail = data_len; - - // start receiving - connection_try_recv(o); -} - -int BSSLConnection_GlobalInit (void) -{ - ASSERT(!bprconnection_initialized) - - if ((bprconnection_identity = PR_GetUniqueIdentity("BSSLConnection")) == PR_INVALID_IO_LAYER) { - BLog(BLOG_ERROR, "PR_GetUniqueIdentity failed"); - return 0; - } - - bprconnection_initialized = 1; - - return 1; -} - -int BSSLConnection_MakeBackend (PRFileDesc *prfd, StreamPassInterface *send_if, StreamRecvInterface *recv_if, BThreadWorkDispatcher *twd, int flags) -{ - ASSERT(bprconnection_initialized) - ASSERT(!(flags & ~(BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE | BSSLCONNECTION_FLAG_THREADWORK_IO))) - ASSERT(!(flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE) || twd) - ASSERT(!(flags & BSSLCONNECTION_FLAG_THREADWORK_IO) || twd) - - // don't do stuff in threads if threads aren't available - if (((flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE) || (flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) && - !BThreadWorkDispatcher_UsingThreads(twd) - ) { - BLog(BLOG_WARNING, "SSL operations in threads requested but threads are not available"); - flags &= ~(BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE | BSSLCONNECTION_FLAG_THREADWORK_IO); - } - - // allocate backend - struct BSSLConnection_backend *b = (struct BSSLConnection_backend *)malloc(sizeof(*b)); - if (!b) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init mutexes - if ((flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE) || (flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) { - if (!BMutex_Init(&b->send_buf_mutex)) { - BLog(BLOG_ERROR, "BMutex_Init failed"); - goto fail1; - } - - if (!BMutex_Init(&b->recv_buf_mutex)) { - BLog(BLOG_ERROR, "BMutex_Init failed"); - goto fail2; - } - } - - // init arguments - b->send_if = send_if; - b->recv_if = recv_if; - b->twd = twd; - b->flags = flags; - - // init interfaces - StreamPassInterface_Sender_Init(b->send_if, (StreamPassInterface_handler_done)backend_send_if_handler_done, b); - StreamRecvInterface_Receiver_Init(b->recv_if, (StreamRecvInterface_handler_done)backend_recv_if_handler_done, b); - - // set no connection - b->con = NULL; - - // init send buffer - b->send_busy = 0; - b->send_len = 0; - b->send_pos = 0; - - // init recv buffer - b->recv_busy = 0; - b->recv_pos = 0; - b->recv_len = 0; - - // set threadwork state - b->threadwork_state = THREADWORK_STATE_NONE; - - // init prfd - memset(prfd, 0, sizeof(*prfd)); - prfd->methods = &methods; - prfd->secret = (PRFilePrivate *)b; - prfd->identity = bprconnection_identity; - - return 1; - - if ((flags & BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE) || (flags & BSSLCONNECTION_FLAG_THREADWORK_IO)) { -fail2: - BMutex_Free(&b->send_buf_mutex); - } -fail1: - free(b); -fail0: - return 0; -} - -void BSSLConnection_Init (BSSLConnection *o, PRFileDesc *prfd, int force_handshake, BPendingGroup *pg, void *user, - BSSLConnection_handler handler) -{ - ASSERT(force_handshake == 0 || force_handshake == 1) - ASSERT(handler) - ASSERT(bprconnection_initialized) - ASSERT(get_bottom(prfd)->identity == bprconnection_identity) - ASSERT(!((struct BSSLConnection_backend *)(get_bottom(prfd)->secret))->con) - - // init arguments - o->prfd = prfd; - o->pg = pg; - o->user = user; - o->handler = handler; - - // set backend - o->backend = (struct BSSLConnection_backend *)(get_bottom(prfd)->secret); - ASSERT(!o->backend->con) - ASSERT(o->backend->threadwork_state == THREADWORK_STATE_NONE) - - // set have no error - o->have_error = 0; - - // init init job - BPending_Init(&o->init_job, o->pg, (BPending_handler)connection_init_job_handler, o); - - if (force_handshake) { - // set not up - o->up = 0; - - // set init job - BPending_Set(&o->init_job); - } else { - // init up - connection_init_up(o); - } - - // set backend connection - o->backend->con = o; - -#ifndef NDEBUG - o->user_io_started = 0; - o->releasebuffers_called = 0; -#endif - - DebugError_Init(&o->d_err, o->pg); - DebugObject_Init(&o->d_obj); -} - -void BSSLConnection_Free (BSSLConnection *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); -#ifndef NDEBUG - ASSERT(o->releasebuffers_called || !o->user_io_started) -#endif - ASSERT(o->backend->threadwork_state == THREADWORK_STATE_NONE) - - if (o->up) { - // free recv job - BPending_Free(&o->recv_job); - - // free recv interface - StreamRecvInterface_Free(&o->recv_if); - - // free send interface - StreamPassInterface_Free(&o->send_if); - } - - // free init job - BPending_Free(&o->init_job); - - // unset backend connection - o->backend->con = NULL; -} - -void BSSLConnection_ReleaseBuffers (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); -#ifndef NDEBUG - ASSERT(!o->releasebuffers_called) -#endif - - // wait for threadwork to finish - if (o->backend->threadwork_state != THREADWORK_STATE_NONE) { - BThreadWork_Free(&o->backend->threadwork); - o->backend->threadwork_state = THREADWORK_STATE_NONE; - } - -#ifndef NDEBUG - o->releasebuffers_called = 1; -#endif -} - -StreamPassInterface * BSSLConnection_GetSendIf (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return &o->send_if; -} - -StreamRecvInterface * BSSLConnection_GetRecvIf (BSSLConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return &o->recv_if; -} diff --git a/external/badvpn_dns/nspr_support/BSSLConnection.h b/external/badvpn_dns/nspr_support/BSSLConnection.h deleted file mode 100644 index 1152cac..0000000 --- a/external/badvpn_dns/nspr_support/BSSLConnection.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file BSSLConnection.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BSSLCONNECTION_H -#define BADVPN_BSSLCONNECTION_H - -#include <prio.h> -#include <ssl.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <base/BMutex.h> -#include <flow/StreamPassInterface.h> -#include <flow/StreamRecvInterface.h> -#include <threadwork/BThreadWork.h> - -#define BSSLCONNECTION_EVENT_UP 1 -#define BSSLCONNECTION_EVENT_ERROR 2 - -#define BSSLCONNECTION_BUF_SIZE 4096 - -#define BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE (1 << 0) -#define BSSLCONNECTION_FLAG_THREADWORK_IO (1 << 1) - -typedef void (*BSSLConnection_handler) (void *user, int event); - -struct BSSLConnection_backend; - -typedef struct { - PRFileDesc *prfd; - BPendingGroup *pg; - void *user; - BSSLConnection_handler handler; - struct BSSLConnection_backend *backend; - int have_error; - int up; - BPending init_job; - StreamPassInterface send_if; - StreamRecvInterface recv_if; - BPending recv_job; - const uint8_t *send_data; - int send_len; - uint8_t *recv_data; - int recv_avail; -#ifndef NDEBUG - int user_io_started; - int releasebuffers_called; -#endif - DebugError d_err; - DebugObject d_obj; -} BSSLConnection; - -struct BSSLConnection_backend { - StreamPassInterface *send_if; - StreamRecvInterface *recv_if; - BThreadWorkDispatcher *twd; - int flags; - BSSLConnection *con; - uint8_t send_buf[BSSLCONNECTION_BUF_SIZE]; - int send_busy; - int send_pos; - int send_len; - uint8_t recv_buf[BSSLCONNECTION_BUF_SIZE]; - int recv_busy; - int recv_pos; - int recv_len; - int threadwork_state; - int threadwork_want_recv; - int threadwork_want_send; - BThreadWork threadwork; - SECStatus threadwork_result_sec; - PRInt32 threadwork_result_pr; - PRErrorCode threadwork_error; - BMutex send_buf_mutex; - BMutex recv_buf_mutex; -}; - -int BSSLConnection_GlobalInit (void) WARN_UNUSED; -int BSSLConnection_MakeBackend (PRFileDesc *prfd, StreamPassInterface *send_if, StreamRecvInterface *recv_if, BThreadWorkDispatcher *twd, int flags) WARN_UNUSED; - -void BSSLConnection_Init (BSSLConnection *o, PRFileDesc *prfd, int force_handshake, BPendingGroup *pg, void *user, - BSSLConnection_handler handler); -void BSSLConnection_Free (BSSLConnection *o); -void BSSLConnection_ReleaseBuffers (BSSLConnection *o); -StreamPassInterface * BSSLConnection_GetSendIf (BSSLConnection *o); -StreamRecvInterface * BSSLConnection_GetRecvIf (BSSLConnection *o); - -#endif diff --git a/external/badvpn_dns/nspr_support/CMakeLists.txt b/external/badvpn_dns/nspr_support/CMakeLists.txt deleted file mode 100644 index d2eb3e7..0000000 --- a/external/badvpn_dns/nspr_support/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(NSPRSUPPORT_SOURCES - DummyPRFileDesc.c - BSSLConnection.c -) -badvpn_add_library(nspr_support "system;flow;threadwork" "${NSPR_LIBRARIES};${NSS_LIBRARIES}" "${NSPRSUPPORT_SOURCES}") diff --git a/external/badvpn_dns/nspr_support/DummyPRFileDesc.c b/external/badvpn_dns/nspr_support/DummyPRFileDesc.c deleted file mode 100644 index 543a3d5..0000000 --- a/external/badvpn_dns/nspr_support/DummyPRFileDesc.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file DummyPRFileDesc.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include <prerror.h> -#include <prmem.h> - -#include <misc/debug.h> -#include <misc/offset.h> - -#include <nspr_support/DummyPRFileDesc.h> - -#ifndef NDEBUG -int dummyprfiledesc_initialized = 0; -#endif -PRDescIdentity dummyprfiledesc_identity; - -static PRStatus method_close (PRFileDesc *fd) -{ - return PR_SUCCESS; -} - -static PRStatus method_getpeername (PRFileDesc *fd, PRNetAddr *addr) -{ - PR_SetError(PR_UNKNOWN_ERROR, 0); - return PR_FAILURE; -} - -static PRIntn _PR_InvalidIntn (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRInt16 _PR_InvalidInt16 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRInt32 _PR_InvalidInt32 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRInt64 _PR_InvalidInt64 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PROffset32 _PR_InvalidOffset32 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PROffset64 _PR_InvalidOffset64 (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} - -static PRStatus _PR_InvalidStatus (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return PR_FAILURE; -} - -static PRFileDesc *_PR_InvalidDesc (void) -{ - ASSERT(0) - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return NULL; -} - -static PRIOMethods methods = { - (PRDescType)0, - method_close, - (PRReadFN)_PR_InvalidInt32, - (PRWriteFN)_PR_InvalidInt32, - (PRAvailableFN)_PR_InvalidInt32, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidOffset32, - (PRSeek64FN)_PR_InvalidOffset64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt32, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt32, - (PRSendFN)_PR_InvalidInt32, - (PRRecvfromFN)_PR_InvalidInt32, - (PRSendtoFN)_PR_InvalidInt32, - (PRPollFN)_PR_InvalidInt16, - (PRAcceptreadFN)_PR_InvalidInt32, - (PRTransmitfileFN)_PR_InvalidInt32, - (PRGetsocknameFN)_PR_InvalidStatus, - method_getpeername, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt32, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn, - (PRReservedFN)_PR_InvalidIntn -}; - -int DummyPRFileDesc_GlobalInit (void) -{ - ASSERT(!dummyprfiledesc_initialized) - - if ((dummyprfiledesc_identity = PR_GetUniqueIdentity("DummyPRFileDesc")) == PR_INVALID_IO_LAYER) { - return 0; - } - - #ifndef NDEBUG - dummyprfiledesc_initialized = 1; - #endif - - return 1; -} - -void DummyPRFileDesc_Create (PRFileDesc *prfd) -{ - ASSERT(dummyprfiledesc_initialized) - - memset(prfd, 0, sizeof(*prfd)); - prfd->methods = &methods; - prfd->secret = NULL; - prfd->identity = dummyprfiledesc_identity; -} diff --git a/external/badvpn_dns/nspr_support/DummyPRFileDesc.h b/external/badvpn_dns/nspr_support/DummyPRFileDesc.h deleted file mode 100644 index 413f105..0000000 --- a/external/badvpn_dns/nspr_support/DummyPRFileDesc.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file DummyPRFileDesc.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Dummy NSPR file descriptor (PRFileDesc). - * Used for creating a model SSL file descriptor to cache various stuff - * to improve performance. - */ - -#ifndef BADVPN_NSPRSUPPORT_DUMMYPRFILEDESC_H -#define BADVPN_NSPRSUPPORT_DUMMYPRFILEDESC_H - -#include <prio.h> - -#include <misc/debug.h> - -extern PRDescIdentity dummyprfiledesc_identity; - -/** - * Globally initialize the dummy NSPR file descriptor backend. - * Must not have been called successfully. - * - * @return 1 on success, 0 on failure - */ -int DummyPRFileDesc_GlobalInit (void) WARN_UNUSED; - -/** - * Creates a dummy NSPR file descriptor. - * {@link DummyPRFileDesc_GlobalInit} must have been done. - * - * @param prfd uninitialized PRFileDesc structure - */ -void DummyPRFileDesc_Create (PRFileDesc *prfd); - -#endif diff --git a/external/badvpn_dns/predicate/BPredicate.c b/external/badvpn_dns/predicate/BPredicate.c deleted file mode 100644 index 5d5dadb..0000000 --- a/external/badvpn_dns/predicate/BPredicate.c +++ /dev/null @@ -1,284 +0,0 @@ -/** - * @file BPredicate.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <predicate/BPredicate_internal.h> -#include <predicate/BPredicate_parser.h> -#include <predicate/LexMemoryBufferInput.h> -#include <base/BLog.h> - -#include <predicate/BPredicate.h> - -#include <generated/blog_channel_BPredicate.h> - -static int eval_predicate_node (BPredicate *p, struct predicate_node *root); - -void yyerror (YYLTYPE *yylloc, yyscan_t scanner, struct predicate_node **result, char *str) -{ -} - -static int string_comparator (void *user, char *s1, char *s2) -{ - int cmp = strcmp(s1, s2); - return B_COMPARE(cmp, 0); -} - -static int eval_function (BPredicate *p, struct predicate_node *root) -{ - ASSERT(root->type == NODE_FUNCTION) - - // lookup function by name - ASSERT(root->function.name) - BAVLNode *tree_node; - if (!(tree_node = BAVL_LookupExact(&p->functions_tree, root->function.name))) { - BLog(BLOG_WARNING, "unknown function"); - return 0; - } - BPredicateFunction *func = UPPER_OBJECT(tree_node, BPredicateFunction, tree_node); - - // evaluate arguments - struct arguments_node *arg = root->function.args; - void *args[PREDICATE_MAX_ARGS]; - for (int i = 0; i < func->num_args; i++) { - if (!arg) { - BLog(BLOG_WARNING, "not enough arguments"); - return 0; - } - switch (func->args[i]) { - case PREDICATE_TYPE_BOOL: - if (arg->arg.type != ARGUMENT_PREDICATE) { - BLog(BLOG_WARNING, "expecting predicate argument"); - return 0; - } - if (!eval_predicate_node(p, arg->arg.predicate)) { - return 0; - } - args[i] = &arg->arg.predicate->eval_value; - break; - case PREDICATE_TYPE_STRING: - if (arg->arg.type != ARGUMENT_STRING) { - BLog(BLOG_WARNING, "expecting string argument"); - return 0; - } - args[i] = arg->arg.string; - break; - default: - ASSERT(0); - } - arg = arg->next; - } - - if (arg) { - BLog(BLOG_WARNING, "too many arguments"); - return 0; - } - - // call callback - #ifndef NDEBUG - p->in_function = 1; - #endif - int res = func->callback(func->user, args); - #ifndef NDEBUG - p->in_function = 0; - #endif - if (res != 0 && res != 1) { - BLog(BLOG_WARNING, "callback returned non-boolean"); - return 0; - } - - root->eval_value = res; - return 1; -} - -int eval_predicate_node (BPredicate *p, struct predicate_node *root) -{ - ASSERT(root) - - switch (root->type) { - case NODE_CONSTANT: - root->eval_value = root->constant.val; - return 1; - case NODE_NEG: - if (!eval_predicate_node(p, root->neg.op)) { - return 0; - } - root->eval_value = !root->neg.op->eval_value; - return 1; - case NODE_CONJUNCT: - if (!eval_predicate_node(p, root->conjunct.op1)) { - return 0; - } - if (!root->conjunct.op1->eval_value) { - root->eval_value = 0; - return 1; - } - if (!eval_predicate_node(p, root->conjunct.op2)) { - return 0; - } - if (!root->conjunct.op2->eval_value) { - root->eval_value = 0; - return 1; - } - root->eval_value = 1; - return 1; - case NODE_DISJUNCT: - if (!eval_predicate_node(p, root->disjunct.op1)) { - return 0; - } - if (root->disjunct.op1->eval_value) { - root->eval_value = 1; - return 1; - } - if (!eval_predicate_node(p, root->disjunct.op2)) { - return 0; - } - if (root->disjunct.op2->eval_value) { - root->eval_value = 1; - return 1; - } - root->eval_value = 0; - return 1; - case NODE_FUNCTION: - return eval_function(p, root); - default: - ASSERT(0) - return 0; - } -} - -int BPredicate_Init (BPredicate *p, char *str) -{ - // initialize input buffer object - LexMemoryBufferInput input; - LexMemoryBufferInput_Init(&input, str, strlen(str)); - - // initialize lexical analyzer - yyscan_t scanner; - yylex_init_extra(&input, &scanner); - - // parse - struct predicate_node *root = NULL; - int result = yyparse(scanner, &root); - - // free lexical analyzer - yylex_destroy(scanner); - - // check for errors - if (LexMemoryBufferInput_HasError(&input) || result != 0 || !root) { - if (root) { - free_predicate_node(root); - } - return 0; - } - - // init tree - p->root = root; - - // init functions tree - BAVL_Init(&p->functions_tree, OFFSET_DIFF(BPredicateFunction, name, tree_node), (BAVL_comparator)string_comparator, NULL); - - // init debuggind - #ifndef NDEBUG - p->in_function = 0; - #endif - - // init debug object - DebugObject_Init(&p->d_obj); - - return 1; -} - -void BPredicate_Free (BPredicate *p) -{ - ASSERT(BAVL_IsEmpty(&p->functions_tree)) - ASSERT(!p->in_function) - - // free debug object - DebugObject_Free(&p->d_obj); - - // free tree - free_predicate_node((struct predicate_node *)p->root); -} - -int BPredicate_Eval (BPredicate *p) -{ - ASSERT(!p->in_function) - - if (!eval_predicate_node(p, (struct predicate_node *)p->root)) { - return -1; - } - - return ((struct predicate_node *)p->root)->eval_value; -} - -void BPredicateFunction_Init (BPredicateFunction *o, BPredicate *p, char *name, int *args, int num_args, BPredicate_callback callback, void *user) -{ - ASSERT(strlen(name) <= PREDICATE_MAX_NAME) - ASSERT(!BAVL_LookupExact(&p->functions_tree, name)) - ASSERT(num_args >= 0) - ASSERT(num_args <= PREDICATE_MAX_ARGS) - for (int i = 0; i < num_args; i++) { - ASSERT(args[i] == PREDICATE_TYPE_BOOL || args[i] == PREDICATE_TYPE_STRING) - } - ASSERT(!p->in_function) - - // init arguments - o->p = p; - strcpy(o->name, name); - memcpy(o->args, args, num_args * sizeof(int)); - o->num_args = num_args; - o->callback = callback; - o->user = user; - - // add to tree - ASSERT_EXECUTE(BAVL_Insert(&p->functions_tree, &o->tree_node, NULL)) - - // init debug object - DebugObject_Init(&o->d_obj); -} - -void BPredicateFunction_Free (BPredicateFunction *o) -{ - ASSERT(!o->p->in_function) - - BPredicate *p = o->p; - - // free debug object - DebugObject_Free(&o->d_obj); - - // remove from tree - BAVL_Remove(&p->functions_tree, &o->tree_node); -} diff --git a/external/badvpn_dns/predicate/BPredicate.h b/external/badvpn_dns/predicate/BPredicate.h deleted file mode 100644 index 04b3aa5..0000000 --- a/external/badvpn_dns/predicate/BPredicate.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file BPredicate.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object that parses and evaluates a logical expression. - * Allows the user to define custom functions than can be - * used in the expression. - * - * Syntax and semantics for logical expressions: - * - * - true - * Logical true constant. Evaluates to 1. - * - * - false - * Logical false constant. Evaluates to 0. - * - * - NOT expression - * Logical negation. If the expression evaluates to error, the - * negation evaluates to error. - * - * - expression OR expression - * Logical disjunction. The second expression is only evaluated - * if the first expression evaluates to false. If a sub-expression - * evaluates to error, the disjunction evaluates to error. - * - * - expression AND expression - * Logical conjunction. The second expression is only evaluated - * if the first expression evaluates to true. If a sub-expression - * evaluates to error, the conjunction evaluates to error. - * - * - function(arg, ..., arg) - * Evaluation of a user-provided function (function is the name of the - * function, [a-zA-Z0-9_]+). - * If the function with the given name does not exist, it evaluates to - * error. - * Arguments are evaluated from left to right. Each argument can either - * be a logical expression or a string (characters enclosed in double - * quotes, without any double quote). - * If an argument is encountered, but all needed arguments have already - * been evaluated, the function evaluates to error. - * If an argument is of wrong type, it is not evaluated and the function - * evaluates to error. - * If an argument evaluates to error, the function evaluates to error. - * If after all arguments have been evaluated, the function needs more - * arguments, it evaluates to error. - * Then the handler function is called. If it returns anything other - * than 1 and 0, the function evaluates to error. Otherwise it evaluates - * to what the handler function returned. - */ - -#ifndef BADVPN_PREDICATE_BPREDICATE_H -#define BADVPN_PREDICATE_BPREDICATE_H - -#include <misc/debug.h> -#include <structure/BAVL.h> -#include <base/DebugObject.h> - -#define PREDICATE_TYPE_BOOL 1 -#define PREDICATE_TYPE_STRING 2 - -#define PREDICATE_MAX_NAME 16 -#define PREDICATE_MAX_ARGS 16 - -/** - * Handler function called when evaluating a custom function in the predicate. - * - * @param user value passed to {@link BPredicateFunction_Init} - * @param args arguments to the function. Points to an array of pointers (as many as the - * function has arguments), where each pointer points to either to an int or - * a zero-terminated string (depending on the type of the argument). - * @return 1 for true, 0 for false, -1 for error - */ -typedef int (*BPredicate_callback) (void *user, void **args); - -/** - * Object that parses and evaluates a logical expression. - * Allows the user to define custom functions than can be - * used in the expression. - */ -typedef struct { - DebugObject d_obj; - void *root; - BAVL functions_tree; - #ifndef NDEBUG - int in_function; - #endif -} BPredicate; - -/** - * Object that represents a custom function in {@link BPredicate}. - */ -typedef struct { - DebugObject d_obj; - BPredicate *p; - char name[PREDICATE_MAX_NAME + 1]; - int args[PREDICATE_MAX_ARGS]; - int num_args; - BPredicate_callback callback; - void *user; - BAVLNode tree_node; -} BPredicateFunction; - -/** - * Initializes the object. - * - * @param p the object - * @param str logical expression - * @return 1 on success, 0 on failure - */ -int BPredicate_Init (BPredicate *p, char *str) WARN_UNUSED; - -/** - * Frees the object. - * Must have no custom functions. - * Must not be called from function handlers. - * - * @param p the object - */ -void BPredicate_Free (BPredicate *p); - -/** - * Evaluates the logical expression. - * Must not be called from function handlers. - * - * @param p the object - * @return 1 for true, 0 for false, -1 for error - */ -int BPredicate_Eval (BPredicate *p); - -/** - * Registers a custom function for {@link BPredicate}. - * Must not be called from function handlers. - * - * @param o the object - * @param p predicate to register the function for - * @param args array of argument types. Each type is either PREDICATE_TYPE_BOOL or PREDICATE_TYPE_STRING. - * @param num_args number of arguments for the function. Must be >=0 and <=PREDICATE_MAX_ARGS. - * @param callback handler to call to evaluate the function - * @param user value to pass to handler - */ -void BPredicateFunction_Init (BPredicateFunction *o, BPredicate *p, char *name, int *args, int num_args, BPredicate_callback callback, void *user); - -/** - * Removes a custom function for {@link BPredicate}. - * Must not be called from function handlers. - * - * @param o the object - */ -void BPredicateFunction_Free (BPredicateFunction *o); - -#endif diff --git a/external/badvpn_dns/predicate/BPredicate.l b/external/badvpn_dns/predicate/BPredicate.l deleted file mode 100644 index 71bfd2f..0000000 --- a/external/badvpn_dns/predicate/BPredicate.l +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file BPredicate.l - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} lexer file. - */ - -%{ - -#include <string.h> -#include <stdlib.h> - -#include <predicate/LexMemoryBufferInput.h> -#include <predicate/BPredicate_internal.h> - -#include <generated/bison_BPredicate.h> - -#define YY_INPUT(buffer, res, max_size) \ - int bytes_read = LexMemoryBufferInput_Read((LexMemoryBufferInput *)yyget_extra(yyscanner), buffer, max_size); \ - res = (bytes_read == 0 ? YY_NULL : bytes_read); - -%} - -%option reentrant stack noyywrap bison-bridge bison-locations never-interactive nounistd - -%% -( return SPAR; -) return EPAR; -, return COMMA; -AND return AND; -OR return OR; -NOT return NOT; -true return CONSTANT_TRUE; -false return CONSTANT_FALSE; -[a-zA-Z0-9_]+ { - int l = strlen(yytext); - char *p = (char *)malloc(l + 1); - if (p) { - memcpy(p, yytext, l); - p[l] = '\0'; - } - yylval->text = p; - return NAME; - } -"[^"]*" { - int l = strlen(yytext); - char *p = (char *)malloc(l - 1); - if (p) { - memcpy(p, yytext + 1, l - 2); - p[l - 2] = '\0'; - } - yylval->text = p; - return STRING; - } -[ \t\n]+ ; -. LexMemoryBufferInput_SetError((LexMemoryBufferInput *)yyget_extra(yyscanner)); return 0; // remember failure and report EOF -%% diff --git a/external/badvpn_dns/predicate/BPredicate.y b/external/badvpn_dns/predicate/BPredicate.y deleted file mode 100644 index f48df45..0000000 --- a/external/badvpn_dns/predicate/BPredicate.y +++ /dev/null @@ -1,345 +0,0 @@ -/** - * @file BPredicate.y - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} grammar file. - */ - -%{ - -#include <stdlib.h> - -#include <predicate/BPredicate_internal.h> -#include <predicate/BPredicate_parser.h> - -#define YYLEX_PARAM scanner - -static struct predicate_node * make_constant (int val) -{ - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - return NULL; - } - - n->type = NODE_CONSTANT; - n->constant.val = val; - - return n; -} - -static struct predicate_node * make_negation (struct predicate_node *op) -{ - if (!op) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_NEG; - n->neg.op = op; - - return n; - -fail: - if (op) { - free_predicate_node(op); - } - return NULL; -} - -static struct predicate_node * make_conjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_CONJUNCT; - n->conjunct.op1 = op1; - n->conjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_disjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_DISJUNCT; - n->disjunct.op1 = op1; - n->disjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_function (char *name, struct arguments_node *args, int need_args) -{ - if (!name || (!args && need_args)) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_FUNCTION; - n->function.name = name; - n->function.args = args; - - return n; - -fail: - if (name) { - free(name); - } - if (args) { - free_arguments_node(args); - } - return NULL; -} - -static struct arguments_node * make_arguments (struct arguments_arg arg, struct arguments_node *next, int need_next) -{ - if (arg.type == ARGUMENT_INVALID || (!next && need_next)) { - goto fail; - } - - struct arguments_node *n = (struct arguments_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->arg = arg; - n->next = next; - - return n; - -fail: - free_argument(arg); - if (next) { - free_arguments_node(next); - } - return NULL; -} - -static struct arguments_arg make_argument_predicate (struct predicate_node *pr) -{ - struct arguments_arg ret; - - if (!pr) { - goto fail; - } - - ret.type = ARGUMENT_PREDICATE; - ret.predicate = pr; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - -static struct arguments_arg make_argument_string (char *string) -{ - struct arguments_arg ret; - - if (!string) { - goto fail; - } - - ret.type = ARGUMENT_STRING; - ret.string = string; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - -%} - -%pure-parser -%locations -%parse-param {void *scanner} -%parse-param {struct predicate_node **result} - -%union { - char *text; - struct predicate_node *node; - struct arguments_node *arg_node; - struct predicate_node nfaw; - struct arguments_arg arg_arg; -}; - -// token types -%token <text> STRING NAME -%token PEER1_NAME PEER2_NAME AND OR NOT SPAR EPAR CONSTANT_TRUE CONSTANT_FALSE COMMA - -// string token destructor -%destructor { - free($$); -} STRING NAME - -// return values -%type <node> predicate constant parentheses neg conjunct disjunct function -%type <arg_node> arguments -%type <arg_arg> argument - -// predicate node destructor -%destructor { - if ($$) { - free_predicate_node($$); - } -} predicate constant parentheses neg conjunct disjunct function - -// argument node destructor -%destructor { - if ($$) { - free_arguments_node($$); - } -} arguments - -// argument argument destructor -%destructor { - free_argument($$); -} argument - -%left OR -%left AND -%nonassoc NOT -%right COMMA - -%% - -input: - predicate { - *result = $1; - } - ; - -predicate: constant | parentheses | neg | conjunct | disjunct | function; - -constant: - CONSTANT_TRUE { - $$ = make_constant(1); - } - | - CONSTANT_FALSE { - $$ = make_constant(0); - } - ; - -parentheses: - SPAR predicate EPAR { - $$ = $2; - } - ; - -neg: - NOT predicate { - $$ = make_negation($2); - } - ; - -conjunct: - predicate AND predicate { - $$ = make_conjunction($1, $3); - } - ; - -disjunct: - predicate OR predicate { - $$ = make_disjunction($1, $3); - } - ; - -function: - NAME SPAR EPAR { - $$ = make_function($1, NULL, 0); - } - | - NAME SPAR arguments EPAR { - $$ = make_function($1, $3, 1); - } - ; - -arguments: - argument { - $$ = make_arguments($1, NULL, 0); - } - | - argument COMMA arguments { - $$ = make_arguments($1, $3, 1); - } - ; - -argument: - predicate { - $$ = make_argument_predicate($1); - } - | - STRING { - $$ = make_argument_string($1); - } - ; diff --git a/external/badvpn_dns/predicate/BPredicate_internal.h b/external/badvpn_dns/predicate/BPredicate_internal.h deleted file mode 100644 index 12db554..0000000 --- a/external/badvpn_dns/predicate/BPredicate_internal.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file BPredicate_internal.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} expression tree definitions and functions. - */ - -#ifndef BADVPN_PREDICATE_BPREDICATE_INTERNAL_H -#define BADVPN_PREDICATE_BPREDICATE_INTERNAL_H - -#include <misc/debug.h> - -#define NODE_CONSTANT 0 -#define NODE_NEG 2 -#define NODE_CONJUNCT 3 -#define NODE_DISJUNCT 4 -#define NODE_FUNCTION 5 - -struct arguments_node; - -struct predicate_node { - int type; - union { - struct { - int val; - } constant; - struct { - struct predicate_node *op; - } neg; - struct { - struct predicate_node *op1; - struct predicate_node *op2; - } conjunct; - struct { - struct predicate_node *op1; - struct predicate_node *op2; - } disjunct; - struct { - char *name; - struct arguments_node *args; - } function; - }; - int eval_value; -}; - -#define ARGUMENT_INVALID 0 -#define ARGUMENT_PREDICATE 1 -#define ARGUMENT_STRING 2 - -struct arguments_arg { - int type; - union { - struct predicate_node *predicate; - char *string; - }; -}; - -struct arguments_node { - struct arguments_arg arg; - struct arguments_node *next; -}; - -static void free_predicate_node (struct predicate_node *root); -static void free_argument (struct arguments_arg arg); -static void free_arguments_node (struct arguments_node *n); - -void free_predicate_node (struct predicate_node *root) -{ - ASSERT(root) - - switch (root->type) { - case NODE_CONSTANT: - break; - case NODE_NEG: - free_predicate_node(root->neg.op); - break; - case NODE_CONJUNCT: - free_predicate_node(root->conjunct.op1); - free_predicate_node(root->conjunct.op2); - break; - case NODE_DISJUNCT: - free_predicate_node(root->disjunct.op1); - free_predicate_node(root->disjunct.op2); - break; - case NODE_FUNCTION: - free(root->function.name); - if (root->function.args) { - free_arguments_node(root->function.args); - } - break; - default: - ASSERT(0) - break; - } - - free(root); -} - -void free_argument (struct arguments_arg arg) -{ - switch (arg.type) { - case ARGUMENT_INVALID: - break; - case ARGUMENT_PREDICATE: - free_predicate_node(arg.predicate); - break; - case ARGUMENT_STRING: - free(arg.string); - break; - default: - ASSERT(0); - } -} - -void free_arguments_node (struct arguments_node *n) -{ - ASSERT(n) - - free_argument(n->arg); - - if (n->next) { - free_arguments_node(n->next); - } - - free(n); -} - -#endif diff --git a/external/badvpn_dns/predicate/BPredicate_parser.h b/external/badvpn_dns/predicate/BPredicate_parser.h deleted file mode 100644 index e7f4a7b..0000000 --- a/external/badvpn_dns/predicate/BPredicate_parser.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @file BPredicate_parser.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} parser definitions. - */ - -#ifndef BADVPN_PREDICATE_BPREDICATE_PARSER_H -#define BADVPN_PREDICATE_BPREDICATE_PARSER_H - -#define YY_NO_UNISTD_H - -#include <predicate/BPredicate_internal.h> - -#include <generated/bison_BPredicate.h> -#include <generated/flex_BPredicate.h> - -// implemented in BPredicate.c -void yyerror (YYLTYPE *yylloc, yyscan_t scanner, struct predicate_node **result, char *str); - -#endif diff --git a/external/badvpn_dns/predicate/CMakeLists.txt b/external/badvpn_dns/predicate/CMakeLists.txt deleted file mode 100644 index dfd852e..0000000 --- a/external/badvpn_dns/predicate/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(PREDICATE_SOURCES - BPredicate.c - ${PROJECT_SOURCE_DIR}/generated/flex_BPredicate.c - ${PROJECT_SOURCE_DIR}/generated/bison_BPredicate.c -) -badvpn_add_library(predicate "system" "" "${PREDICATE_SOURCES}") diff --git a/external/badvpn_dns/predicate/LexMemoryBufferInput.h b/external/badvpn_dns/predicate/LexMemoryBufferInput.h deleted file mode 100644 index e8f1730..0000000 --- a/external/badvpn_dns/predicate/LexMemoryBufferInput.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file LexMemoryBufferInput.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object that can be used by a lexer to read input from a memory buffer. - */ - -#ifndef BADVPN_PREDICATE_LEXMEMORYBUFFERINPUT_H -#define BADVPN_PREDICATE_LEXMEMORYBUFFERINPUT_H - -#include <string.h> - -#include <misc/debug.h> - -typedef struct { - char *buf; - int len; - int pos; - int error; -} LexMemoryBufferInput; - -static void LexMemoryBufferInput_Init (LexMemoryBufferInput *input, char *buf, int len) -{ - input->buf = buf; - input->len = len; - input->pos = 0; - input->error = 0; -} - -static int LexMemoryBufferInput_Read (LexMemoryBufferInput *input, char *dest, int len) -{ - ASSERT(dest) - ASSERT(len > 0) - - if (input->pos >= input->len) { - return 0; - } - - int to_read = input->len - input->pos; - if (to_read > len) { - to_read = len; - } - - memcpy(dest, input->buf + input->pos, to_read); - input->pos += to_read; - - return to_read; -} - -static void LexMemoryBufferInput_SetError (LexMemoryBufferInput *input) -{ - input->error = 1; -} - -static int LexMemoryBufferInput_HasError (LexMemoryBufferInput *input) -{ - return input->error; -} - -#endif diff --git a/external/badvpn_dns/protocol/addr.bproto b/external/badvpn_dns/protocol/addr.bproto deleted file mode 100644 index f020350..0000000 --- a/external/badvpn_dns/protocol/addr.bproto +++ /dev/null @@ -1,11 +0,0 @@ -// message for an AddrProto address -message addr { - // address type. from addr.h - required uint8 type = 1; - // for IPv4 and IPv6 addresses, the port (network byte order) - optional data("2") ip_port = 2; - // for IPv4 addresses, the IP address - optional data("4") ipv4_addr = 3; - // for IPv6 addresses, the IP address - optional data("16") ipv6_addr = 4; -}; diff --git a/external/badvpn_dns/protocol/addr.h b/external/badvpn_dns/protocol/addr.h deleted file mode 100644 index 9d20265..0000000 --- a/external/badvpn_dns/protocol/addr.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - * @file addr.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * AddrProto, a protocol for encoding network addresses. - * - * AddrProto is built with BProto, the protocol and code generator for building - * custom message protocols. The BProto specification file is addr.bproto. - */ - -#ifndef BADVPN_PROTOCOL_ADDR_H -#define BADVPN_PROTOCOL_ADDR_H - -#include <stdint.h> -#include <string.h> - -#include <misc/debug.h> -#include <system/BAddr.h> -#include <base/BLog.h> - -#include <generated/bproto_addr.h> - -#include <generated/blog_channel_addr.h> - -#define ADDR_TYPE_IPV4 1 -#define ADDR_TYPE_IPV6 2 - -#define ADDR_SIZE_IPV4 (addr_SIZEtype + addr_SIZEip_port + addr_SIZEipv4_addr) -#define ADDR_SIZE_IPV6 (addr_SIZEtype + addr_SIZEip_port + addr_SIZEipv6_addr) - -/** - * Determines if the given address is supported by AddrProto. - * Depends only on the type of the address. - * - * @param addr address to check. Must be recognized according to {@link BAddr_IsRecognized}. - * @return 1 if supported, 0 if not - */ -static int addr_supported (BAddr addr); - -/** - * Determines the size of the given address when encoded by AddrProto. - * Depends only on the type of the address. - * - * @param addr address to check. Must be supported according to {@link addr_supported}. - * @return encoded size - */ -static int addr_size (BAddr addr); - -/** - * Encodes an address according to AddrProto. - * - * @param out output buffer. Must have at least addr_size(addr) space. - * @param addr address to encode. Must be supported according to {@link addr_supported}. - */ -static void addr_write (uint8_t *out, BAddr addr); - -/** - * Decodes an address according to AddrProto. - * - * @param data input buffer containing the address to decode - * @param data_len size of input. Must be >=0. - * @param out_addr the decoded address will be stored here on success - * @return 1 on success, 0 on failure - */ -static int addr_read (uint8_t *data, int data_len, BAddr *out_addr) WARN_UNUSED; - -int addr_supported (BAddr addr) -{ - BAddr_Assert(&addr); - - switch (addr.type) { - case BADDR_TYPE_IPV4: - case BADDR_TYPE_IPV6: - return 1; - default: - return 0; - } -} - -int addr_size (BAddr addr) -{ - ASSERT(addr_supported(addr)) - - switch (addr.type) { - case BADDR_TYPE_IPV4: - return ADDR_SIZE_IPV4; - case BADDR_TYPE_IPV6: - return ADDR_SIZE_IPV6; - default: - ASSERT(0) - return 0; - } -} - -void addr_write (uint8_t *out, BAddr addr) -{ - ASSERT(addr_supported(addr)) - - addrWriter writer; - addrWriter_Init(&writer, out); - - switch (addr.type) { - case BADDR_TYPE_IPV4: { - addrWriter_Addtype(&writer, ADDR_TYPE_IPV4); - uint8_t *out_port = addrWriter_Addip_port(&writer); - memcpy(out_port, &addr.ipv4.port, sizeof(addr.ipv4.port)); - uint8_t *out_addr = addrWriter_Addipv4_addr(&writer); - memcpy(out_addr, &addr.ipv4.ip, sizeof(addr.ipv4.ip)); - } break; - case BADDR_TYPE_IPV6: { - addrWriter_Addtype(&writer, ADDR_TYPE_IPV6); - uint8_t *out_port = addrWriter_Addip_port(&writer); - memcpy(out_port, &addr.ipv6.port, sizeof(addr.ipv6.port)); - uint8_t *out_addr = addrWriter_Addipv6_addr(&writer); - memcpy(out_addr, addr.ipv6.ip, sizeof(addr.ipv6.ip)); - } break; - default: - ASSERT(0); - } - - int len = addrWriter_Finish(&writer); - B_USE(len) - - ASSERT(len == addr_size(addr)) -} - -int addr_read (uint8_t *data, int data_len, BAddr *out_addr) -{ - ASSERT(data_len >= 0) - - addrParser parser; - if (!addrParser_Init(&parser, data, data_len)) { - BLog(BLOG_ERROR, "failed to parse addr"); - return 0; - } - - uint8_t type = 0; // to remove warning - addrParser_Gettype(&parser, &type); - - switch (type) { - case ADDR_TYPE_IPV4: { - uint8_t *port_data; - if (!addrParser_Getip_port(&parser, &port_data)) { - BLog(BLOG_ERROR, "port missing for IPv4 address"); - return 0; - } - uint8_t *addr_data; - if (!addrParser_Getipv4_addr(&parser, &addr_data)) { - BLog(BLOG_ERROR, "address missing for IPv4 address"); - return 0; - } - uint16_t port; - uint32_t addr; - memcpy(&port, port_data, sizeof(port)); - memcpy(&addr, addr_data, sizeof(addr)); - BAddr_InitIPv4(out_addr, addr, port); - } break; - case ADDR_TYPE_IPV6: { - uint8_t *port_data; - if (!addrParser_Getip_port(&parser, &port_data)) { - BLog(BLOG_ERROR, "port missing for IPv6 address"); - return 0; - } - uint8_t *addr_data; - if (!addrParser_Getipv6_addr(&parser, &addr_data)) { - BLog(BLOG_ERROR, "address missing for IPv6 address"); - return 0; - } - uint16_t port; - memcpy(&port, port_data, sizeof(port)); - BAddr_InitIPv6(out_addr, addr_data, port); - } break; - default: - BLog(BLOG_ERROR, "unknown address type %d", (int)type); - return 0; - } - - return 1; -} - -#endif diff --git a/external/badvpn_dns/protocol/dataproto.h b/external/badvpn_dns/protocol/dataproto.h deleted file mode 100644 index 998d953..0000000 --- a/external/badvpn_dns/protocol/dataproto.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file dataproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for DataProto, the protocol for data transport between VPN peers. - * - * All multi-byte integers in structs are little-endian, unless stated otherwise. - * - * A DataProto packet consists of: - * - the header (struct {@link dataproto_header}) - * - between zero and DATAPROTO_MAX_PEER_IDS destination peer IDs (struct {@link dataproto_peer_id}) - * - the payload, e.g. Ethernet frame - */ - -#ifndef BADVPN_PROTOCOL_DATAPROTO_H -#define BADVPN_PROTOCOL_DATAPROTO_H - -#include <stdint.h> - -#include <protocol/scproto.h> -#include <misc/packed.h> - -#define DATAPROTO_MAX_PEER_IDS 1 - -#define DATAPROTO_FLAGS_RECEIVING_KEEPALIVES 1 - -/** - * DataProto header. - */ -B_START_PACKED -struct dataproto_header { - /** - * Bitwise OR of flags. Possible flags: - * - DATAPROTO_FLAGS_RECEIVING_KEEPALIVES - * Indicates that when the peer sent this packet, it has received at least - * one packet from the other peer in the last keep-alive tolerance time. - */ - uint8_t flags; - - /** - * ID of the peer this frame originates from. - */ - peerid_t from_id; - - /** - * Number of destination peer IDs that follow. - * Must be <=DATAPROTO_MAX_PEER_IDS. - */ - peerid_t num_peer_ids; -} B_PACKED; -B_END_PACKED - -/** - * Structure for a destination peer ID in DataProto. - * Wraps a single peerid_t in a packed struct for easy access. - */ -B_START_PACKED -struct dataproto_peer_id { - peerid_t id; -} B_PACKED; -B_END_PACKED - -#define DATAPROTO_MAX_OVERHEAD (sizeof(struct dataproto_header) + DATAPROTO_MAX_PEER_IDS * sizeof(struct dataproto_peer_id)) - -#endif diff --git a/external/badvpn_dns/protocol/fragmentproto.h b/external/badvpn_dns/protocol/fragmentproto.h deleted file mode 100644 index 4d2315e..0000000 --- a/external/badvpn_dns/protocol/fragmentproto.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file fragmentproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for FragmentProto, a protocol that allows sending of arbitrarily sized packets over - * a link with a fixed MTU. - * - * All multi-byte integers in structs are little-endian, unless stated otherwise. - * - * A FragmentProto packet consists of a number of chunks. - * Each chunk consists of: - * - the chunk header (struct {@link fragmentproto_chunk_header}) - * - the chunk payload, i.e. part of the frame specified in the header - */ - -#ifndef BADVPN_PROTOCOL_FRAGMENTPROTO_H -#define BADVPN_PROTOCOL_FRAGMENTPROTO_H - -#include <stdint.h> - -#include <misc/balign.h> -#include <misc/packed.h> - -typedef uint16_t fragmentproto_frameid; - -/** - * FragmentProto chunk header. - */ -B_START_PACKED -struct fragmentproto_chunk_header { - /** - * Identifier of the frame this chunk belongs to. - * Frames should be given ascending identifiers as they are encoded - * into chunks (except when the ID wraps to zero). - */ - fragmentproto_frameid frame_id; - - /** - * Position in the frame where this chunk starts. - */ - uint16_t chunk_start; - - /** - * Length of the chunk's payload. - */ - uint16_t chunk_len; - - /** - * Whether this is the last chunk of the frame, i.e. - * the total length of the frame is chunk_start + chunk_len. - */ - uint8_t is_last; -} B_PACKED; -B_END_PACKED - -/** - * Calculates how many chunks are needed at most for encoding one frame of the - * given maximum size with FragmentProto onto a carrier with a given MTU. - * This includes the case when the first chunk of a frame is not the first chunk - * in a FragmentProto packet. - * - * @param carrier_mtu MTU of the carrier, i.e. maximum length of FragmentProto packets. Must be >sizeof(struct fragmentproto_chunk_header). - * @param frame_mtu maximum frame size. Must be >=0. - * @return maximum number of chunks needed. Will be >0. - */ -static int fragmentproto_max_chunks_for_frame (int carrier_mtu, int frame_mtu) -{ - ASSERT(carrier_mtu > sizeof(struct fragmentproto_chunk_header)) - ASSERT(frame_mtu >= 0) - - return (bdivide_up(frame_mtu, (carrier_mtu - sizeof(struct fragmentproto_chunk_header))) + 1); -} - -#endif diff --git a/external/badvpn_dns/protocol/msgproto.bproto b/external/badvpn_dns/protocol/msgproto.bproto deleted file mode 100644 index 202931e..0000000 --- a/external/badvpn_dns/protocol/msgproto.bproto +++ /dev/null @@ -1,43 +0,0 @@ -// message for all MsgProto messages -message msg { - // message type, from msgproto.h - required uint16 type = 1; - // message payload. Is itself one of the messages below - // for "youconnect", "seed" and "confirmseed" messages, - // and empty for other messages - required data payload = 2; -}; - -// "youconnect" message payload -message msg_youconnect { - // external addresses to try; one or more msg_youconnect_addr messages - required repeated data addr = 1; - // encryption key if using UDP and encryption is enabled - optional data key = 2; - // password if using TCP - optional uint64 password = 3; -}; - -// an external address -message msg_youconnect_addr { - // scope name for this address - required data name = 1; - // address according to AddrProto - required data addr = 2; -}; - -// "seed" message payload -message msg_seed { - // identifier for the seed being send - required uint16 seed_id = 1; - // seed encryption key - required data key = 2; - // seed IV - required data iv = 3; -}; - -// "confirmseed" message payload -message msg_confirmseed { - // identifier for the seed being confirmed - required uint16 seed_id = 1; -}; diff --git a/external/badvpn_dns/protocol/msgproto.h b/external/badvpn_dns/protocol/msgproto.h deleted file mode 100644 index 286abb0..0000000 --- a/external/badvpn_dns/protocol/msgproto.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file msgproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * MsgProto is used by each pair of VPN peers as messages through the server, in order to - * establish a direct data connection. MsgProto operates on top of the SCProto message - * service, optionally secured with SSL; see {@link scproto.h} for details. - * - * MsgProto is built with BProto, the protocol and code generator for building - * custom message protocols. The BProto specification file is msgproto.bproto. - * - * It goes roughly like that: - * - * We name one peer the master and the other the slave. The master is the one with - * greater ID. - * When the peers get to know about each other, the master starts the binding procedure. - * It binds/listens to an address, and sends the slave the "youconnect" message. It - * contains a list of external addresses for that bind address and additional parameters. - * Each external address includes a string called a scope name. The slave, which receives - * the "youconnect" message, finds the first external address whose scope it recognizes, - * and attempts to establish connection to that address. If it finds an address, buf fails - * at connecting, it sends "youretry", which makes the master restart the binding procedure - * after some time. If it however does not recognize any external address, it sends - * "cannotconnect" back to the master. - * When the master receives the "cannotconnect", it tries the next bind address, as described - * above. When the master runs out of bind addresses, it sends "cannotbind" to the slave. - * When the slave receives the "cannotbind", it starts its own binding procedure, similarly - * to what is described above, with master and slave reversed. First difference is if the - * master fails to connect to a recognized address, it doesn't send "youretry", but rather - * simply restarts the whole procedure after some time. The other difference is when the - * slave runs out of bind addresses, it not only sends "cannotbind" to the master, but - * registers relaying to the master. And in this case, when the master receives the "cannotbind", - * it doesn't start the binding procedure all all over, but registers relaying to the slave. - */ - -#ifndef BADVPN_PROTOCOL_MSGPROTO_H -#define BADVPN_PROTOCOL_MSGPROTO_H - -#include <generated/bproto_msgproto.h> - -#define MSGID_YOUCONNECT 1 -#define MSGID_CANNOTCONNECT 2 -#define MSGID_CANNOTBIND 3 -#define MSGID_YOURETRY 5 -#define MSGID_SEED 6 -#define MSGID_CONFIRMSEED 7 - -#define MSG_MAX_PAYLOAD (SC_MAX_MSGLEN - msg_SIZEtype - msg_SIZEpayload(0)) - -#endif diff --git a/external/badvpn_dns/protocol/packetproto.h b/external/badvpn_dns/protocol/packetproto.h deleted file mode 100644 index 0f0982b..0000000 --- a/external/badvpn_dns/protocol/packetproto.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file packetproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for PacketProto, a protocol that allows sending of packets - * over a reliable stream connection. - * - * All multi-byte integers in structs are little-endian, unless stated otherwise. - * - * Packets are encoded into a stream by representing each packet with: - * - a 16-bit little-endian unsigned integer representing the length - * of the payload - * - that many bytes of payload - */ - -#ifndef BADVPN_PROTOCOL_PACKETPROTO_H -#define BADVPN_PROTOCOL_PACKETPROTO_H - -#include <stdint.h> -#include <limits.h> - -#include <misc/packed.h> - -/** - * PacketProto packet header. - * Wraps a single uint16_t in a packed struct for easy access. - */ -B_START_PACKED -struct packetproto_header -{ - /** - * Length of the packet payload that follows. - */ - uint16_t len; -} B_PACKED; -B_END_PACKED - -#define PACKETPROTO_ENCLEN(_len) (sizeof(struct packetproto_header) + (_len)) - -#define PACKETPROTO_MAXPAYLOAD UINT16_MAX - -#endif diff --git a/external/badvpn_dns/protocol/requestproto.h b/external/badvpn_dns/protocol/requestproto.h deleted file mode 100644 index 2ec3d0d..0000000 --- a/external/badvpn_dns/protocol/requestproto.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file requestproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_REQUESTPROTO_H -#define BADVPN_REQUESTPROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define REQUESTPROTO_TYPE_CLIENT_REQUEST 1 -#define REQUESTPROTO_TYPE_CLIENT_ABORT 2 -#define REQUESTPROTO_TYPE_SERVER_REPLY 3 -#define REQUESTPROTO_TYPE_SERVER_FINISHED 4 -#define REQUESTPROTO_TYPE_SERVER_ERROR 5 - -B_START_PACKED -struct requestproto_header { - uint32_t request_id; - uint32_t type; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/protocol/scproto.h b/external/badvpn_dns/protocol/scproto.h deleted file mode 100644 index f138e0a..0000000 --- a/external/badvpn_dns/protocol/scproto.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @file scproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for SCProto, the protocol that the clients communicate in - * with the server. - * - * All multi-byte integers in structs are little-endian, unless stated otherwise. - * - * A SCProto packet consists of: - * - a header (struct {@link sc_header}) which contains the type of the - * packet - * - the payload - * - * It goes roughly like that: - * - * When the client connects to the server, it sends a "clienthello" packet - * to the server. The packet contains the protocol version the client is using. - * When the server receives the "clienthello" packet, it checks the version. - * If it doesn't match, it disconnects the client. Otherwise the server sends - * the client a "serverhello" packet to the client. That packet contains - * the ID of the client and possibly its IPv4 address as the server sees it - * (zero if not applicable). - * - * The server than proceeds to synchronize the peers' knowledge of each other. - * It does that by sending a "newclient" messages to a client to inform it of - * another peer, and "endclient" messages to inform it that a peer is gone. - * Each client, upon receiving a "newclient" message, MUST sent a corresponding - * "acceptpeer" message, before sending any messages to the new peer. - * The server forwards messages between synchronized peers to allow them to - * communicate. A peer sends a message to another peer by sending the "outmsg" - * packet to the server, and the server delivers a message to a peer by sending - * it the "inmsg" packet. - * - * The message service is reliable; messages from one client to another are - * expected to arrive unmodified and in the same order. There is, however, - * no flow control. This means that messages can not be used for bulk transfers - * between the clients (and they are not). If the server runs out of buffer for - * messages from one client to another, it will stop forwarding messages, and - * will reset knowledge of the two clients after some delay. Similarly, if one - * of the clients runs out of buffer locally, it will send the "resetpeer" - * packet to make the server reset knowledge. - * - * The messages transport either: - * - * - If the relevant "newclient" packets do not contain the - * SCID_NEWCLIENT_FLAG_SSL flag, then plaintext MsgProto messages. - * - * - If the relevant "newclient" packets do contain the SCID_NEWCLIENT_FLAG_SSL - * flag, then SSL, broken down into packets, PacketProto inside SSL, and finally - * MsgProto inside PacketProto. The master peer (one with higher ID) acts as an - * SSL server, and the other acts as an SSL client. The peers must identify with - * the same certificate they used when connecting to the server, and each peer - * must byte-compare the other's certificate agains the one provided to it by - * by the server in the relevent "newclient" message. - */ - -#ifndef BADVPN_PROTOCOL_SCPROTO_H -#define BADVPN_PROTOCOL_SCPROTO_H - -#include <stdint.h> - -#include <misc/packed.h> - -#define SC_VERSION 29 -#define SC_OLDVERSION_NOSSL 27 -#define SC_OLDVERSION_BROKENCERT 26 - -#define SC_KEEPALIVE_INTERVAL 10000 - -/** - * SCProto packet header. - * Follows up to SC_MAX_PAYLOAD bytes of payload. - */ -B_START_PACKED -struct sc_header { - /** - * Message type. - */ - uint8_t type; -} B_PACKED; -B_END_PACKED - -#define SC_MAX_PAYLOAD 2000 -#define SC_MAX_ENC (sizeof(struct sc_header) + SC_MAX_PAYLOAD) - -typedef uint16_t peerid_t; - -#define SCID_KEEPALIVE 0 -#define SCID_CLIENTHELLO 1 -#define SCID_SERVERHELLO 2 -#define SCID_NEWCLIENT 3 -#define SCID_ENDCLIENT 4 -#define SCID_OUTMSG 5 -#define SCID_INMSG 6 -#define SCID_RESETPEER 7 -#define SCID_ACCEPTPEER 8 - -/** - * "clienthello" client packet payload. - * Packet type is SCID_CLIENTHELLO. - */ -B_START_PACKED -struct sc_client_hello { - /** - * Protocol version the client is using. - */ - uint16_t version; -} B_PACKED; -B_END_PACKED - -/** - * "serverhello" server packet payload. - * Packet type is SCID_SERVERHELLO. - */ -B_START_PACKED -struct sc_server_hello { - /** - * Flags. Not used yet. - */ - uint16_t flags; - - /** - * Peer ID of the client. - */ - peerid_t id; - - /** - * IPv4 address of the client as seen by the server - * (network byte order). Zero if not applicable. - */ - uint32_t clientAddr; -} B_PACKED; -B_END_PACKED - -/** - * "newclient" server packet payload. - * Packet type is SCID_NEWCLIENT. - * If the server is using TLS, follows up to SCID_NEWCLIENT_MAX_CERT_LEN - * bytes of the new client's certificate (encoded in DER). - */ -B_START_PACKED -struct sc_server_newclient { - /** - * ID of the new peer. - */ - peerid_t id; - - /** - * Flags. Possible flags: - * - SCID_NEWCLIENT_FLAG_RELAY_SERVER - * You can relay frames to other peers through this peer. - * - SCID_NEWCLIENT_FLAG_RELAY_CLIENT - * You must allow this peer to relay frames to other peers through you. - * - SCID_NEWCLIENT_FLAG_SSL - * SSL must be used to talk to this peer through messages. - */ - uint16_t flags; -} B_PACKED; -B_END_PACKED - -#define SCID_NEWCLIENT_FLAG_RELAY_SERVER 1 -#define SCID_NEWCLIENT_FLAG_RELAY_CLIENT 2 -#define SCID_NEWCLIENT_FLAG_SSL 4 - -#define SCID_NEWCLIENT_MAX_CERT_LEN (SC_MAX_PAYLOAD - sizeof(struct sc_server_newclient)) - -/** - * "endclient" server packet payload. - * Packet type is SCID_ENDCLIENT. - */ -B_START_PACKED -struct sc_server_endclient { - /** - * ID of the removed peer. - */ - peerid_t id; -} B_PACKED; -B_END_PACKED - -/** - * "outmsg" client packet header. - * Packet type is SCID_OUTMSG. - * Follows up to SC_MAX_MSGLEN bytes of message payload. - */ -B_START_PACKED -struct sc_client_outmsg { - /** - * ID of the destionation peer. - */ - peerid_t clientid; -} B_PACKED; -B_END_PACKED - -/** - * "inmsg" server packet payload. - * Packet type is SCID_INMSG. - * Follows up to SC_MAX_MSGLEN bytes of message payload. - */ -B_START_PACKED -struct sc_server_inmsg { - /** - * ID of the source peer. - */ - peerid_t clientid; -} B_PACKED; -B_END_PACKED - -#define _SC_MAX_OUTMSGLEN (SC_MAX_PAYLOAD - sizeof(struct sc_client_outmsg)) -#define _SC_MAX_INMSGLEN (SC_MAX_PAYLOAD - sizeof(struct sc_server_inmsg)) - -#define SC_MAX_MSGLEN (_SC_MAX_OUTMSGLEN < _SC_MAX_INMSGLEN ? _SC_MAX_OUTMSGLEN : _SC_MAX_INMSGLEN) - -/** - * "resetpeer" client packet header. - * Packet type is SCID_RESETPEER. - */ -B_START_PACKED -struct sc_client_resetpeer { - /** - * ID of the peer to reset. - */ - peerid_t clientid; -} B_PACKED; -B_END_PACKED - -/** - * "acceptpeer" client packet payload. - * Packet type is SCID_ACCEPTPEER. - */ -B_START_PACKED -struct sc_client_acceptpeer { - /** - * ID of the peer to accept. - */ - peerid_t clientid; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/external/badvpn_dns/protocol/spproto.h b/external/badvpn_dns/protocol/spproto.h deleted file mode 100644 index 4b5bf5d..0000000 --- a/external/badvpn_dns/protocol/spproto.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file spproto.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Protocol for securing datagram communication. - * - * Security features implemented: - * - Encryption. Encrypts packets with a block cipher. - * Protects against a third party from seeing the data - * being transmitted. - * - Hashes. Adds a hash of the packet into the packet. - * Combined with encryption, protects against tampering - * with packets and crafting new packets. - * - One-time passwords. Adds a password to each packet - * for the receiver to recognize. Protects agains replaying - * packets and crafting new packets. - * - * A SPProto plaintext packet contains the following, in order: - * - if OTPs are used, a struct {@link spproto_otpdata} which contains - * the seed ID and the OTP, - * - if hashes are used, the hash, - * - payload data. - * - * If encryption is used: - * - the plaintext is padded by appending a 0x01 byte and as many 0x00 - * bytes as needed to align to block size, - * - the padded plaintext is encrypted, and - * - the initialization vector (IV) is prepended. - */ - -#ifndef BADVPN_PROTOCOL_SPPROTO_H -#define BADVPN_PROTOCOL_SPPROTO_H - -#include <stdint.h> -#include <limits.h> - -#include <misc/debug.h> -#include <misc/balign.h> -#include <misc/packed.h> -#include <security/BHash.h> -#include <security/BEncryption.h> -#include <security/OTPCalculator.h> - -#define SPPROTO_HASH_MODE_NONE 0 -#define SPPROTO_ENCRYPTION_MODE_NONE 0 -#define SPPROTO_OTP_MODE_NONE 0 - -/** - * Stores security parameters for SPProto. - */ -struct spproto_security_params { - /** - * Hash mode. - * Either SPPROTO_HASH_MODE_NONE for no hashes, or a valid bhash - * hash mode. - */ - int hash_mode; - - /** - * Encryption mode. - * Either SPPROTO_ENCRYPTION_MODE_NONE for no encryption, or a valid - * {@link BEncryption} cipher. - */ - int encryption_mode; - - /** - * One-time password (OTP) mode. - * Either SPPROTO_OTP_MODE_NONE for no OTPs, or a valid - * {@link BEncryption} cipher. - */ - int otp_mode; - - /** - * If OTPs are used (otp_mode != SPPROTO_OTP_MODE_NONE), number of - * OTPs generated from a single seed. - */ - int otp_num; -}; - -#define SPPROTO_HAVE_HASH(_params) ((_params).hash_mode != SPPROTO_HASH_MODE_NONE) -#define SPPROTO_HASH_SIZE(_params) ( \ - SPPROTO_HAVE_HASH(_params) ? \ - BHash_size((_params).hash_mode) : \ - 0 \ -) - -#define SPPROTO_HAVE_ENCRYPTION(_params) ((_params).encryption_mode != SPPROTO_ENCRYPTION_MODE_NONE) - -#define SPPROTO_HAVE_OTP(_params) ((_params).otp_mode != SPPROTO_OTP_MODE_NONE) - -B_START_PACKED -struct spproto_otpdata { - uint16_t seed_id; - otp_t otp; -} B_PACKED; -B_END_PACKED - -#define SPPROTO_HEADER_OTPDATA_OFF(_params) 0 -#define SPPROTO_HEADER_OTPDATA_LEN(_params) (SPPROTO_HAVE_OTP(_params) ? sizeof(struct spproto_otpdata) : 0) -#define SPPROTO_HEADER_HASH_OFF(_params) (SPPROTO_HEADER_OTPDATA_OFF(_params) + SPPROTO_HEADER_OTPDATA_LEN(_params)) -#define SPPROTO_HEADER_HASH_LEN(_params) SPPROTO_HASH_SIZE(_params) -#define SPPROTO_HEADER_LEN(_params) (SPPROTO_HEADER_HASH_OFF(_params) + SPPROTO_HEADER_HASH_LEN(_params)) - -/** - * Asserts that the given SPProto security parameters are valid. - * - * @param params security parameters - */ -static void spproto_assert_security_params (struct spproto_security_params params) -{ - ASSERT(params.hash_mode == SPPROTO_HASH_MODE_NONE || BHash_type_valid(params.hash_mode)) - ASSERT(params.encryption_mode == SPPROTO_ENCRYPTION_MODE_NONE || BEncryption_cipher_valid(params.encryption_mode)) - ASSERT(params.otp_mode == SPPROTO_OTP_MODE_NONE || BEncryption_cipher_valid(params.otp_mode)) - ASSERT(params.otp_mode == SPPROTO_OTP_MODE_NONE || params.otp_num > 0) -} - -/** - * Calculates the maximum payload size for SPProto given the - * security parameters and the maximum encoded packet size. - * - * @param params security parameters - * @param carrier_mtu maximum encoded packet size. Must be >=0. - * @return maximum payload size. Negative means is is impossible - * to encode anything. - */ -static int spproto_payload_mtu_for_carrier_mtu (struct spproto_security_params params, int carrier_mtu) -{ - spproto_assert_security_params(params); - ASSERT(carrier_mtu >= 0) - - if (params.encryption_mode == SPPROTO_ENCRYPTION_MODE_NONE) { - return (carrier_mtu - SPPROTO_HEADER_LEN(params)); - } else { - int block_size = BEncryption_cipher_block_size(params.encryption_mode); - return (balign_down(carrier_mtu, block_size) - block_size - SPPROTO_HEADER_LEN(params) - 1); - } -} - -/** - * Calculates the maximum encoded packet size for SPProto given the - * security parameters and the maximum payload size. - * - * @param params security parameters - * @param payload_mtu maximum payload size. Must be >=0. - * @return maximum encoded packet size, -1 if payload_mtu is too large - */ -static int spproto_carrier_mtu_for_payload_mtu (struct spproto_security_params params, int payload_mtu) -{ - spproto_assert_security_params(params); - ASSERT(payload_mtu >= 0) - - if (params.encryption_mode == SPPROTO_ENCRYPTION_MODE_NONE) { - if (payload_mtu > INT_MAX - SPPROTO_HEADER_LEN(params)) { - return -1; - } - - return (SPPROTO_HEADER_LEN(params) + payload_mtu); - } else { - int block_size = BEncryption_cipher_block_size(params.encryption_mode); - - if (payload_mtu > INT_MAX - (block_size + SPPROTO_HEADER_LEN(params) + block_size)) { - return -1; - } - - return (block_size + balign_up((SPPROTO_HEADER_LEN(params) + payload_mtu + 1), block_size)); - } -} - -#endif diff --git a/external/badvpn_dns/protocol/udpgw_proto.h b/external/badvpn_dns/protocol/udpgw_proto.h deleted file mode 100644 index 606fe6c..0000000 --- a/external/badvpn_dns/protocol/udpgw_proto.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_PROTOCOL_UDPGW_PROTO_H -#define BADVPN_PROTOCOL_UDPGW_PROTO_H - -#include <stdint.h> - -#include <misc/bsize.h> -#include <misc/packed.h> - -#define UDPGW_CLIENT_FLAG_KEEPALIVE (1 << 0) -#define UDPGW_CLIENT_FLAG_REBIND (1 << 1) -#define UDPGW_CLIENT_FLAG_DNS (1 << 2) -#define UDPGW_CLIENT_FLAG_IPV6 (1 << 3) - -B_START_PACKED -struct udpgw_header { - uint8_t flags; - uint16_t conid; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct udpgw_addr_ipv4 { - uint32_t addr_ip; - uint16_t addr_port; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct udpgw_addr_ipv6 { - uint8_t addr_ip[16]; - uint16_t addr_port; -} B_PACKED; -B_END_PACKED - -static int udpgw_compute_mtu (int dgram_mtu) -{ - bsize_t bs = bsize_add( - bsize_fromsize(sizeof(struct udpgw_header)), - bsize_add( - bsize_max( - bsize_fromsize(sizeof(struct udpgw_addr_ipv4)), - bsize_fromsize(sizeof(struct udpgw_addr_ipv6)) - ), - bsize_fromint(dgram_mtu) - ) - ); - - int s; - if (!bsize_toint(bs, &s)) { - return -1; - } - - return s; -} - -#endif diff --git a/external/badvpn_dns/random/BRandom2.c b/external/badvpn_dns/random/BRandom2.c deleted file mode 100644 index a0761de..0000000 --- a/external/badvpn_dns/random/BRandom2.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file BRandom2.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "BRandom2.h" - -static int do_init (BRandom2 *o) -{ - if (o->initialized) { - return 1; - } - - o->urandom_fd = open("/dev/urandom", O_RDONLY); - if (o->urandom_fd < 0) { - return 0; - } - - o->initialized = 1; - - return 1; -} - -int BRandom2_Init (BRandom2 *o, int flags) -{ - ASSERT((flags & ~(BRANDOM2_INIT_LAZY)) == 0) - - o->initialized = 0; - - if (!(flags & BRANDOM2_INIT_LAZY) && !do_init(o)) { - return 0; - } - - DebugObject_Init(&o->d_obj); - return 1; -} - -void BRandom2_Free (BRandom2 *o) -{ - DebugObject_Free(&o->d_obj); - - if (o->initialized) { - close(o->urandom_fd); - } -} - -int BRandom2_GenBytes (BRandom2 *o, void *out, size_t len) -{ - DebugObject_Access(&o->d_obj); - - if (!do_init(o)) { - return 0; - } - - ssize_t res = read(o->urandom_fd, out, len); - if (res < 0 || res != len) { - return 0; - } - - return 1; -} diff --git a/external/badvpn_dns/random/BRandom2.h b/external/badvpn_dns/random/BRandom2.h deleted file mode 100644 index 6851b84..0000000 --- a/external/badvpn_dns/random/BRandom2.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file BRandom2.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_RANDOM2_H -#define BADVPN_RANDOM2_H - -#include <stddef.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> - -#define BRANDOM2_INIT_LAZY (1 << 0) - -typedef struct { - int initialized; - int urandom_fd; - DebugObject d_obj; -} BRandom2; - -int BRandom2_Init (BRandom2 *o, int flags) WARN_UNUSED; -void BRandom2_Free (BRandom2 *o); -int BRandom2_GenBytes (BRandom2 *o, void *out, size_t len) WARN_UNUSED; - -#endif diff --git a/external/badvpn_dns/random/CMakeLists.txt b/external/badvpn_dns/random/CMakeLists.txt deleted file mode 100644 index 76a4821..0000000 --- a/external/badvpn_dns/random/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(badvpn_random "base" "" BRandom2.c) diff --git a/external/badvpn_dns/scripts/cmake b/external/badvpn_dns/scripts/cmake deleted file mode 100755 index 51af777..0000000 --- a/external/badvpn_dns/scripts/cmake +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -export ROOT="<root>" -export MINGW="/home/<user>/mingw/cross_win32" - -export PATH="$MINGW/bin:$PATH" - -exec /usr/bin/cmake -DCMAKE_TOOLCHAIN_FILE="$ROOT/toolchain.cmake" "$@" diff --git a/external/badvpn_dns/scripts/copy_nss b/external/badvpn_dns/scripts/copy_nss deleted file mode 100755 index 9b52112..0000000 --- a/external/badvpn_dns/scripts/copy_nss +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -NSSDIST="$1" -DEST="$2" - -if [ -z "${NSSDIST}" ] || [ -z "${DEST}" ]; then - echo "Copies a Windows build of NSS such that it can be found by the BadVPN build system" - echo "Usage: $0 <nss dist dir> <dest>" - exit 1 -fi - -NSSOBJ="${NSSDIST}/WINNT5.1_OPT.OBJ" - -set -e - -mkdir -p "${DEST}"/include -cp -r "${NSSOBJ}/include"/* "${DEST}"/include/ -cp -r "${NSSDIST}/public/nss"/* "${DEST}"/include/ -mkdir -p "${DEST}"/lib -cp "${NSSOBJ}/lib"/{libnspr4,libplc4,libplds4,ssl3,smime3,nss3}.lib "${DEST}"/lib/ -mkdir -p "${DEST}"/bin -cp "${NSSOBJ}/lib"/*.dll "${DEST}"/bin/ -cp "${NSSOBJ}/bin"/*.exe "${DEST}"/bin/ diff --git a/external/badvpn_dns/scripts/toolchain.cmake b/external/badvpn_dns/scripts/toolchain.cmake deleted file mode 100644 index 5f4a90a..0000000 --- a/external/badvpn_dns/scripts/toolchain.cmake +++ /dev/null @@ -1,6 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Windows) -SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) -SET(CMAKE_FIND_ROOT_PATH $ENV{ROOT}) -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/external/badvpn_dns/security/BEncryption.c b/external/badvpn_dns/security/BEncryption.c deleted file mode 100644 index f0f476c..0000000 --- a/external/badvpn_dns/security/BEncryption.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @file BEncryption.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <base/BLog.h> - -#include <security/BEncryption.h> - -#include <generated/blog_channel_BEncryption.h> - -int BEncryption_cipher_valid (int cipher) -{ - switch (cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - case BENCRYPTION_CIPHER_AES: - return 1; - default: - return 0; - } -} - -int BEncryption_cipher_block_size (int cipher) -{ - switch (cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - return BENCRYPTION_CIPHER_BLOWFISH_BLOCK_SIZE; - case BENCRYPTION_CIPHER_AES: - return BENCRYPTION_CIPHER_AES_BLOCK_SIZE; - default: - ASSERT(0) - return 0; - } -} - -int BEncryption_cipher_key_size (int cipher) -{ - switch (cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - return BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE; - case BENCRYPTION_CIPHER_AES: - return BENCRYPTION_CIPHER_AES_KEY_SIZE; - default: - ASSERT(0) - return 0; - } -} - -void BEncryption_Init (BEncryption *enc, int mode, int cipher, uint8_t *key) -{ - ASSERT(!(mode&~(BENCRYPTION_MODE_ENCRYPT|BENCRYPTION_MODE_DECRYPT))) - ASSERT((mode&BENCRYPTION_MODE_ENCRYPT) || (mode&BENCRYPTION_MODE_DECRYPT)) - - enc->mode = mode; - enc->cipher = cipher; - - #ifdef BADVPN_USE_CRYPTODEV - - switch (enc->cipher) { - case BENCRYPTION_CIPHER_AES: - enc->cryptodev.cipher = CRYPTO_AES_CBC; - break; - default: - goto fail1; - } - - if ((enc->cryptodev.fd = open("/dev/crypto", O_RDWR, 0)) < 0) { - BLog(BLOG_ERROR, "failed to open /dev/crypto"); - goto fail1; - } - - if (ioctl(enc->cryptodev.fd, CRIOGET, &enc->cryptodev.cfd)) { - BLog(BLOG_ERROR, "failed ioctl(CRIOGET)"); - goto fail2; - } - - struct session_op sess; - memset(&sess, 0, sizeof(sess)); - sess.cipher = enc->cryptodev.cipher; - sess.keylen = BEncryption_cipher_key_size(enc->cipher); - sess.key = key; - if (ioctl(enc->cryptodev.cfd, CIOCGSESSION, &sess)) { - BLog(BLOG_ERROR, "failed ioctl(CIOCGSESSION)"); - goto fail3; - } - - enc->cryptodev.ses = sess.ses; - enc->use_cryptodev = 1; - - goto success; - -fail3: - ASSERT_FORCE(close(enc->cryptodev.cfd) == 0) -fail2: - ASSERT_FORCE(close(enc->cryptodev.fd) == 0) -fail1: - - enc->use_cryptodev = 0; - - #endif - - int res; - - switch (enc->cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - BF_set_key(&enc->blowfish, BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE, key); - break; - case BENCRYPTION_CIPHER_AES: - if (enc->mode&BENCRYPTION_MODE_ENCRYPT) { - res = AES_set_encrypt_key(key, 128, &enc->aes.encrypt); - ASSERT_EXECUTE(res >= 0) - } - if (enc->mode&BENCRYPTION_MODE_DECRYPT) { - res = AES_set_decrypt_key(key, 128, &enc->aes.decrypt); - ASSERT_EXECUTE(res >= 0) - } - break; - default: - ASSERT(0) - ; - } - - #ifdef BADVPN_USE_CRYPTODEV -success: - #endif - // init debug object - DebugObject_Init(&enc->d_obj); -} - -void BEncryption_Free (BEncryption *enc) -{ - // free debug object - DebugObject_Free(&enc->d_obj); - - #ifdef BADVPN_USE_CRYPTODEV - - if (enc->use_cryptodev) { - ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCFSESSION, &enc->cryptodev.ses) == 0) - ASSERT_FORCE(close(enc->cryptodev.cfd) == 0) - ASSERT_FORCE(close(enc->cryptodev.fd) == 0) - } - - #endif -} - -void BEncryption_Encrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv) -{ - ASSERT(enc->mode&BENCRYPTION_MODE_ENCRYPT) - ASSERT(len >= 0) - ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0) - - #ifdef BADVPN_USE_CRYPTODEV - - if (enc->use_cryptodev) { - struct crypt_op cryp; - memset(&cryp, 0, sizeof(cryp)); - cryp.ses = enc->cryptodev.ses; - cryp.len = len; - cryp.src = in; - cryp.dst = out; - cryp.iv = iv; - cryp.op = COP_ENCRYPT; - ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0) - - return; - } - - #endif - - switch (enc->cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_ENCRYPT); - break; - case BENCRYPTION_CIPHER_AES: - AES_cbc_encrypt(in, out, len, &enc->aes.encrypt, iv, AES_ENCRYPT); - break; - default: - ASSERT(0); - } -} - -void BEncryption_Decrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv) -{ - ASSERT(enc->mode&BENCRYPTION_MODE_DECRYPT) - ASSERT(len >= 0) - ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0) - - #ifdef BADVPN_USE_CRYPTODEV - - if (enc->use_cryptodev) { - struct crypt_op cryp; - memset(&cryp, 0, sizeof(cryp)); - cryp.ses = enc->cryptodev.ses; - cryp.len = len; - cryp.src = in; - cryp.dst = out; - cryp.iv = iv; - cryp.op = COP_DECRYPT; - ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0) - - return; - } - - #endif - - switch (enc->cipher) { - case BENCRYPTION_CIPHER_BLOWFISH: - BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_DECRYPT); - break; - case BENCRYPTION_CIPHER_AES: - AES_cbc_encrypt(in, out, len, &enc->aes.decrypt, iv, AES_DECRYPT); - break; - default: - ASSERT(0); - } -} diff --git a/external/badvpn_dns/security/BEncryption.h b/external/badvpn_dns/security/BEncryption.h deleted file mode 100644 index 60a4fdc..0000000 --- a/external/badvpn_dns/security/BEncryption.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @file BEncryption.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Block cipher encryption abstraction. - */ - -#ifndef BADVPN_SECURITY_BENCRYPTION_H -#define BADVPN_SECURITY_BENCRYPTION_H - -#include <stdint.h> -#include <string.h> - -#ifdef BADVPN_USE_CRYPTODEV -#include <crypto/cryptodev.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#endif - -#include <openssl/blowfish.h> -#include <openssl/aes.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> - -#define BENCRYPTION_MODE_ENCRYPT 1 -#define BENCRYPTION_MODE_DECRYPT 2 - -#define BENCRYPTION_MAX_BLOCK_SIZE 16 -#define BENCRYPTION_MAX_KEY_SIZE 16 - -#define BENCRYPTION_CIPHER_BLOWFISH 1 -#define BENCRYPTION_CIPHER_BLOWFISH_BLOCK_SIZE 8 -#define BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE 16 - -#define BENCRYPTION_CIPHER_AES 2 -#define BENCRYPTION_CIPHER_AES_BLOCK_SIZE 16 -#define BENCRYPTION_CIPHER_AES_KEY_SIZE 16 - -// NOTE: update the maximums above when adding a cipher! - -/** - * Block cipher encryption abstraction. - */ -typedef struct { - DebugObject d_obj; - int mode; - int cipher; - #ifdef BADVPN_USE_CRYPTODEV - int use_cryptodev; - #endif - union { - BF_KEY blowfish; - struct { - AES_KEY encrypt; - AES_KEY decrypt; - } aes; - #ifdef BADVPN_USE_CRYPTODEV - struct { - int fd; - int cfd; - int cipher; - uint32_t ses; - } cryptodev; - #endif - }; -} BEncryption; - -/** - * Checks if the given cipher number is valid. - * - * @param cipher cipher number - * @return 1 if valid, 0 if not - */ -int BEncryption_cipher_valid (int cipher); - -/** - * Returns the block size of a cipher. - * - * @param cipher cipher number. Must be valid. - * @return block size in bytes - */ -int BEncryption_cipher_block_size (int cipher); - -/** - * Returns the key size of a cipher. - * - * @param cipher cipher number. Must be valid. - * @return key size in bytes - */ -int BEncryption_cipher_key_size (int cipher); - -/** - * Initializes the object. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if this object - * will be used from a non-main thread. - * - * @param enc the object - * @param mode whether encryption or decryption is to be done, or both. - * Must be a bitwise-OR of at least one of BENCRYPTION_MODE_ENCRYPT - * and BENCRYPTION_MODE_DECRYPT. - * @param cipher cipher number. Must be valid. - * @param key encryption key - */ -void BEncryption_Init (BEncryption *enc, int mode, int cipher, uint8_t *key); - -/** - * Frees the object. - * - * @param enc the object - */ -void BEncryption_Free (BEncryption *enc); - -/** - * Encrypts data. - * The object must have been initialized with mode including - * BENCRYPTION_MODE_ENCRYPT. - * - * @param enc the object - * @param in data to encrypt - * @param out ciphertext output - * @param len number of bytes to encrypt. Must be >=0 and a multiple of - * block size. - * @param iv initialization vector. Updated such that continuing a previous encryption - * starting with the updated IV is equivalent to performing just one encryption. - */ -void BEncryption_Encrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv); - -/** - * Decrypts data. - * The object must have been initialized with mode including - * BENCRYPTION_MODE_DECRYPT. - * - * @param enc the object - * @param in data to decrypt - * @param out plaintext output - * @param len number of bytes to decrypt. Must be >=0 and a multiple of - * block size. - * @param iv initialization vector. Updated such that continuing a previous decryption - * starting with the updated IV is equivalent to performing just one decryption. - */ -void BEncryption_Decrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv); - -#endif diff --git a/external/badvpn_dns/security/BHash.c b/external/badvpn_dns/security/BHash.c deleted file mode 100644 index fec2616..0000000 --- a/external/badvpn_dns/security/BHash.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file BHash.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <security/BHash.h> - -int BHash_type_valid (int type) -{ - switch (type) { - case BHASH_TYPE_MD5: - case BHASH_TYPE_SHA1: - return 1; - default: - return 0; - } -} - -int BHash_size (int type) -{ - switch (type) { - case BHASH_TYPE_MD5: - return BHASH_TYPE_MD5_SIZE; - case BHASH_TYPE_SHA1: - return BHASH_TYPE_SHA1_SIZE; - default: - ASSERT(0) - return 0; - } -} - -void BHash_calculate (int type, uint8_t *data, int data_len, uint8_t *out) -{ - switch (type) { - case BHASH_TYPE_MD5: - MD5(data, data_len, out); - break; - case BHASH_TYPE_SHA1: - SHA1(data, data_len, out); - break; - default: - ASSERT(0) - ; - } -} diff --git a/external/badvpn_dns/security/BHash.h b/external/badvpn_dns/security/BHash.h deleted file mode 100644 index 6fb6f9a..0000000 --- a/external/badvpn_dns/security/BHash.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file BHash.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Cryptographic hash funtions abstraction. - */ - -#ifndef BADVPN_SECURITY_BHASH_H -#define BADVPN_SECURITY_BHASH_H - -#include <stdint.h> - -#include <openssl/md5.h> -#include <openssl/sha.h> - -#include <misc/debug.h> - -#define BHASH_TYPE_MD5 1 -#define BHASH_TYPE_MD5_SIZE 16 - -#define BHASH_TYPE_SHA1 2 -#define BHASH_TYPE_SHA1_SIZE 20 - -#define BHASH_MAX_SIZE 20 - -/** - * Checks if the given hash type number is valid. - * - * @param type hash type number - * @return 1 if valid, 0 if not - */ -int BHash_type_valid (int type); - -/** - * Returns the size of a hash. - * - * @param cipher hash type number. Must be valid. - * @return hash size in bytes - */ -int BHash_size (int type); - -/** - * Calculates a hash. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if this is - * being called from a non-main thread. - * - * @param type hash type number. Must be valid. - * @param data data to calculate the hash of - * @param data_len length of data - * @param out the hash will be written here. Must not overlap with data. - */ -void BHash_calculate (int type, uint8_t *data, int data_len, uint8_t *out); - -#endif diff --git a/external/badvpn_dns/security/BRandom.c b/external/badvpn_dns/security/BRandom.c deleted file mode 100644 index ea9f276..0000000 --- a/external/badvpn_dns/security/BRandom.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file BRandom.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <openssl/rand.h> - -#include <misc/debug.h> - -#include <security/BRandom.h> - -void BRandom_randomize (uint8_t *buf, int len) -{ - ASSERT(len >= 0) - - DEBUG_ZERO_MEMORY(buf, len) - ASSERT_FORCE(RAND_bytes(buf, len) == 1) -} diff --git a/external/badvpn_dns/security/BRandom.h b/external/badvpn_dns/security/BRandom.h deleted file mode 100644 index 3529b82..0000000 --- a/external/badvpn_dns/security/BRandom.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file BRandom.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Random data generation function. - */ - -#ifndef BADVPN_SECURITY_BRANDOM_H -#define BADVPN_SECURITY_BRANDOM_H - -#include <stdint.h> - -/** - * Generates random data. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if this is - * being called from a non-main thread. - * - * @param buf buffer to write data into - * @param len number of bytes to generate. Must be >=0. - */ -void BRandom_randomize (uint8_t *buf, int len); - -#endif diff --git a/external/badvpn_dns/security/BSecurity.c b/external/badvpn_dns/security/BSecurity.c deleted file mode 100644 index f3fb7c8..0000000 --- a/external/badvpn_dns/security/BSecurity.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file BSecurity.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#ifdef BADVPN_THREADWORK_USE_PTHREAD - #include <pthread.h> -#endif - -#include <openssl/crypto.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -#include <security/BSecurity.h> - -int bsecurity_initialized = 0; - -#ifdef BADVPN_THREADWORK_USE_PTHREAD -pthread_mutex_t *bsecurity_locks; -int bsecurity_num_locks; -#endif - -#ifdef BADVPN_THREADWORK_USE_PTHREAD - -static unsigned long id_callback (void) -{ - ASSERT(bsecurity_initialized) - - return (unsigned long)pthread_self(); -} - -static void locking_callback (int mode, int type, const char *file, int line) -{ - ASSERT(bsecurity_initialized) - ASSERT(type >= 0) - ASSERT(type < bsecurity_num_locks) - - if ((mode & CRYPTO_LOCK)) { - ASSERT_FORCE(pthread_mutex_lock(&bsecurity_locks[type]) == 0) - } else { - ASSERT_FORCE(pthread_mutex_unlock(&bsecurity_locks[type]) == 0) - } -} - -#endif - -int BSecurity_GlobalInitThreadSafe (void) -{ - ASSERT(!bsecurity_initialized) - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - - // get number of locks - int num_locks = CRYPTO_num_locks(); - ASSERT_FORCE(num_locks >= 0) - - // alloc locks array - if (!(bsecurity_locks = BAllocArray(num_locks, sizeof(bsecurity_locks[0])))) { - goto fail0; - } - - // init locks - bsecurity_num_locks = 0; - for (int i = 0; i < num_locks; i++) { - if (pthread_mutex_init(&bsecurity_locks[i], NULL) != 0) { - goto fail1; - } - bsecurity_num_locks++; - } - - #endif - - bsecurity_initialized = 1; - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - CRYPTO_set_id_callback(id_callback); - CRYPTO_set_locking_callback(locking_callback); - #endif - - return 1; - - #ifdef BADVPN_THREADWORK_USE_PTHREAD -fail1: - while (bsecurity_num_locks > 0) { - ASSERT_FORCE(pthread_mutex_destroy(&bsecurity_locks[bsecurity_num_locks - 1]) == 0) - bsecurity_num_locks--; - } - BFree(bsecurity_locks); -fail0: - return 0; - #endif -} - -void BSecurity_GlobalFreeThreadSafe (void) -{ - ASSERT(bsecurity_initialized) - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - - // remove callbacks - CRYPTO_set_locking_callback(NULL); - CRYPTO_set_id_callback(NULL); - - // free locks - while (bsecurity_num_locks > 0) { - ASSERT_FORCE(pthread_mutex_destroy(&bsecurity_locks[bsecurity_num_locks - 1]) == 0) - bsecurity_num_locks--; - } - - // free locks array - BFree(bsecurity_locks); - - #endif - - bsecurity_initialized = 0; -} - -void BSecurity_GlobalAssertThreadSafe (int thread_safe) -{ - ASSERT(thread_safe == 0 || thread_safe == 1) - ASSERT(!(thread_safe) || bsecurity_initialized) -} diff --git a/external/badvpn_dns/security/BSecurity.h b/external/badvpn_dns/security/BSecurity.h deleted file mode 100644 index c429e4e..0000000 --- a/external/badvpn_dns/security/BSecurity.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file BSecurity.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Initialization of OpenSSL for security functions. - */ - -#ifndef BADVPN_SECURITY_BSECURITY_H -#define BADVPN_SECURITY_BSECURITY_H - -/** - * Initializes thread safety for security functions. - * Thread safety must not be initialized. - * - * @return 1 on success, 0 on failure - */ -int BSecurity_GlobalInitThreadSafe (void); - -/** - * Deinitializes thread safety for security functions. - * Thread safety must be initialized. - */ -void BSecurity_GlobalFreeThreadSafe (void); - -/** - * Asserts that {@link BSecurity_GlobalInitThreadSafe} was done, - * if thread_safe=1. - * - * @param thread_safe whether thread safety is to be asserted. - * Must be 0 or 1. - */ -void BSecurity_GlobalAssertThreadSafe (int thread_safe); - -#endif diff --git a/external/badvpn_dns/security/CMakeLists.txt b/external/badvpn_dns/security/CMakeLists.txt deleted file mode 100644 index fe29a51..0000000 --- a/external/badvpn_dns/security/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(SECURITY_SOURCES - BSecurity.c - BEncryption.c - BHash.c - BRandom.c - OTPCalculator.c - OTPChecker.c - OTPGenerator.c -) -badvpn_add_library(security "system;threadwork" "${LIBCRYPTO_LIBRARIES}" "${SECURITY_SOURCES}") diff --git a/external/badvpn_dns/security/OTPCalculator.c b/external/badvpn_dns/security/OTPCalculator.c deleted file mode 100644 index 069dbe6..0000000 --- a/external/badvpn_dns/security/OTPCalculator.c +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file OTPCalculator.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <limits.h> - -#include <misc/balloc.h> - -#include <security/OTPCalculator.h> - -int OTPCalculator_Init (OTPCalculator *calc, int num_otps, int cipher) -{ - ASSERT(num_otps >= 0) - ASSERT(BEncryption_cipher_valid(cipher)) - - // init arguments - calc->num_otps = num_otps; - calc->cipher = cipher; - - // remember block size - calc->block_size = BEncryption_cipher_block_size(calc->cipher); - - // calculate number of blocks - if (calc->num_otps > SIZE_MAX / sizeof(otp_t)) { - goto fail0; - } - calc->num_blocks = bdivide_up(calc->num_otps * sizeof(otp_t), calc->block_size); - - // allocate buffer - if (!(calc->data = (otp_t *)BAllocArray(calc->num_blocks, calc->block_size))) { - goto fail0; - } - - // init debug object - DebugObject_Init(&calc->d_obj); - - return 1; - -fail0: - return 0; -} - -void OTPCalculator_Free (OTPCalculator *calc) -{ - // free debug object - DebugObject_Free(&calc->d_obj); - - // free buffer - BFree(calc->data); -} - -otp_t * OTPCalculator_Generate (OTPCalculator *calc, uint8_t *key, uint8_t *iv, int shuffle) -{ - ASSERT(shuffle == 0 || shuffle == 1) - - // copy IV so it can be updated - uint8_t iv_work[BENCRYPTION_MAX_BLOCK_SIZE]; - memcpy(iv_work, iv, calc->block_size); - - // create zero block - uint8_t zero[BENCRYPTION_MAX_BLOCK_SIZE]; - memset(zero, 0, calc->block_size); - - // init encryptor - BEncryption encryptor; - BEncryption_Init(&encryptor, BENCRYPTION_MODE_ENCRYPT, calc->cipher, key); - - // encrypt zero blocks - for (size_t i = 0; i < calc->num_blocks; i++) { - BEncryption_Encrypt(&encryptor, zero, (uint8_t *)calc->data + i * calc->block_size, calc->block_size, iv_work); - } - - // free encryptor - BEncryption_Free(&encryptor); - - // shuffle if requested - if (shuffle) { - int i = 0; - while (i < calc->num_otps) { - uint16_t ints[256]; - BRandom_randomize((uint8_t *)ints, sizeof(ints)); - for (int j = 0; j < 256 && i < calc->num_otps; j++) { - int newIndex = i + (ints[j] % (calc->num_otps - i)); - otp_t temp = calc->data[i]; - calc->data[i] = calc->data[newIndex]; - calc->data[newIndex] = temp; - i++; - } - } - } - - return calc->data; -} diff --git a/external/badvpn_dns/security/OTPCalculator.h b/external/badvpn_dns/security/OTPCalculator.h deleted file mode 100644 index f15f845..0000000 --- a/external/badvpn_dns/security/OTPCalculator.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file OTPCalculator.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object that calculates OTPs. - */ - -#ifndef BADVPN_SECURITY_OTPCALCULATOR_H -#define BADVPN_SECURITY_OTPCALCULATOR_H - -#include <stdlib.h> -#include <string.h> - -#include <misc/balign.h> -#include <misc/debug.h> -#include <security/BRandom.h> -#include <security/BEncryption.h> -#include <base/DebugObject.h> - -/** - * Type for an OTP. - */ -typedef uint32_t otp_t; - -/** - * Object that calculates OTPs. - */ -typedef struct { - DebugObject d_obj; - int num_otps; - int cipher; - int block_size; - size_t num_blocks; - otp_t *data; -} OTPCalculator; - -/** - * Initializes the calculator. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if this object - * will be used from a non-main thread. - * - * @param calc the object - * @param num_otps number of OTPs to generate from a seed. Must be >=0. - * @param cipher encryption cipher for calculating the OTPs. Must be valid - * according to {@link BEncryption_cipher_valid}. - * @return 1 on success, 0 on failure - */ -int OTPCalculator_Init (OTPCalculator *calc, int num_otps, int cipher) WARN_UNUSED; - -/** - * Frees the calculator. - * - * @param calc the object - */ -void OTPCalculator_Free (OTPCalculator *calc); - -/** - * Generates OTPs from the given key and IV. - * - * @param calc the object - * @param key encryption key - * @param iv initialization vector - * @param shuffle whether to shuffle the OTPs. Must be 1 or 0. - * @return pointer to an array of 32-bit OPTs. Constains as many OTPs as was specified - * in {@link OTPCalculator_Init}. Valid until the next generation or - * until the object is freed. - */ -otp_t * OTPCalculator_Generate (OTPCalculator *calc, uint8_t *key, uint8_t *iv, int shuffle); - -#endif diff --git a/external/badvpn_dns/security/OTPChecker.c b/external/badvpn_dns/security/OTPChecker.c deleted file mode 100644 index 8606a31..0000000 --- a/external/badvpn_dns/security/OTPChecker.c +++ /dev/null @@ -1,297 +0,0 @@ -/** - * @file OTPChecker.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/balloc.h> - -#include <security/OTPChecker.h> - -static void OTPChecker_Table_Empty (OTPChecker *mc, struct OTPChecker_table *t); -static void OTPChecker_Table_AddOTP (OTPChecker *mc, struct OTPChecker_table *t, otp_t otp); -static void OTPChecker_Table_Generate (OTPChecker *mc, struct OTPChecker_table *t, OTPCalculator *calc, uint8_t *key, uint8_t *iv); -static int OTPChecker_Table_CheckOTP (OTPChecker *mc, struct OTPChecker_table *t, otp_t otp); - -void OTPChecker_Table_Empty (OTPChecker *mc, struct OTPChecker_table *t) -{ - for (int i = 0; i < mc->num_entries; i++) { - t->entries[i].avail = -1; - } -} - -void OTPChecker_Table_AddOTP (OTPChecker *mc, struct OTPChecker_table *t, otp_t otp) -{ - // calculate starting index - int start_index = otp % mc->num_entries; - - // try indexes starting with the base position - for (int i = 0; i < mc->num_entries; i++) { - int index = bmodadd_int(start_index, i, mc->num_entries); - struct OTPChecker_entry *entry = &t->entries[index]; - - // if we find a free index, use it - if (entry->avail < 0) { - entry->otp = otp; - entry->avail = 1; - return; - } - - // if we find a used index with the same mac, - // use it by incrementing its count - if (entry->otp == otp) { - entry->avail++; - return; - } - } - - // will never add more macs than we can hold - ASSERT(0) -} - -void OTPChecker_Table_Generate (OTPChecker *mc, struct OTPChecker_table *t, OTPCalculator *calc, uint8_t *key, uint8_t *iv) -{ - // calculate values - otp_t *otps = OTPCalculator_Generate(calc, key, iv, 0); - - // empty table - OTPChecker_Table_Empty(mc ,t); - - // add calculated values to table - for (int i = 0; i < mc->num_otps; i++) { - OTPChecker_Table_AddOTP(mc, t, otps[i]); - } -} - -int OTPChecker_Table_CheckOTP (OTPChecker *mc, struct OTPChecker_table *t, otp_t otp) -{ - // calculate starting index - int start_index = otp % mc->num_entries; - - // try indexes starting with the base position - for (int i = 0; i < mc->num_entries; i++) { - int index = bmodadd_int(start_index, i, mc->num_entries); - struct OTPChecker_entry *entry = &t->entries[index]; - - // if we find an empty entry, there is no such mac - if (entry->avail < 0) { - return 0; - } - - // if we find a matching entry, check its count - if (entry->otp == otp) { - if (entry->avail > 0) { - entry->avail--; - return 1; - } - return 0; - } - } - - // there are always empty slots - ASSERT(0) - return 0; -} - -static void work_func (OTPChecker *mc) -{ - struct OTPChecker_table *table = &mc->tables[mc->next_table]; - OTPChecker_Table_Generate(mc, table, &mc->calc, mc->tw_key, mc->tw_iv); -} - -static void work_done_handler (OTPChecker *mc) -{ - ASSERT(mc->tw_have) - DebugObject_Access(&mc->d_obj); - - // free work - BThreadWork_Free(&mc->tw); - mc->tw_have = 0; - - // update next table number - mc->next_table = bmodadd_int(mc->next_table, 1, mc->num_tables); - - // update number of used tables if not all are used yet - if (mc->tables_used < mc->num_tables) { - mc->tables_used++; - } - - // call handler - if (mc->handler) { - mc->handler(mc->user); - return; - } -} - -int OTPChecker_Init (OTPChecker *mc, int num_otps, int cipher, int num_tables, BThreadWorkDispatcher *twd) -{ - ASSERT(num_otps > 0) - ASSERT(BEncryption_cipher_valid(cipher)) - ASSERT(num_tables > 0) - - // init arguments - mc->num_otps = num_otps; - mc->cipher = cipher; - mc->num_tables = num_tables; - mc->twd = twd; - - // set no handlers - mc->handler = NULL; - - // set number of entries - if (mc->num_otps > INT_MAX / 2) { - goto fail0; - } - mc->num_entries = 2 * mc->num_otps; - - // set no tables used - mc->tables_used = 0; - mc->next_table = 0; - - // initialize calculator - if (!OTPCalculator_Init(&mc->calc, mc->num_otps, cipher)) { - goto fail0; - } - - // allocate tables - if (!(mc->tables = (struct OTPChecker_table *)BAllocArray(mc->num_tables, sizeof(mc->tables[0])))) { - goto fail1; - } - - // allocate entries - if (!(mc->entries = (struct OTPChecker_entry *)BAllocArray2(mc->num_tables, mc->num_entries, sizeof(mc->entries[0])))) { - goto fail2; - } - - // initialize tables - for (int i = 0; i < mc->num_tables; i++) { - struct OTPChecker_table *table = &mc->tables[i]; - table->entries = mc->entries + (size_t)i * mc->num_entries; - OTPChecker_Table_Empty(mc, table); - } - - // have no work - mc->tw_have = 0; - - DebugObject_Init(&mc->d_obj); - return 1; - -fail2: - BFree(mc->tables); -fail1: - OTPCalculator_Free(&mc->calc); -fail0: - return 0; -} - -void OTPChecker_Free (OTPChecker *mc) -{ - DebugObject_Free(&mc->d_obj); - - // free work - if (mc->tw_have) { - BThreadWork_Free(&mc->tw); - } - - // free entries - BFree(mc->entries); - - // free tables - BFree(mc->tables); - - // free calculator - OTPCalculator_Free(&mc->calc); -} - -void OTPChecker_AddSeed (OTPChecker *mc, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(mc->next_table >= 0) - ASSERT(mc->next_table < mc->num_tables) - DebugObject_Access(&mc->d_obj); - - // free existing work - if (mc->tw_have) { - BThreadWork_Free(&mc->tw); - } - - // set table's seed ID - mc->tables[mc->next_table].id = seed_id; - - // copy key and IV - memcpy(mc->tw_key, key, BEncryption_cipher_key_size(mc->cipher)); - memcpy(mc->tw_iv, iv, BEncryption_cipher_block_size(mc->cipher)); - - // start work - BThreadWork_Init(&mc->tw, mc->twd, (BThreadWork_handler_done)work_done_handler, mc, (BThreadWork_work_func)work_func, mc); - - // set have work - mc->tw_have = 1; -} - -void OTPChecker_RemoveSeeds (OTPChecker *mc) -{ - DebugObject_Access(&mc->d_obj); - - // free existing work - if (mc->tw_have) { - BThreadWork_Free(&mc->tw); - mc->tw_have = 0; - } - - mc->tables_used = 0; - mc->next_table = 0; -} - -int OTPChecker_CheckOTP (OTPChecker *mc, uint16_t seed_id, otp_t otp) -{ - DebugObject_Access(&mc->d_obj); - - // try tables in reverse order - for (int i = 1; i <= mc->tables_used; i++) { - int table_index = bmodadd_int(mc->next_table, mc->num_tables - i, mc->num_tables); - if (table_index == mc->next_table && mc->tw_have) { - // ignore table that is being generated - continue; - } - - struct OTPChecker_table *table = &mc->tables[table_index]; - if (table->id == seed_id) { - return OTPChecker_Table_CheckOTP(mc, table, otp); - } - } - - return 0; -} - -void OTPChecker_SetHandlers (OTPChecker *mc, OTPChecker_handler handler, void *user) -{ - DebugObject_Access(&mc->d_obj); - - mc->handler = handler; - mc->user = user; -} diff --git a/external/badvpn_dns/security/OTPChecker.h b/external/badvpn_dns/security/OTPChecker.h deleted file mode 100644 index d81a91c..0000000 --- a/external/badvpn_dns/security/OTPChecker.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file OTPChecker.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object that checks OTPs agains known seeds. - */ - -#ifndef BADVPN_SECURITY_OTPCHECKER_H -#define BADVPN_SECURITY_OTPCHECKER_H - -#include <stdint.h> - -#include <misc/balign.h> -#include <misc/debug.h> -#include <misc/modadd.h> -#include <security/OTPCalculator.h> -#include <base/DebugObject.h> -#include <threadwork/BThreadWork.h> - -struct OTPChecker_entry { - otp_t otp; - int avail; -}; - -struct OTPChecker_table { - uint16_t id; - struct OTPChecker_entry *entries; -}; - -/** - * Handler called when OTP generation for a seed is finished and new OTPs - * can be recognized. - * - * @param user as in {@link OTPChecker_Init} - */ -typedef void (*OTPChecker_handler) (void *user); - -/** - * Object that checks OTPs agains known seeds. - */ -typedef struct { - BThreadWorkDispatcher *twd; - OTPChecker_handler handler; - void *user; - int num_otps; - int cipher; - int num_entries; - int num_tables; - int tables_used; - int next_table; - OTPCalculator calc; - struct OTPChecker_table *tables; - struct OTPChecker_entry *entries; - int tw_have; - BThreadWork tw; - uint8_t tw_key[BENCRYPTION_MAX_KEY_SIZE]; - uint8_t tw_iv[BENCRYPTION_MAX_BLOCK_SIZE]; - DebugObject d_obj; -} OTPChecker; - -/** - * Initializes the checker. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param mc the object - * @param num_otps number of OTPs to generate from a seed. Must be >0. - * @param cipher encryption cipher for calculating the OTPs. Must be valid - * according to {@link BEncryption_cipher_valid}. - * @param num_tables number of tables to keep, each for one seed. Must be >0. - * @param twd thread work dispatcher - * @return 1 on success, 0 on failure - */ -int OTPChecker_Init (OTPChecker *mc, int num_otps, int cipher, int num_tables, BThreadWorkDispatcher *twd) WARN_UNUSED; - -/** - * Frees the checker. - * - * @param mc the object - */ -void OTPChecker_Free (OTPChecker *mc); - -/** - * Starts generating OTPs to recognize for a seed. - * OTPs for this seed will not be recognized until the {@link OTPChecker_handler} handler is called. - * If OTPs are still being generated for a previous seed, it will be forgotten. - * - * @param mc the object - * @param seed_id seed identifier - * @param key encryption key - * @param iv initialization vector - */ -void OTPChecker_AddSeed (OTPChecker *mc, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes all active seeds. - * - * @param mc the object - */ -void OTPChecker_RemoveSeeds (OTPChecker *mc); - -/** - * Checks an OTP. - * - * @param mc the object - * @param seed_id identifer of seed whom the OTP is claimed to belong to - * @param otp OTP to check - * @return 1 if the OTP is valid, 0 if not - */ -int OTPChecker_CheckOTP (OTPChecker *mc, uint16_t seed_id, otp_t otp); - -/** - * Sets handlers. - * - * @param mc the object - * @param handler handler to call when generation of new OTPs is complete, - * after {@link OTPChecker_AddSeed} was called. - * @param user argument to handler - */ -void OTPChecker_SetHandlers (OTPChecker *mc, OTPChecker_handler handler, void *user); - -#endif diff --git a/external/badvpn_dns/security/OTPGenerator.c b/external/badvpn_dns/security/OTPGenerator.c deleted file mode 100644 index 58a59f5..0000000 --- a/external/badvpn_dns/security/OTPGenerator.c +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @file OTPGenerator.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <security/OTPGenerator.h> - -static void work_func (OTPGenerator *g) -{ - g->otps[!g->cur_calc] = OTPCalculator_Generate(&g->calc[!g->cur_calc], g->tw_key, g->tw_iv, 1); -} - -static void work_done_handler (OTPGenerator *g) -{ - ASSERT(g->tw_have) - DebugObject_Access(&g->d_obj); - - // free work - BThreadWork_Free(&g->tw); - g->tw_have = 0; - - // use new OTPs - g->cur_calc = !g->cur_calc; - g->position = 0; - - // call handler - g->handler(g->user); - return; -} - -int OTPGenerator_Init (OTPGenerator *g, int num_otps, int cipher, BThreadWorkDispatcher *twd, OTPGenerator_handler handler, void *user) -{ - ASSERT(num_otps >= 0) - ASSERT(BEncryption_cipher_valid(cipher)) - - // init arguments - g->num_otps = num_otps; - g->cipher = cipher; - g->twd = twd; - g->handler = handler; - g->user = user; - - // init position - g->position = g->num_otps; - - // init calculator - if (!OTPCalculator_Init(&g->calc[0], g->num_otps, g->cipher)) { - goto fail0; - } - - // init calculator - if (!OTPCalculator_Init(&g->calc[1], g->num_otps, g->cipher)) { - goto fail1; - } - - // set current calculator - g->cur_calc = 0; - - // have no work - g->tw_have = 0; - - DebugObject_Init(&g->d_obj); - return 1; - -fail1: - OTPCalculator_Free(&g->calc[0]); -fail0: - return 0; -} - -void OTPGenerator_Free (OTPGenerator *g) -{ - DebugObject_Free(&g->d_obj); - - // free work - if (g->tw_have) { - BThreadWork_Free(&g->tw); - } - - // free calculator - OTPCalculator_Free(&g->calc[1]); - - // free calculator - OTPCalculator_Free(&g->calc[0]); -} - -void OTPGenerator_SetSeed (OTPGenerator *g, uint8_t *key, uint8_t *iv) -{ - DebugObject_Access(&g->d_obj); - - // free existing work - if (g->tw_have) { - BThreadWork_Free(&g->tw); - } - - // copy key and IV - memcpy(g->tw_key, key, BEncryption_cipher_key_size(g->cipher)); - memcpy(g->tw_iv, iv, BEncryption_cipher_block_size(g->cipher)); - - // start work - BThreadWork_Init(&g->tw, g->twd, (BThreadWork_handler_done)work_done_handler, g, (BThreadWork_work_func)work_func, g); - - // set have work - g->tw_have = 1; -} - -int OTPGenerator_GetPosition (OTPGenerator *g) -{ - DebugObject_Access(&g->d_obj); - - return g->position; -} - -void OTPGenerator_Reset (OTPGenerator *g) -{ - DebugObject_Access(&g->d_obj); - - // free existing work - if (g->tw_have) { - BThreadWork_Free(&g->tw); - g->tw_have = 0; - } - - g->position = g->num_otps; -} - -otp_t OTPGenerator_GetOTP (OTPGenerator *g) -{ - ASSERT(g->position < g->num_otps) - DebugObject_Access(&g->d_obj); - - return g->otps[g->cur_calc][g->position++]; -} diff --git a/external/badvpn_dns/security/OTPGenerator.h b/external/badvpn_dns/security/OTPGenerator.h deleted file mode 100644 index f2c83dd..0000000 --- a/external/badvpn_dns/security/OTPGenerator.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file OTPGenerator.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which generates OTPs for use in sending packets. - */ - -#ifndef BADVPN_SECURITY_OTPGENERATOR_H -#define BADVPN_SECURITY_OTPGENERATOR_H - -#include <misc/debug.h> -#include <security/OTPCalculator.h> -#include <base/DebugObject.h> -#include <threadwork/BThreadWork.h> - -/** - * Handler called when OTP generation for a seed is finished. - * The OTP position is reset to zero before the handler is called. - * - * @param user as in {@link OTPGenerator_Init} - */ -typedef void (*OTPGenerator_handler) (void *user); - -/** - * Object which generates OTPs for use in sending packets. - */ -typedef struct { - int num_otps; - int cipher; - BThreadWorkDispatcher *twd; - OTPGenerator_handler handler; - void *user; - int position; - int cur_calc; - OTPCalculator calc[2]; - otp_t *otps[2]; - int tw_have; - BThreadWork tw; - uint8_t tw_key[BENCRYPTION_MAX_KEY_SIZE]; - uint8_t tw_iv[BENCRYPTION_MAX_BLOCK_SIZE]; - DebugObject d_obj; -} OTPGenerator; - -/** - * Initializes the generator. - * The object is initialized with number of used OTPs = num_otps. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param g the object - * @param num_otps number of OTPs to generate from a seed. Must be >=0. - * @param cipher encryption cipher for calculating the OTPs. Must be valid - * according to {@link BEncryption_cipher_valid}. - * @param twd thread work dispatcher - * @param handler handler to call when generation of new OTPs is complete, - * after {@link OTPGenerator_SetSeed} was called. - * @param user argument to handler - * @return 1 on success, 0 on failure - */ -int OTPGenerator_Init (OTPGenerator *g, int num_otps, int cipher, BThreadWorkDispatcher *twd, OTPGenerator_handler handler, void *user) WARN_UNUSED; - -/** - * Frees the generator. - * - * @param g the object - */ -void OTPGenerator_Free (OTPGenerator *g); - -/** - * Starts generating OTPs for a seed. - * When generation is complete and the new OTPs may be used, the {@link OTPGenerator_handler} - * handler will be called. - * If OTPs are still being generated for a previous seed, it will be forgotten. - * This call by itself does not affect the OTP position; rather the position is set to zero - * before the handler is called. - * - * @param g the object - * @param key encryption key - * @param iv initialization vector - */ -void OTPGenerator_SetSeed (OTPGenerator *g, uint8_t *key, uint8_t *iv); - -/** - * Returns the number of OTPs used up from the current seed so far. - * If there is no seed yet, returns num_otps. - * - * @param g the object - * @return number of used OTPs - */ -int OTPGenerator_GetPosition (OTPGenerator *g); - -/** - * Sets the number of used OTPs to num_otps. - * - * @param g the object - */ -void OTPGenerator_Reset (OTPGenerator *g); - -/** - * Generates a single OTP. - * The number of used OTPs must be < num_otps. - * The number of used OTPs is incremented. - * - * @param g the object - */ -otp_t OTPGenerator_GetOTP (OTPGenerator *g); - -#endif diff --git a/external/badvpn_dns/server/CMakeLists.txt b/external/badvpn_dns/server/CMakeLists.txt deleted file mode 100644 index 1d02432..0000000 --- a/external/badvpn_dns/server/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -add_executable(badvpn-server server.c) -target_link_libraries(badvpn-server system flow flowextra nspr_support predicate security ${NSPR_LIBRARIES} ${NSS_LIBRARIES}) - -install( - TARGETS badvpn-server - RUNTIME DESTINATION bin -) - -install( - FILES badvpn-server.8 - DESTINATION share/man/man8 -) diff --git a/external/badvpn_dns/server/badvpn-server.8 b/external/badvpn_dns/server/badvpn-server.8 deleted file mode 100644 index b8c60e5..0000000 --- a/external/badvpn_dns/server/badvpn-server.8 +++ /dev/null @@ -1,190 +0,0 @@ -.TH badvpn-server 8 "21 June 2011" -.SH NAME -badvpn-server - chat server for the BadVPN peer-to-peer VPN system -.SH SYNOPSIS -.B badvpn-server -.RS -.RB "[" --help "]" -.br -.RB "[" --version "]" -.br -.RB "[" --logger " <stdout/syslog>]" -.br -(logger=syslog? -.br -.RS -.br -.RB "[" --syslog-facility " <string>]" -.br -.RB "[" --syslog-ident " <string>]" -.br -.RE -) -.br -.RB "[" --loglevel " <0-5/none/error/warning/notice/info/debug>]" -.br -.RB "[" --channel-loglevel " <channel-name> <0-5/none/error/warning/notice/info/debug>] ..." -.br -.RB "[" --listen-addr " <addr>] ..." -.br -.RB "[" --ssl " " --nssdb " <string> " --server-cert-name " <string>]" -.br -.RB "[" --comm-predicate " <string>]" -.br -.RB "[" --relay-predicate " <string>]" -.br -.RB "[" --client-socket-sndbuf " <bytes / 0>]" -.br -.RE -.SH INTRODUCTION -.P -This page documents the BadVPN server, which is used in a BadVPN VPN network by peers to -talk to each other in order to establish data connections. For a general description of -BadVPN, see -.BR badvpn (7). -.SH DESCRIPTION -.P -The BadVPN server is a chat server used by nodes in the VPN network to talk to each other -in order to establish data connections. Once it initializes, the server only terminates -if a signal is received. -.SH OPTIONS -.P -The BadVPN server is configured entirely from command line. -.TP -.BR --help -Print version and command line syntax and exit. -.TP -.BR --version -Print version and exit. -.TP -.BR --logger " <stdout/syslog>" -Select where to log messages. Default is stdout. Syslog is not available on Windows. -.TP -.BR --syslog-facility " <string>" -When logging to syslog, set the logging facility. The facility name must be in lower case. -.TP -.BR --syslog-ident " <string>" -When logging to syslog, set the ident. -.TP -.BR --loglevel " <0-5/none/error/warning/notice/info/debug>" -Set the default logging level. -.TP -.BR --channel-loglevel " <channel-name> <0-5/none/error/warning/notice/info/debug>" -Set the logging level for a specific logging channel. -.TP -.BR --listen-addr " <addr>" -Add an address for the server to listen on. See below for address format. -.TP -.BR --ssl -Use TLS. Requires --nssdb and --server-cert-name. -.TP -.BR --nssdb " <string>" -When using TLS, the NSS database to use. Probably something like sql:/some/folder. -.TP -.BR --server-cert-name " <string>" -When using TLS, the name of the certificate to use. The certificate must be readily accessible. -.TP -.BR --comm-predicate " <string>" -Set a predicate to define which pairs of clients are allowed to communicate. The predicate is a -logical expression; see below for details. Available functions: -.br -.BR p1name "(string)" -- true if the TLS common name of peer 1 equals the given string. If TLS is not used, the common -name is assumed to be an empty string. -.br -.BR p1addr "(string)" -- true if the IP address of peer 1 equals the given string. The string must not be a name. -.br -.BR p2name "(string)" -- true if the TLS common name of peer 2 equals the given string. If TLS is not used, the common -name is assumed to be an empty string. -.br -.BR p2addr "(string)" -- true if the IP address of peer 2 equals the given string. The string must not be a name. -.br -There is no rule as to which is peer 1 and which peer 2. When the server needs to determine -whether to allow two peers to communicate, it evaluates the predicate once and in no specific order. -.TP -.BR --relay-predicate " <string>" -Set a predicate to define how peers can relay data through other peers. The predicate is a -logical expression; see below for details. If the predicate evaluates to true, peer P can relay data -through peer R. Available functions: -.br -.BR pname "(string)" -- true if the TLS common name of peer P peer equals the given string. If TLS is not used, the common -name is assumed to be an empty string. -.br -.BR paddr "(string)" -- true if the IP address of peer P equals the given string. The string must not be a name. -.br -.BR rname "(string)" -- true if the TLS common name of peer R peer equals the given string. If TLS is not used, the common -name is assumed to be an empty string. -.br -.BR raddr "(string)" -- true if the IP address of peer R equals the given string. The string must not be a name. -.br -.TP -.BR --client-socket-sndbuf " <bytes / 0>" -Sets the value of the SO_SNDBUF socket option for client TCP sockets (zero to not set). Lower values -will improve fairness when data from multiple peers is being sent to a given peer, but may result in lower -bandwidth if the network's bandwidth-delay product to too big. -.SH "EXIT CODE" -.P -If initialization fails, exits with code 1. Otherwise runs until termination is requested and exits with code 1. -.SH "ADDRESS FORMAT" -.P -Addresses have the form ipaddr:port, where ipaddr is either an IPv4 address (name or numeric), or an -IPv6 address enclosed in brackets [] (name or numeric again). -.SH PREDICATES -.P -The BadVPN server includes a small predicate language used to define certain policies. -Syntax and semantics of the language are described here. -.TP -.BR true -Logical true constant. Evaluates to 1. -.TP -.BR false -Logical false constant. Evaluates to 0. -.TP -.BR NOT " expression" -Logical negation. If the expression evaluates to error, the -negation evaluates to error. -.TP -.RB "expression " OR " expression" -Logical disjunction. The second expression is only evaluated -if the first expression evaluates to false. If a sub-expression -evaluates to error, the disjunction evaluates to error. -.TP -.RB "expression " AND " expression" -Logical conjunction. The second expression is only evaluated -if the first expression evaluates to true. If a sub-expression -evaluates to error, the conjunction evaluates to error. -.TP -.RB function "(" "arg" "," " ..." "," " arg" ")" -Evaluation of a user-provided function (function is the name of the -function, [a-zA-Z0-9_]+). -If the function with the given name does not exist, it evaluates to -error. -Arguments are evaluated from left to right. Each argument can either -be a logical expression or a string (characters enclosed in double -quotes, without any double quote). -If an argument is encountered, but all needed arguments have already -been evaluated, the function evaluates to error. -If an argument is of wrong type, it is not evaluated and the function -evaluates to error. -If an argument evaluates to error, the function evaluates to error. -If after all arguments have been evaluated, the function needs more -arguments, it evaluates to error. -Then the handler function is called. If it returns anything other -than 1 and 0, the function evaluates to error. Otherwise it evaluates -to what the handler function returned. -.SH "EXAMPLES" -.P -For examples of using BadVPN, see -.BR badvpn (7). -.SH "SEE ALSO" -.BR badvpn-client (8), -.BR badvpn (7) -.SH AUTHORS -Ambroz Bizjak ambrop7@gmail.com diff --git a/external/badvpn_dns/server/server.c b/external/badvpn_dns/server/server.c deleted file mode 100644 index 2b22101..0000000 --- a/external/badvpn_dns/server/server.c +++ /dev/null @@ -1,2394 +0,0 @@ -/** - * @file server.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stddef.h> -#include <stdarg.h> - -// NSPR and NSS -#include <prinit.h> -#include <prio.h> -#include <prerror.h> -#include <prtypes.h> -#include <nss.h> -#include <ssl.h> -#include <cert.h> -#include <keyhi.h> -#include <secasn1.h> - -// BadVPN -#include <misc/version.h> -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/nsskey.h> -#include <misc/byteorder.h> -#include <misc/loglevel.h> -#include <misc/loggers_string.h> -#include <misc/open_standard_streams.h> -#include <misc/compare.h> -#include <misc/bsize.h> -#include <predicate/BPredicate.h> -#include <base/DebugObject.h> -#include <base/BLog.h> -#include <system/BSignal.h> -#include <system/BTime.h> -#include <system/BNetwork.h> -#include <security/BRandom.h> -#include <nspr_support/DummyPRFileDesc.h> -#include <threadwork/BThreadWork.h> - -#ifndef BADVPN_USE_WINAPI -#include <base/BLog_syslog.h> -#endif - -#include <server/server.h> - -#include <generated/blog_channel_server.h> - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -// parsed command-line options -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - int threads; - int use_threads_for_ssl_handshake; - int use_threads_for_ssl_data; - int ssl; - char *nssdb; - char *server_cert_name; - char *listen_addrs[MAX_LISTEN_ADDRS]; - int num_listen_addrs; - char *comm_predicate; - char *relay_predicate; - int client_socket_sndbuf; - int max_clients; -} options; - -// listen addresses -BAddr listen_addrs[MAX_LISTEN_ADDRS]; -int num_listen_addrs; - -// communication predicate -BPredicate comm_predicate; - -// communication predicate functions -BPredicateFunction comm_predicate_func_p1name; -BPredicateFunction comm_predicate_func_p2name; -BPredicateFunction comm_predicate_func_p1addr; -BPredicateFunction comm_predicate_func_p2addr; - -// variables when evaluating the predicate, adjusted before every evaluation -const char *comm_predicate_p1name; -const char *comm_predicate_p2name; -BIPAddr comm_predicate_p1addr; -BIPAddr comm_predicate_p2addr; - -// relay predicate -BPredicate relay_predicate; - -// gateway predicate functions -BPredicateFunction relay_predicate_func_pname; -BPredicateFunction relay_predicate_func_rname; -BPredicateFunction relay_predicate_func_paddr; -BPredicateFunction relay_predicate_func_raddr; - -// variables when evaluating the comm_predicate, adjusted before every evaluation -const char *relay_predicate_pname; -const char *relay_predicate_rname; -BIPAddr relay_predicate_paddr; -BIPAddr relay_predicate_raddr; - -// i/o system -BReactor ss; - -// thread work dispatcher -BThreadWorkDispatcher twd; - -// server certificate if using SSL -CERTCertificate *server_cert; - -// server private key if using SSL -SECKEYPrivateKey *server_key; - -// model NSPR file descriptor to speed up client initialization -PRFileDesc model_dprfd; -PRFileDesc *model_prfd; - -// listeners -BListener listeners[MAX_LISTEN_ADDRS]; -int num_listeners; - -// number of connected clients -int clients_num; - -// ID assigned to last connected client -peerid_t clients_nextid; - -// clients list -LinkedList1 clients; - -// clients tree (by ID) -BAVL clients_tree; - -// prints help text to standard output -static void print_help (const char *name); - -// prints program name and version to standard output -static void print_version (void); - -// parses the command line -static int parse_arguments (int argc, char *argv[]); - -// processes certain command line options -static int process_arguments (void); - -static int ssl_flags (void); - -// handler for program termination request -static void signal_handler (void *unused); - -// listener handler, accepts new clients -static void listener_handler (BListener *listener); - -// frees resources used by a client -static void client_dealloc (struct client_data *client); - -static int client_compute_buffer_size (struct client_data *client); - -// initializes the I/O porition of the client -static int client_init_io (struct client_data *client); - -// deallocates the I/O portion of the client. Must have no outgoing flows. -static void client_dealloc_io (struct client_data *client); - -// removes a client -static void client_remove (struct client_data *client); - -// job to finish removal after clients are informed -static void client_dying_job (struct client_data *client); - -// appends client log prefix -static void client_logfunc (struct client_data *client); - -// passes a message to the logger, prepending about the client -static void client_log (struct client_data *client, int level, const char *fmt, ...); - -// client activity timer handler. Removes the client. -static void client_disconnect_timer_handler (struct client_data *client); - -// BConnection handler -static void client_connection_handler (struct client_data *client, int event); - -// BSSLConnection handler -static void client_sslcon_handler (struct client_data *client, int event); - -// decoder handler -static void client_decoder_handler_error (struct client_data *client); - -// provides a buffer for sending a control packet to the client -static int client_start_control_packet (struct client_data *client, void **data, int len); - -// submits a packet written after client_start_control_packet -static void client_end_control_packet (struct client_data *client, uint8_t id); - -// sends a newclient message to a client -static int client_send_newclient (struct client_data *client, struct client_data *nc, int relay_server, int relay_client); - -// sends an endclient message to a client -static int client_send_endclient (struct client_data *client, peerid_t end_id); - -// handler for packets received from the client -static void client_input_handler_send (struct client_data *client, uint8_t *data, int data_len); - -// processes hello packets from clients -static void process_packet_hello (struct client_data *client, uint8_t *data, int data_len); - -// processes outmsg packets from clients -static void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_len); - -// processes resetpeer packets from clients -static void process_packet_resetpeer (struct client_data *client, uint8_t *data, int data_len); - -// processes acceptpeer packets from clients -static void process_packet_acceptpeer (struct client_data *client, uint8_t *data, int data_len); - -// creates a peer flow -static struct peer_flow * peer_flow_create (struct client_data *src_client, struct client_data *dest_client); - -// deallocates a peer flow -static void peer_flow_dealloc (struct peer_flow *flow); - -static int peer_flow_init_io (struct peer_flow *flow); -static void peer_flow_free_io (struct peer_flow *flow); - -// disconnects the source client from a peer flow -static void peer_flow_disconnect (struct peer_flow *flow); - -// provides a buffer for sending a peer-to-peer packet -static int peer_flow_start_packet (struct peer_flow *flow, void **data, int len); - -// submits a peer-to-peer packet written after peer_flow_start_packet -static void peer_flow_end_packet (struct peer_flow *flow, uint8_t type); - -// handler called by the queue when a peer flow can be freed after its source has gone away -static void peer_flow_handler_canremove (struct peer_flow *flow); - -static void peer_flow_start_reset (struct peer_flow *flow); -static void peer_flow_drive_reset (struct peer_flow *flow); - -static void peer_flow_reset_qflow_handler_busy (struct peer_flow *flow); - -// resets clients knowledge after the timer expires -static void peer_flow_reset_timer_handler (struct peer_flow *flow); - -// generates a client ID to be used for a newly connected client -static peerid_t new_client_id (void); - -// finds a client by its ID -static struct client_data * find_client_by_id (peerid_t id); - -// checks if two clients are allowed to communicate. May depend on the order -// of the clients. -static int clients_allowed (struct client_data *client1, struct client_data *client2); - -// communication predicate function p1name -static int comm_predicate_func_p1name_cb (void *user, void **args); - -// communication predicate function p2name -static int comm_predicate_func_p2name_cb (void *user, void **args); - -// communication predicate function p1addr -static int comm_predicate_func_p1addr_cb (void *user, void **args); - -// communication predicate function p2addr -static int comm_predicate_func_p2addr_cb (void *user, void **args); - -// checks if relay is allowed for a client through another client -static int relay_allowed (struct client_data *client, struct client_data *relay); - -// relay predicate function pname -static int relay_predicate_func_pname_cb (void *user, void **args); - -// relay predicate function rname -static int relay_predicate_func_rname_cb (void *user, void **args); - -// relay predicate function paddr -static int relay_predicate_func_paddr_cb (void *user, void **args); - -// relay predicate function raddr -static int relay_predicate_func_raddr_cb (void *user, void **args); - -// comparator for peerid_t used in AVL tree -static int peerid_comparator (void *unused, peerid_t *p1, peerid_t *p2); - -static struct peer_know * create_know (struct client_data *from, struct client_data *to, int relay_server, int relay_client); -static void remove_know (struct peer_know *k); -static void know_inform_job_handler (struct peer_know *k); -static void uninform_know (struct peer_know *k); -static void know_uninform_job_handler (struct peer_know *k); - -static int launch_pair (struct peer_flow *flow_to); - -// find flow from a client to some client -static struct peer_flow * find_flow (struct client_data *client, peerid_t dest_id); - -int main (int argc, char *argv[]) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - if (options.ssl) { - // initialize NSPR - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - // initialize i/o layer types - if (!DummyPRFileDesc_GlobalInit()) { - BLog(BLOG_ERROR, "DummyPRFileDesc_GlobalInit failed"); - goto fail01; - } - if (!BSSLConnection_GlobalInit()) { - BLog(BLOG_ERROR, "BSSLConnection_GlobalInit failed"); - goto fail01; - } - - // initialize NSS - if (NSS_Init(options.nssdb) != SECSuccess) { - BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError()); - goto fail01; - } - if (NSS_SetDomesticPolicy() != SECSuccess) { - BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // initialize server cache - if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // open server certificate and private key - if (!open_nss_cert_and_key(options.server_cert_name, &server_cert, &server_key)) { - BLog(BLOG_ERROR, "Cannot open certificate and key"); - goto fail03; - } - - // initialize model SSL fd - DummyPRFileDesc_Create(&model_dprfd); - if (!(model_prfd = SSL_ImportFD(NULL, &model_dprfd))) { - BLog(BLOG_ERROR, "SSL_ImportFD failed"); - ASSERT_FORCE(PR_Close(&model_dprfd) == PR_SUCCESS) - goto fail04; - } - - // set server certificate - if (SSL_ConfigSecureServer(model_prfd, server_cert, server_key, NSS_FindCertKEAType(server_cert)) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigSecureServer failed"); - goto fail05; - } - } - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init communication predicate - if (options.comm_predicate) { - // init predicate - if (!BPredicate_Init(&comm_predicate, options.comm_predicate)) { - BLog(BLOG_ERROR, "BPredicate_Init failed"); - goto fail1; - } - - // init functions - int args[] = {PREDICATE_TYPE_STRING}; - BPredicateFunction_Init(&comm_predicate_func_p1name, &comm_predicate, "p1name", args, 1, comm_predicate_func_p1name_cb, NULL); - BPredicateFunction_Init(&comm_predicate_func_p2name, &comm_predicate, "p2name", args, 1, comm_predicate_func_p2name_cb, NULL); - BPredicateFunction_Init(&comm_predicate_func_p1addr, &comm_predicate, "p1addr", args, 1, comm_predicate_func_p1addr_cb, NULL); - BPredicateFunction_Init(&comm_predicate_func_p2addr, &comm_predicate, "p2addr", args, 1, comm_predicate_func_p2addr_cb, NULL); - } - - // init relay predicate - if (options.relay_predicate) { - // init predicate - if (!BPredicate_Init(&relay_predicate, options.relay_predicate)) { - BLog(BLOG_ERROR, "BPredicate_Init failed"); - goto fail2; - } - - // init functions - int args[] = {PREDICATE_TYPE_STRING}; - BPredicateFunction_Init(&relay_predicate_func_pname, &relay_predicate, "pname", args, 1, relay_predicate_func_pname_cb, NULL); - BPredicateFunction_Init(&relay_predicate_func_rname, &relay_predicate, "rname", args, 1, relay_predicate_func_rname_cb, NULL); - BPredicateFunction_Init(&relay_predicate_func_paddr, &relay_predicate, "paddr", args, 1, relay_predicate_func_paddr_cb, NULL); - BPredicateFunction_Init(&relay_predicate_func_raddr, &relay_predicate, "raddr", args, 1, relay_predicate_func_raddr_cb, NULL); - } - - // init time - BTime_Init(); - - // initialize reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail3; - } - - // init thread work dispatcher - if (!BThreadWorkDispatcher_Init(&twd, &ss, options.threads)) { - BLog(BLOG_ERROR, "BThreadWorkDispatcher_Init failed"); - goto fail3a; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail4; - } - - // initialize number of clients - clients_num = 0; - - // first client ID will be zero - clients_nextid = 0; - - // initialize clients linked list - LinkedList1_Init(&clients); - - // initialize clients tree - BAVL_Init(&clients_tree, OFFSET_DIFF(struct client_data, id, tree_node), (BAVL_comparator)peerid_comparator, NULL); - - // initialize listeners - num_listeners = 0; - while (num_listeners < num_listen_addrs) { - if (!BListener_Init(&listeners[num_listeners], listen_addrs[num_listeners], &ss, &listeners[num_listeners], (BListener_handler)listener_handler)) { - BLog(BLOG_ERROR, "BListener_Init failed"); - goto fail10; - } - num_listeners++; - } - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - // free clients - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&clients)) { - struct client_data *client = UPPER_OBJECT(node, struct client_data, list_node); - - // remove outgoing knows - LinkedList1Node *node2; - while (node2 = LinkedList1_GetFirst(&client->know_out_list)) { - struct peer_know *k = UPPER_OBJECT(node2, struct peer_know, from_node); - remove_know(k); - } - - // remove incoming knows - LinkedList1Node *node3; - while (node3 = LinkedList1_GetFirst(&client->know_in_list)) { - struct peer_know *k = UPPER_OBJECT(node3, struct peer_know, to_node); - remove_know(k); - } - - // remove outgoing flows - LinkedList1Node *flow_node; - while (flow_node = LinkedList1_GetFirst(&client->peer_out_flows_list)) { - struct peer_flow *flow = UPPER_OBJECT(flow_node, struct peer_flow, src_list_node); - ASSERT(flow->src_client == client) - - // allow freeing queue flows at dest - PacketPassFairQueue_PrepareFree(&flow->dest_client->output_peers_fairqueue); - - // deallocate flow - peer_flow_dealloc(flow); - } - - // deallocate client - client_dealloc(client); - } -fail10: - while (num_listeners > 0) { - num_listeners--; - BListener_Free(&listeners[num_listeners]); - } - - BSignal_Finish(); -fail4: - BThreadWorkDispatcher_Free(&twd); -fail3a: - BReactor_Free(&ss); -fail3: - if (options.relay_predicate) { - BPredicateFunction_Free(&relay_predicate_func_raddr); - BPredicateFunction_Free(&relay_predicate_func_paddr); - BPredicateFunction_Free(&relay_predicate_func_rname); - BPredicateFunction_Free(&relay_predicate_func_pname); - BPredicate_Free(&relay_predicate); - } -fail2: - if (options.comm_predicate) { - BPredicateFunction_Free(&comm_predicate_func_p2addr); - BPredicateFunction_Free(&comm_predicate_func_p1addr); - BPredicateFunction_Free(&comm_predicate_func_p2name); - BPredicateFunction_Free(&comm_predicate_func_p1name); - BPredicate_Free(&comm_predicate); - } -fail1: - if (options.ssl) { -fail05: - ASSERT_FORCE(PR_Close(model_prfd) == PR_SUCCESS) -fail04: - CERT_DestroyCertificate(server_cert); - SECKEY_DestroyPrivateKey(server_key); -fail03: - ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess) -fail02: - ASSERT_FORCE(NSS_Shutdown() == SECSuccess) -fail01: - ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS) - PL_ArenaFinish(); - } - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--threads <integer>]\n" - " [--use-threads-for-ssl-handshake]\n" - " [--use-threads-for-ssl-data]\n" - " [--listen-addr <addr>] ...\n" - " [--ssl --nssdb <string> --server-cert-name <string>]\n" - " [--comm-predicate <string>]\n" - " [--relay-predicate <string>]\n" - " [--client-socket-sndbuf <bytes / 0>]\n" - " [--max-clients <number>]\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.threads = 0; - options.use_threads_for_ssl_handshake = 0; - options.use_threads_for_ssl_data = 0; - options.ssl = 0; - options.nssdb = NULL; - options.server_cert_name = NULL; - options.num_listen_addrs = 0; - options.comm_predicate = NULL; - options.relay_predicate = NULL; - options.client_socket_sndbuf = CLIENT_DEFAULT_SOCKET_SNDBUF; - options.max_clients = DEFAULT_MAX_CLIENTS; - - for (int i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (i + 1 >= argc) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (i + 1 >= argc) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (i + 1 >= argc) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--threads")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.threads = atoi(argv[i + 1]); - i++; - } - else if (!strcmp(arg, "--use-threads-for-ssl-handshake")) { - options.use_threads_for_ssl_handshake = 1; - } - else if (!strcmp(arg, "--use-threads-for-ssl-data")) { - options.use_threads_for_ssl_data = 1; - } - else if (!strcmp(arg, "--ssl")) { - options.ssl = 1; - } - else if (!strcmp(arg, "--nssdb")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.nssdb = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-cert-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_cert_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--listen-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_listen_addrs == MAX_LISTEN_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.listen_addrs[options.num_listen_addrs] = argv[i + 1]; - options.num_listen_addrs++; - i++; - } - else if (!strcmp(arg, "--comm-predicate")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.comm_predicate = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--relay-predicate")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.relay_predicate = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--client-socket-sndbuf")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.client_socket_sndbuf = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else { - fprintf(stderr, "%s: unknown option\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!!options.nssdb != options.ssl) { - fprintf(stderr, "--ssl and --nssdb must be used together\n"); - return 0; - } - - if (!!options.server_cert_name != options.ssl) { - fprintf(stderr, "--ssl and --server-cert-name must be used together\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen addresses - num_listen_addrs = 0; - while (num_listen_addrs < options.num_listen_addrs) { - if (!BAddr_Parse(&listen_addrs[num_listen_addrs], options.listen_addrs[num_listen_addrs], NULL, 0)) { - BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed"); - return 0; - } - num_listen_addrs++; - } - - return 1; -} - -int ssl_flags (void) -{ - int flags = 0; - if (options.use_threads_for_ssl_handshake) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE; - } - if (options.use_threads_for_ssl_data) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_IO; - } - return flags; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&ss, 0); -} - -void listener_handler (BListener *listener) -{ - if (clients_num == options.max_clients) { - BLog(BLOG_WARNING, "too many clients for new client"); - goto fail0; - } - - // allocate the client structure - struct client_data *client = (struct client_data *)malloc(sizeof(*client)); - if (!client) { - BLog(BLOG_ERROR, "failed to allocate client"); - goto fail0; - } - - // accept connection - if (!BConnection_Init(&client->con, BConnection_source_listener(listener, &client->addr), &ss, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // limit socket send buffer, else our scheduling is pointless - if (options.client_socket_sndbuf > 0) { - if (!BConnection_SetSendBuffer(&client->con, options.client_socket_sndbuf)) { - BLog(BLOG_WARNING, "BConnection_SetSendBuffer failed"); - } - } - - // assign ID - client->id = new_client_id(); - - // set no common name - client->common_name = NULL; - - // now client_log() works - - // init connection interfaces - BConnection_SendAsync_Init(&client->con); - BConnection_RecvAsync_Init(&client->con); - - if (options.ssl) { - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&client->bottom_prfd, BConnection_SendAsync_GetIf(&client->con), BConnection_RecvAsync_GetIf(&client->con), &twd, ssl_flags())) { - client_log(client, BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail2; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(client->ssl_prfd = SSL_ImportFD(model_prfd, &client->bottom_prfd))) { - client_log(client, BLOG_ERROR, "SSL_ImportFD failed"); - ASSERT_FORCE(PR_Close(&client->bottom_prfd) == PR_SUCCESS) - goto fail2; - } - - // set server mode - if (SSL_ResetHandshake(client->ssl_prfd, PR_TRUE) != SECSuccess) { - client_log(client, BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail3; - } - - // set require client certificate - if (SSL_OptionSet(client->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) { - client_log(client, BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed"); - goto fail3; - } - if (SSL_OptionSet(client->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) { - client_log(client, BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed"); - goto fail3; - } - - // init SSL connection - BSSLConnection_Init(&client->sslcon, client->ssl_prfd, 1, BReactor_PendingGroup(&ss), client, (BSSLConnection_handler)client_sslcon_handler); - } else { - // initialize I/O - if (!client_init_io(client)) { - goto fail2; - } - } - - // start disconnect timer - BTimer_Init(&client->disconnect_timer, CLIENT_NO_DATA_TIME_LIMIT, (BTimer_handler)client_disconnect_timer_handler, client); - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // link in - clients_num++; - LinkedList1_Append(&clients, &client->list_node); - ASSERT_EXECUTE(BAVL_Insert(&clients_tree, &client->tree_node, NULL)) - - // init knowledge lists - LinkedList1_Init(&client->know_out_list); - LinkedList1_Init(&client->know_in_list); - - // initialize peer flows from us list and tree (flows for sending messages to other clients) - LinkedList1_Init(&client->peer_out_flows_list); - BAVL_Init(&client->peer_out_flows_tree, OFFSET_DIFF(struct peer_flow, dest_client_id, src_tree_node), (BAVL_comparator)peerid_comparator, NULL); - - // init dying - client->dying = 0; - BPending_Init(&client->dying_job, BReactor_PendingGroup(&ss), (BPending_handler)client_dying_job, client); - - // set state - client->initstatus = (options.ssl ? INITSTATUS_HANDSHAKE : INITSTATUS_WAITHELLO); - - client_log(client, BLOG_INFO, "initialized"); - - return; - - if (options.ssl) { -fail3: - ASSERT_FORCE(PR_Close(client->ssl_prfd) == PR_SUCCESS) - } -fail2: - BConnection_RecvAsync_Free(&client->con); - BConnection_SendAsync_Free(&client->con); - BConnection_Free(&client->con); -fail1: - free(client); -fail0: - return; -} - -void client_dealloc (struct client_data *client) -{ - ASSERT(LinkedList1_IsEmpty(&client->know_out_list)) - ASSERT(LinkedList1_IsEmpty(&client->know_in_list)) - ASSERT(LinkedList1_IsEmpty(&client->peer_out_flows_list)) - - // free I/O - if (client->initstatus >= INITSTATUS_WAITHELLO && !client->dying) { - client_dealloc_io(client); - } - - // free dying - BPending_Free(&client->dying_job); - - // link out - BAVL_Remove(&clients_tree, &client->tree_node); - LinkedList1_Remove(&clients, &client->list_node); - clients_num--; - - // stop disconnect timer - BReactor_RemoveTimer(&ss, &client->disconnect_timer); - - // free SSL - if (options.ssl) { - BSSLConnection_Free(&client->sslcon); - ASSERT_FORCE(PR_Close(client->ssl_prfd) == PR_SUCCESS) - } - - // free common name - if (client->common_name) { - PORT_Free(client->common_name); - } - - // free connection interfaces - BConnection_RecvAsync_Free(&client->con); - BConnection_SendAsync_Free(&client->con); - - // free connection - BConnection_Free(&client->con); - - // free memory - free(client); -} - -int client_compute_buffer_size (struct client_data *client) -{ - bsize_t s = bsize_add(bsize_fromsize(1), bsize_mul(bsize_fromsize(2), bsize_fromsize(options.max_clients - 1))); - - if (s.is_overflow || s.value > INT_MAX) { - return INT_MAX; - } else { - return s.value; - } -} - -int client_init_io (struct client_data *client) -{ - StreamPassInterface *send_if = (options.ssl ? BSSLConnection_GetSendIf(&client->sslcon) : BConnection_SendAsync_GetIf(&client->con)); - StreamRecvInterface *recv_if = (options.ssl ? BSSLConnection_GetRecvIf(&client->sslcon) : BConnection_RecvAsync_GetIf(&client->con)); - - // init input - - // init interface - PacketPassInterface_Init(&client->input_interface, SC_MAX_ENC, (PacketPassInterface_handler_send)client_input_handler_send, client, BReactor_PendingGroup(&ss)); - - // init decoder - if (!PacketProtoDecoder_Init(&client->input_decoder, recv_if, &client->input_interface, BReactor_PendingGroup(&ss), client, - (PacketProtoDecoder_handler_error)client_decoder_handler_error - )) { - client_log(client, BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail1; - } - - // init output common - - // init sender - PacketStreamSender_Init(&client->output_sender, send_if, PACKETPROTO_ENCLEN(SC_MAX_ENC), BReactor_PendingGroup(&ss)); - - // init queue - PacketPassPriorityQueue_Init(&client->output_priorityqueue, PacketStreamSender_GetInput(&client->output_sender), BReactor_PendingGroup(&ss), 0); - - // init output control flow - - // init queue flow - PacketPassPriorityQueueFlow_Init(&client->output_control_qflow, &client->output_priorityqueue, -1); - - // init PacketProtoFlow - if (!PacketProtoFlow_Init( - &client->output_control_oflow, SC_MAX_ENC, client_compute_buffer_size(client), - PacketPassPriorityQueueFlow_GetInput(&client->output_control_qflow), BReactor_PendingGroup(&ss) - )) { - client_log(client, BLOG_ERROR, "PacketProtoFlow_Init failed"); - goto fail2; - } - client->output_control_input = PacketProtoFlow_GetInput(&client->output_control_oflow); - client->output_control_packet_len = -1; - - // init output peers flow - - // init queue flow - // use lower priority than control flow (higher number) - PacketPassPriorityQueueFlow_Init(&client->output_peers_qflow, &client->output_priorityqueue, 0); - - // init fair queue (for different peers) - if (!PacketPassFairQueue_Init(&client->output_peers_fairqueue, PacketPassPriorityQueueFlow_GetInput(&client->output_peers_qflow), BReactor_PendingGroup(&ss), 0, 1)) { - client_log(client, BLOG_ERROR, "PacketPassFairQueue_Init failed"); - goto fail3; - } - - // init list of flows - LinkedList1_Init(&client->output_peers_flows); - - return 1; - -fail3: - PacketPassPriorityQueueFlow_Free(&client->output_peers_qflow); - PacketProtoFlow_Free(&client->output_control_oflow); -fail2: - PacketPassPriorityQueueFlow_Free(&client->output_control_qflow); - // free output common - PacketPassPriorityQueue_Free(&client->output_priorityqueue); - PacketStreamSender_Free(&client->output_sender); - // free input - PacketProtoDecoder_Free(&client->input_decoder); -fail1: - PacketPassInterface_Free(&client->input_interface); - return 0; -} - -void client_dealloc_io (struct client_data *client) -{ - // stop using any buffers before they get freed - if (options.ssl) { - BSSLConnection_ReleaseBuffers(&client->sslcon); - } - - // allow freeing fair queue flows - PacketPassFairQueue_PrepareFree(&client->output_peers_fairqueue); - - // remove flows to us - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&client->output_peers_flows)) { - struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, dest_list_node); - ASSERT(flow->dest_client == client) - peer_flow_dealloc(flow); - } - - // allow freeing priority queue flows - PacketPassPriorityQueue_PrepareFree(&client->output_priorityqueue); - - // free output peers flow - PacketPassFairQueue_Free(&client->output_peers_fairqueue); - PacketPassPriorityQueueFlow_Free(&client->output_peers_qflow); - - // free output control flow - PacketProtoFlow_Free(&client->output_control_oflow); - PacketPassPriorityQueueFlow_Free(&client->output_control_qflow); - - // free output common - PacketPassPriorityQueue_Free(&client->output_priorityqueue); - PacketStreamSender_Free(&client->output_sender); - - // free input - PacketProtoDecoder_Free(&client->input_decoder); - PacketPassInterface_Free(&client->input_interface); -} - -void client_remove (struct client_data *client) -{ - ASSERT(!client->dying) - - client_log(client, BLOG_INFO, "removing"); - - // set dying to prevent sending this client anything - client->dying = 1; - - // free I/O now, removing incoming flows - if (client->initstatus >= INITSTATUS_WAITHELLO) { - client_dealloc_io(client); - } - - // remove outgoing knows - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&client->know_out_list)) { - struct peer_know *k = UPPER_OBJECT(node, struct peer_know, from_node); - remove_know(k); - } - - // remove outgoing flows - while (node = LinkedList1_GetFirst(&client->peer_out_flows_list)) { - struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, src_list_node); - ASSERT(flow->src_client == client) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - - if (flow->have_io && PacketPassFairQueueFlow_IsBusy(&flow->qflow)) { - client_log(client, BLOG_DEBUG, "removing flow to %d later", (int)flow->dest_client->id); - peer_flow_disconnect(flow); - } else { - client_log(client, BLOG_DEBUG, "removing flow to %d now", (int)flow->dest_client->id); - peer_flow_dealloc(flow); - } - } - - // schedule job to finish removal after clients are informed - BPending_Set(&client->dying_job); - - // inform other clients that 'client' is no more - node = LinkedList1_GetFirst(&client->know_in_list); - while (node) { - LinkedList1Node *next = LinkedList1Node_Next(node); - struct peer_know *k = UPPER_OBJECT(node, struct peer_know, to_node); - uninform_know(k); - node = next; - } -} - -void client_dying_job (struct client_data *client) -{ - ASSERT(client->dying) - ASSERT(LinkedList1_IsEmpty(&client->know_in_list)) - - client_dealloc(client); - return; -} - -void client_logfunc (struct client_data *client) -{ - char addr[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->addr, addr); - - BLog_Append("client %d (%s)", (int)client->id, addr); - if (client->common_name) { - BLog_Append(" (%s)", client->common_name); - } - BLog_Append(": "); -} - -void client_log (struct client_data *client, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void client_disconnect_timer_handler (struct client_data *client) -{ - ASSERT(!client->dying) - - client_log(client, BLOG_INFO, "timed out"); - - client_remove(client); - return; -} - -void client_connection_handler (struct client_data *client, int event) -{ - ASSERT(!client->dying) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - client_log(client, BLOG_INFO, "connection closed"); - } else { - client_log(client, BLOG_INFO, "connection error"); - } - - client_remove(client); - return; -} - -void client_sslcon_handler (struct client_data *client, int event) -{ - ASSERT(options.ssl) - ASSERT(!client->dying) - ASSERT(event == BSSLCONNECTION_EVENT_UP || event == BSSLCONNECTION_EVENT_ERROR) - ASSERT(!(event == BSSLCONNECTION_EVENT_UP) || client->initstatus == INITSTATUS_HANDSHAKE) - - if (event == BSSLCONNECTION_EVENT_ERROR) { - client_log(client, BLOG_ERROR, "SSL error"); - client_remove(client); - return; - } - - // get client certificate - CERTCertificate *cert = SSL_PeerCertificate(client->ssl_prfd); - if (!cert) { - client_log(client, BLOG_ERROR, "SSL_PeerCertificate failed"); - goto fail0; - } - - // remember common name - if (!(client->common_name = CERT_GetCommonName(&cert->subject))) { - client_log(client, BLOG_NOTICE, "CERT_GetCommonName failed"); - goto fail1; - } - - // store certificate - SECItem der = cert->derCert; - if (der.len > sizeof(client->cert)) { - client_log(client, BLOG_NOTICE, "client certificate too big"); - goto fail1; - } - memcpy(client->cert, der.data, der.len); - client->cert_len = der.len; - - PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - client_log(client, BLOG_ERROR, "PORT_NewArena failed"); - goto fail1; - } - - // encode certificate - memset(&der, 0, sizeof(der)); - if (!SEC_ASN1EncodeItem(arena, &der, cert, SEC_ASN1_GET(CERT_CertificateTemplate))) { - client_log(client, BLOG_ERROR, "SEC_ASN1EncodeItem failed"); - goto fail2; - } - - // store re-encoded certificate (for compatibility with old clients) - if (der.len > sizeof(client->cert_old)) { - client_log(client, BLOG_NOTICE, "client certificate too big"); - goto fail2; - } - memcpy(client->cert_old, der.data, der.len); - client->cert_old_len = der.len; - - // init I/O chains - if (!client_init_io(client)) { - goto fail2; - } - - PORT_FreeArena(arena, PR_FALSE); - CERT_DestroyCertificate(cert); - - // set client state - client->initstatus = INITSTATUS_WAITHELLO; - - client_log(client, BLOG_INFO, "handshake complete"); - - return; - - // handle errors -fail2: - PORT_FreeArena(arena, PR_FALSE); -fail1: - CERT_DestroyCertificate(cert); -fail0: - client_remove(client); -} - -void client_decoder_handler_error (struct client_data *client) -{ - ASSERT(INITSTATUS_HASLINK(client->initstatus)) - ASSERT(!client->dying) - - client_log(client, BLOG_ERROR, "decoder error"); - - client_remove(client); - return; -} - -int client_start_control_packet (struct client_data *client, void **data, int len) -{ - ASSERT(len >= 0) - ASSERT(len <= SC_MAX_PAYLOAD) - ASSERT(!(len > 0) || data) - ASSERT(INITSTATUS_HASLINK(client->initstatus)) - ASSERT(!client->dying) - ASSERT(client->output_control_packet_len == -1) - -#ifdef SIMULATE_OUT_OF_CONTROL_BUFFER - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < SIMULATE_OUT_OF_CONTROL_BUFFER) { - client_log(client, BLOG_INFO, "out of control buffer, removing"); - client_remove(client); - return -1; - } -#endif - - // obtain location for writing the packet - if (!BufferWriter_StartPacket(client->output_control_input, &client->output_control_packet)) { - // out of buffer, kill client - client_log(client, BLOG_INFO, "out of control buffer, removing"); - client_remove(client); - return -1; - } - - client->output_control_packet_len = len; - - if (data) { - *data = client->output_control_packet + sizeof(struct sc_header); - } - - return 0; -} - -void client_end_control_packet (struct client_data *client, uint8_t type) -{ - ASSERT(INITSTATUS_HASLINK(client->initstatus)) - ASSERT(!client->dying) - ASSERT(client->output_control_packet_len >= 0) - ASSERT(client->output_control_packet_len <= SC_MAX_PAYLOAD) - - // write header - struct sc_header header; - header.type = htol8(type); - memcpy(client->output_control_packet, &header, sizeof(header)); - - // finish writing packet - BufferWriter_EndPacket(client->output_control_input, sizeof(struct sc_header) + client->output_control_packet_len); - - client->output_control_packet_len = -1; -} - -int client_send_newclient (struct client_data *client, struct client_data *nc, int relay_server, int relay_client) -{ - ASSERT(client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client->dying) - ASSERT(nc->initstatus == INITSTATUS_COMPLETE) - ASSERT(!nc->dying) - - int flags = 0; - if (relay_server) { - flags |= SCID_NEWCLIENT_FLAG_RELAY_SERVER; - } - if (relay_client) { - flags |= SCID_NEWCLIENT_FLAG_RELAY_CLIENT; - } - if (options.ssl && client->version > SC_OLDVERSION_NOSSL && nc->version > SC_OLDVERSION_NOSSL) { - flags |= SCID_NEWCLIENT_FLAG_SSL; - } - - uint8_t *cert_data = NULL; - int cert_len = 0; - if (options.ssl) { - cert_data = (client->version == SC_OLDVERSION_BROKENCERT ? nc->cert_old : nc->cert); - cert_len = (client->version == SC_OLDVERSION_BROKENCERT ? nc->cert_old_len : nc->cert_len); - } - - struct sc_server_newclient omsg; - void *pack; - if (client_start_control_packet(client, &pack, sizeof(omsg) + cert_len) < 0) { - return -1; - } - omsg.id = htol16(nc->id); - omsg.flags = htol16(flags); - memcpy(pack, &omsg, sizeof(omsg)); - if (cert_len > 0) { - memcpy((char *)pack + sizeof(omsg), cert_data, cert_len); - } - client_end_control_packet(client, SCID_NEWCLIENT); - - return 0; -} - -int client_send_endclient (struct client_data *client, peerid_t end_id) -{ - ASSERT(client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client->dying) - - struct sc_server_endclient omsg; - void *pack; - if (client_start_control_packet(client, &pack, sizeof(omsg)) < 0) { - return -1; - } - omsg.id = htol16(end_id); - memcpy(pack, &omsg, sizeof(omsg)); - client_end_control_packet(client, SCID_ENDCLIENT); - - return 0; -} - -void client_input_handler_send (struct client_data *client, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_ENC) - ASSERT(INITSTATUS_HASLINK(client->initstatus)) - ASSERT(!client->dying) - - // accept packet - PacketPassInterface_Done(&client->input_interface); - - // restart disconnect timer - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // parse header - if (data_len < sizeof(struct sc_header)) { - client_log(client, BLOG_NOTICE, "packet too short"); - client_remove(client); - return; - } - struct sc_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t type = ltoh8(header.type); - - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_PAYLOAD) - - // perform action based on packet type - switch (type) { - case SCID_KEEPALIVE: - client_log(client, BLOG_DEBUG, "received keep-alive"); - return; - case SCID_CLIENTHELLO: - process_packet_hello(client, data, data_len); - return; - case SCID_OUTMSG: - process_packet_outmsg(client, data, data_len); - return; - case SCID_RESETPEER: - process_packet_resetpeer(client, data, data_len); - return; - case SCID_ACCEPTPEER: - process_packet_acceptpeer(client, data, data_len); - return; - default: - client_log(client, BLOG_NOTICE, "unknown packet type %d, removing", (int)type); - client_remove(client); - return; - } -} - -void process_packet_hello (struct client_data *client, uint8_t *data, int data_len) -{ - if (client->initstatus != INITSTATUS_WAITHELLO) { - client_log(client, BLOG_NOTICE, "hello: not expected"); - client_remove(client); - return; - } - - if (data_len != sizeof(struct sc_client_hello)) { - client_log(client, BLOG_NOTICE, "hello: invalid length"); - client_remove(client); - return; - } - - struct sc_client_hello msg; - memcpy(&msg, data, sizeof(msg)); - client->version = ltoh16(msg.version); - - switch (client->version) { - case SC_VERSION: - case SC_OLDVERSION_NOSSL: - case SC_OLDVERSION_BROKENCERT: - break; - default: - client_log(client, BLOG_ERROR, "hello: unknown version (%d)", client->version); - client_remove(client); - return; - } - - client_log(client, BLOG_INFO, "received hello"); - - // set client state to complete - client->initstatus = INITSTATUS_COMPLETE; - - // publish client - for (LinkedList1Node *list_node = LinkedList1_GetFirst(&clients); list_node; list_node = LinkedList1Node_Next(list_node)) { - struct client_data *client2 = UPPER_OBJECT(list_node, struct client_data, list_node); - if (client2 == client || client2->initstatus != INITSTATUS_COMPLETE || client2->dying || !clients_allowed(client, client2)) { - continue; - } - - // create flow from client to client2 - struct peer_flow *flow_to = peer_flow_create(client, client2); - if (!flow_to) { - client_log(client, BLOG_ERROR, "failed to allocate flow to %d", (int)client2->id); - goto fail; - } - - // create flow from client2 to client - struct peer_flow *flow_from = peer_flow_create(client2, client); - if (!flow_from) { - client_log(client, BLOG_ERROR, "failed to allocate flow from %d", (int)client2->id); - goto fail; - } - - // set opposite flow pointers - flow_to->opposite = flow_from; - flow_from->opposite = flow_to; - - // launch pair - if (!launch_pair(flow_to)) { - return; - } - } - - // send hello - struct sc_server_hello omsg; - void *pack; - if (client_start_control_packet(client, &pack, sizeof(omsg)) < 0) { - return; - } - omsg.flags = htol16(0); - omsg.id = htol16(client->id); - omsg.clientAddr = (client->addr.type == BADDR_TYPE_IPV4 ? client->addr.ipv4.ip : hton32(0)); - memcpy(pack, &omsg, sizeof(omsg)); - client_end_control_packet(client, SCID_SERVERHELLO); - - return; - -fail: - client_remove(client); -} - -void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_len) -{ - if (client->initstatus != INITSTATUS_COMPLETE) { - client_log(client, BLOG_NOTICE, "outmsg: not expected"); - client_remove(client); - return; - } - - if (data_len < sizeof(struct sc_client_outmsg)) { - client_log(client, BLOG_NOTICE, "outmsg: wrong size"); - client_remove(client); - return; - } - - struct sc_client_outmsg msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.clientid); - int payload_size = data_len - sizeof(struct sc_client_outmsg); - - if (payload_size > SC_MAX_MSGLEN) { - client_log(client, BLOG_NOTICE, "outmsg: too large payload"); - client_remove(client); - return; - } - - uint8_t *payload = data + sizeof(struct sc_client_outmsg); - - // lookup flow to destination client - struct peer_flow *flow = find_flow(client, id); - if (!flow) { - client_log(client, BLOG_INFO, "no flow for message to %d", (int)id); - return; - } - - // if pair is resetting, ignore message - if (flow->resetting || flow->opposite->resetting) { - client_log(client, BLOG_INFO, "pair is resetting; not forwarding message to %d", (int)id); - return; - } - - // if sending client hasn't accepted yet, ignore message - if (!flow->accepted) { - client_log(client, BLOG_INFO, "client hasn't accepted; not forwarding message to %d", (int)id); - return; - } - -#ifdef SIMULATE_OUT_OF_FLOW_BUFFER - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < SIMULATE_OUT_OF_FLOW_BUFFER) { - client_log(client, BLOG_WARNING, "simulating error; resetting to %d", (int)flow->dest_client->id); - peer_flow_start_reset(flow); - return; - } -#endif - - // send packet - struct sc_server_inmsg omsg; - void *pack; - if (!peer_flow_start_packet(flow, &pack, sizeof(omsg) + payload_size)) { - // out of buffer, reset these two clients - client_log(client, BLOG_WARNING, "out of buffer; resetting to %d", (int)flow->dest_client->id); - peer_flow_start_reset(flow); - return; - } - omsg.clientid = htol16(client->id); - memcpy(pack, &omsg, sizeof(omsg)); - memcpy((char *)pack + sizeof(omsg), payload, payload_size); - peer_flow_end_packet(flow, SCID_INMSG); -} - -void process_packet_resetpeer (struct client_data *client, uint8_t *data, int data_len) -{ - if (client->initstatus != INITSTATUS_COMPLETE) { - client_log(client, BLOG_NOTICE, "resetpeer: not expected"); - client_remove(client); - return; - } - - if (data_len != sizeof(struct sc_client_resetpeer)) { - client_log(client, BLOG_NOTICE, "resetpeer: wrong size"); - client_remove(client); - return; - } - - struct sc_client_resetpeer msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.clientid); - - // lookup flow to destination client - struct peer_flow *flow = find_flow(client, id); - if (!flow) { - client_log(client, BLOG_INFO, "no flow for reset to %d", (int)id); - return; - } - - // if pair is resetting, ignore message - if (flow->resetting || flow->opposite->resetting) { - client_log(client, BLOG_INFO, "pair is resetting; not resetting to %d", (int)id); - return; - } - - // if sending client hasn't accepted yet, ignore message - if (!flow->accepted) { - client_log(client, BLOG_INFO, "client hasn't accepted; not resetting to %d", (int)id); - return; - } - - client_log(client, BLOG_WARNING, "resetting to %d", (int)flow->dest_client->id); - - // reset clients - peer_flow_start_reset(flow); -} - -void process_packet_acceptpeer (struct client_data *client, uint8_t *data, int data_len) -{ - if (client->initstatus != INITSTATUS_COMPLETE) { - client_log(client, BLOG_NOTICE, "acceptpeer: not expected"); - client_remove(client); - return; - } - - if (data_len != sizeof(struct sc_client_acceptpeer)) { - client_log(client, BLOG_NOTICE, "acceptpeer: wrong size"); - client_remove(client); - return; - } - - struct sc_client_acceptpeer msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.clientid); - - // lookup flow to destination client - struct peer_flow *flow = find_flow(client, id); - if (!flow) { - // the specified client has probably gone away but the sending client didn't know - // that yet; this is expected - client_log(client, BLOG_INFO, "acceptpeer: no flow to %d", (int)id); - return; - } - - // client can only accept once - if (flow->accepted) { - // the previous accept is probably from an old client with the same ID as this one; - // this is bad, disconnect client - client_log(client, BLOG_ERROR, "acceptpeer: already accepted to %d", (int)id); - client_remove(client); - return; - } - - client_log(client, BLOG_INFO, "accepted %d", (int)id); - - // set accepted - flow->accepted = 1; - - // if pair is resetting, continue - if (flow->resetting) { - peer_flow_drive_reset(flow); - } else if (flow->opposite->resetting) { - peer_flow_drive_reset(flow->opposite); - } -} - -struct peer_flow * peer_flow_create (struct client_data *src_client, struct client_data *dest_client) -{ - ASSERT(src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!src_client->dying) - ASSERT(dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!dest_client->dying) - ASSERT(!find_flow(src_client, dest_client->id)) - - // allocate flow structure - struct peer_flow *flow = (struct peer_flow *)malloc(sizeof(*flow)); - if (!flow) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set source and destination - flow->src_client = src_client; - flow->dest_client = dest_client; - flow->dest_client_id = dest_client->id; - - // add to source list and tree - LinkedList1_Append(&flow->src_client->peer_out_flows_list, &flow->src_list_node); - ASSERT_EXECUTE(BAVL_Insert(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node, NULL)) - - // add to destination client list - LinkedList1_Append(&flow->dest_client->output_peers_flows, &flow->dest_list_node); - - // have no I/O - flow->have_io = 0; - - // init reset timer - BTimer_Init(&flow->reset_timer, CLIENT_RESET_TIME, (BTimer_handler)peer_flow_reset_timer_handler, flow); - - return flow; - -fail0: - return NULL; -} - -void peer_flow_dealloc (struct peer_flow *flow) -{ - if (flow->have_io) { PacketPassFairQueueFlow_AssertFree(&flow->qflow); } - - // free reset timer - BReactor_RemoveTimer(&ss, &flow->reset_timer); - - // free I/O - if (flow->have_io) { - peer_flow_free_io(flow); - } - - // remove from destination client list - LinkedList1_Remove(&flow->dest_client->output_peers_flows, &flow->dest_list_node); - - // remove from source list and hash table - if (flow->src_client) { - BAVL_Remove(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node); - LinkedList1_Remove(&flow->src_client->peer_out_flows_list, &flow->src_list_node); - } - - // free memory - free(flow); -} - -int peer_flow_init_io (struct peer_flow *flow) -{ - ASSERT(!flow->have_io) - - // init queue flow - PacketPassFairQueueFlow_Init(&flow->qflow, &flow->dest_client->output_peers_fairqueue); - - // init PacketProtoFlow - if (!PacketProtoFlow_Init( - &flow->oflow, SC_MAX_ENC, CLIENT_PEER_FLOW_BUFFER_MIN_PACKETS, - PacketPassFairQueueFlow_GetInput(&flow->qflow), BReactor_PendingGroup(&ss) - )) { - BLog(BLOG_ERROR, "PacketProtoFlow_Init failed"); - goto fail1; - } - flow->input = PacketProtoFlow_GetInput(&flow->oflow); - - // set no packet - flow->packet_len = -1; - - // set have I/O - flow->have_io = 1; - - return 1; - -fail1: - PacketPassFairQueueFlow_Free(&flow->qflow); - return 0; -} - -void peer_flow_free_io (struct peer_flow *flow) -{ - ASSERT(flow->have_io) - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - - // free PacketProtoFlow - PacketProtoFlow_Free(&flow->oflow); - - // free queue flow - PacketPassFairQueueFlow_Free(&flow->qflow); - - // set have no I/O - flow->have_io = 0; -} - -void peer_flow_disconnect (struct peer_flow *flow) -{ - ASSERT(flow->src_client) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->have_io) - ASSERT(PacketPassFairQueueFlow_IsBusy(&flow->qflow)) - - // stop reset timer - BReactor_RemoveTimer(&ss, &flow->reset_timer); - - // remove from source list and hash table - BAVL_Remove(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node); - LinkedList1_Remove(&flow->src_client->peer_out_flows_list, &flow->src_list_node); - - // set no source - flow->src_client = NULL; - - // set busy handler - PacketPassFairQueueFlow_SetBusyHandler(&flow->qflow, (PacketPassFairQueue_handler_busy)peer_flow_handler_canremove, flow); -} - -int peer_flow_start_packet (struct peer_flow *flow, void **data, int len) -{ - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->src_client->dying) - ASSERT(!flow->resetting) - ASSERT(!flow->opposite->resetting) - ASSERT(flow->have_io) - ASSERT(flow->packet_len == -1) - ASSERT(len >= 0) - ASSERT(len <= SC_MAX_PAYLOAD) - ASSERT(!(len > 0) || data) - - // obtain location for writing the packet - if (!BufferWriter_StartPacket(flow->input, &flow->packet)) { - return 0; - } - - // remember packet length - flow->packet_len = len; - - if (data) { - *data = flow->packet + sizeof(struct sc_header); - } - return 1; -} - -void peer_flow_end_packet (struct peer_flow *flow, uint8_t type) -{ - ASSERT(flow->have_io) - ASSERT(flow->packet_len >= 0) - ASSERT(flow->packet_len <= SC_MAX_PAYLOAD) - - // write header - struct sc_header header; - header.type = type; - memcpy(flow->packet, &header, sizeof(header)); - - // finish writing packet - BufferWriter_EndPacket(flow->input, sizeof(struct sc_header) + flow->packet_len); - - // set have no packet - flow->packet_len = -1; -} - -void peer_flow_handler_canremove (struct peer_flow *flow) -{ - ASSERT(!flow->src_client) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->have_io) - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - - client_log(flow->dest_client, BLOG_DEBUG, "removing old flow"); - - peer_flow_dealloc(flow); - return; -} - -void peer_flow_start_reset (struct peer_flow *flow) -{ - ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->src_client->dying) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(!flow->resetting) - ASSERT(!flow->opposite->resetting) - ASSERT(flow->have_io) - ASSERT(flow->opposite->have_io) - - client_log(flow->src_client, BLOG_INFO, "starting reset to %d", (int)flow->dest_client->id); - - // set resetting - flow->resetting = 1; - - peer_flow_drive_reset(flow); -} - -void peer_flow_drive_reset (struct peer_flow *flow) -{ - ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->src_client->dying) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->resetting) - ASSERT(!flow->opposite->resetting) - ASSERT(!BTimer_IsRunning(&flow->reset_timer)) - - // try to free I/O - if (flow->have_io) { - if (PacketPassFairQueueFlow_IsBusy(&flow->qflow)) { - PacketPassFairQueueFlow_SetBusyHandler(&flow->qflow, (PacketPassFairQueue_handler_busy)peer_flow_reset_qflow_handler_busy, flow); - } else { - peer_flow_free_io(flow); - } - } - - // try to free opposite I/O - if (flow->opposite->have_io) { - if (PacketPassFairQueueFlow_IsBusy(&flow->opposite->qflow)) { - PacketPassFairQueueFlow_SetBusyHandler(&flow->opposite->qflow, (PacketPassFairQueue_handler_busy)peer_flow_reset_qflow_handler_busy, flow->opposite); - } else { - peer_flow_free_io(flow->opposite); - } - } - - // if we still got some I/O, or some client hasn't accepted yet, wait - if (flow->have_io || flow->opposite->have_io || !flow->accepted || !flow->opposite->accepted) { - return; - } - - // set reset timer - BReactor_SetTimer(&ss, &flow->reset_timer); -} - -void peer_flow_reset_qflow_handler_busy (struct peer_flow *flow) -{ - ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->src_client->dying) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->resetting || flow->opposite->resetting) - ASSERT(flow->have_io) - ASSERT(!PacketPassFairQueueFlow_IsBusy(&flow->qflow)) - - if (flow->resetting) { - peer_flow_drive_reset(flow); - } else { - peer_flow_drive_reset(flow->opposite); - } -} - -void peer_flow_reset_timer_handler (struct peer_flow *flow) -{ - ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->src_client->dying) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - ASSERT(flow->resetting) - ASSERT(!flow->opposite->resetting) - ASSERT(!flow->have_io) - ASSERT(!flow->opposite->have_io) - ASSERT(flow->accepted) - ASSERT(flow->opposite->accepted) - - client_log(flow->src_client, BLOG_INFO, "finally resetting to %d", (int)flow->dest_client->id); - - struct peer_know *know = flow->know; - struct peer_know *know_opposite = flow->opposite->know; - - // launch pair - if (!launch_pair(flow)) { - return; - } - - // remove old knows - uninform_know(know); - uninform_know(know_opposite); -} - -peerid_t new_client_id (void) -{ - ASSERT(clients_num < options.max_clients) - - for (int i = 0; i < options.max_clients; i++) { - peerid_t id = clients_nextid++; - if (!find_client_by_id(id)) { - return id; - } - } - - ASSERT(0) - return 42; -} - -struct client_data * find_client_by_id (peerid_t id) -{ - BAVLNode *node; - if (!(node = BAVL_LookupExact(&clients_tree, &id))) { - return NULL; - } - - return UPPER_OBJECT(node, struct client_data, tree_node); -} - -int clients_allowed (struct client_data *client1, struct client_data *client2) -{ - ASSERT(client1->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client1->dying) - ASSERT(client2->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client2->dying) - - if (!options.comm_predicate) { - return 1; - } - - // set values to compare against - comm_predicate_p1name = (client1->common_name ? client1->common_name : ""); - comm_predicate_p2name = (client2->common_name ? client2->common_name : ""); - BAddr_GetIPAddr(&client1->addr, &comm_predicate_p1addr); - BAddr_GetIPAddr(&client2->addr, &comm_predicate_p2addr); - - // evaluate predicate - int res = BPredicate_Eval(&comm_predicate); - if (res < 0) { - return 0; - } - - return res; -} - -int comm_predicate_func_p1name_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - return (!strcmp(arg, comm_predicate_p1name)); -} - -int comm_predicate_func_p2name_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - return (!strcmp(arg, comm_predicate_p2name)); -} - -int comm_predicate_func_p1addr_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - BIPAddr addr; - if (!BIPAddr_Resolve(&addr, arg, 1)) { - BLog(BLOG_WARNING, "failed to parse address"); - return -1; - } - - return BIPAddr_Compare(&addr, &comm_predicate_p1addr); -} - -int comm_predicate_func_p2addr_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - BIPAddr addr; - if (!BIPAddr_Resolve(&addr, arg, 1)) { - BLog(BLOG_WARNING, "failed to parse address"); - return -1; - } - - return BIPAddr_Compare(&addr, &comm_predicate_p2addr); -} - -int relay_allowed (struct client_data *client, struct client_data *relay) -{ - if (!options.relay_predicate) { - return 0; - } - - // set values to compare against - relay_predicate_pname = (client->common_name ? client->common_name : ""); - relay_predicate_rname = (relay->common_name ? relay->common_name : ""); - BAddr_GetIPAddr(&client->addr, &relay_predicate_paddr); - BAddr_GetIPAddr(&relay->addr, &relay_predicate_raddr); - - // evaluate predicate - int res = BPredicate_Eval(&relay_predicate); - if (res < 0) { - return 0; - } - - return res; -} - -int relay_predicate_func_pname_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - return (!strcmp(arg, relay_predicate_pname)); -} - -int relay_predicate_func_rname_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - return (!strcmp(arg, relay_predicate_rname)); -} - -int relay_predicate_func_paddr_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - BIPAddr addr; - if (!BIPAddr_Resolve(&addr, arg, 1)) { - BLog(BLOG_ERROR, "paddr: failed to parse address"); - return -1; - } - - return BIPAddr_Compare(&addr, &relay_predicate_paddr); -} - -int relay_predicate_func_raddr_cb (void *user, void **args) -{ - char *arg = (char *)args[0]; - - BIPAddr addr; - if (!BIPAddr_Resolve(&addr, arg, 1)) { - BLog(BLOG_ERROR, "raddr: failed to parse address"); - return -1; - } - - return BIPAddr_Compare(&addr, &relay_predicate_raddr); -} - -int peerid_comparator (void *unused, peerid_t *p1, peerid_t *p2) -{ - return B_COMPARE(*p1, *p2); -} - -struct peer_know * create_know (struct client_data *from, struct client_data *to, int relay_server, int relay_client) -{ - ASSERT(from->initstatus == INITSTATUS_COMPLETE) - ASSERT(!from->dying) - ASSERT(to->initstatus == INITSTATUS_COMPLETE) - ASSERT(!to->dying) - - // allocate structure - struct peer_know *k = (struct peer_know *)malloc(sizeof(*k)); - if (!k) { - return NULL; - } - - // init arguments - k->from = from; - k->to = to; - k->relay_server = relay_server; - k->relay_client = relay_client; - - // append to lists - LinkedList1_Append(&from->know_out_list, &k->from_node); - LinkedList1_Append(&to->know_in_list, &k->to_node); - - // init and set inform job to inform client 'from' about client 'to' - BPending_Init(&k->inform_job, BReactor_PendingGroup(&ss), (BPending_handler)know_inform_job_handler, k); - BPending_Set(&k->inform_job); - - // init uninform job - BPending_Init(&k->uninform_job, BReactor_PendingGroup(&ss), (BPending_handler)know_uninform_job_handler, k); - - return k; -} - -void remove_know (struct peer_know *k) -{ - // free uninform job - BPending_Free(&k->uninform_job); - - // free inform job - BPending_Free(&k->inform_job); - - // remove from lists - LinkedList1_Remove(&k->to->know_in_list, &k->to_node); - LinkedList1_Remove(&k->from->know_out_list, &k->from_node); - - // free structure - free(k); -} - -void know_inform_job_handler (struct peer_know *k) -{ - ASSERT(!k->from->dying) - ASSERT(!k->to->dying) - - client_send_newclient(k->from, k->to, k->relay_server, k->relay_client); - return; -} - -void uninform_know (struct peer_know *k) -{ - ASSERT(!k->from->dying) - - // if 'from' has not been informed about 'to' yet, remove know, otherwise - // schedule informing 'from' that 'to' is no more - if (BPending_IsSet(&k->inform_job)) { - remove_know(k); - } else { - BPending_Set(&k->uninform_job); - } -} - -void know_uninform_job_handler (struct peer_know *k) -{ - ASSERT(!k->from->dying) - ASSERT(!BPending_IsSet(&k->inform_job)) - - struct client_data *from = k->from; - struct client_data *to = k->to; - - // remove know - remove_know(k); - - // uninform - client_send_endclient(from, to->id); -} - -int launch_pair (struct peer_flow *flow_to) -{ - struct client_data *client = flow_to->src_client; - struct client_data *client2 = flow_to->dest_client; - ASSERT(client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client->dying) - ASSERT(client2->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client2->dying) - ASSERT(!flow_to->have_io) - ASSERT(!flow_to->opposite->have_io) - ASSERT(!BTimer_IsRunning(&flow_to->reset_timer)) - ASSERT(!BTimer_IsRunning(&flow_to->opposite->reset_timer)) - - // init I/O - if (!peer_flow_init_io(flow_to)) { - goto fail; - } - - // init opposite I/O - if (!peer_flow_init_io(flow_to->opposite)) { - goto fail; - } - - // determine relay relations - int relay_to = relay_allowed(client, client2); - int relay_from = relay_allowed(client2, client); - - // create know to - struct peer_know *know_to = create_know(client, client2, relay_to, relay_from); - if (!know_to) { - client_log(client, BLOG_ERROR, "failed to allocate know to %d", (int)client2->id); - goto fail; - } - - // create know from - struct peer_know *know_from = create_know(client2, client, relay_from, relay_to); - if (!know_from) { - client_log(client, BLOG_ERROR, "failed to allocate know from %d", (int)client2->id); - goto fail; - } - - // set know pointers in flows - flow_to->know = know_to; - flow_to->opposite->know = know_from; - - // set not accepted, or assume accepted for old version - flow_to->accepted = (flow_to->src_client->version <= SC_OLDVERSION_NOSSL); - flow_to->opposite->accepted = (flow_to->opposite->src_client->version <= SC_OLDVERSION_NOSSL); - - // set not resetting - flow_to->resetting = 0; - flow_to->opposite->resetting = 0; - - return 1; - -fail: - client_remove(client); - return 0; -} - -struct peer_flow * find_flow (struct client_data *client, peerid_t dest_id) -{ - ASSERT(client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client->dying) - - BAVLNode *node = BAVL_LookupExact(&client->peer_out_flows_tree, &dest_id); - if (!node) { - return NULL; - } - struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, src_tree_node); - - ASSERT(flow->dest_client->id == dest_id) - ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!flow->dest_client->dying) - - return flow; -} diff --git a/external/badvpn_dns/server/server.h b/external/badvpn_dns/server/server.h deleted file mode 100644 index 66103a9..0000000 --- a/external/badvpn_dns/server/server.h +++ /dev/null @@ -1,186 +0,0 @@ -/** - * @file server.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> - -#include <protocol/scproto.h> -#include <structure/LinkedList1.h> -#include <structure/BAVL.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketPassPriorityQueue.h> -#include <flow/PacketPassFairQueue.h> -#include <flow/PacketProtoFlow.h> -#include <system/BReactor.h> -#include <system/BConnection.h> -#include <nspr_support/BSSLConnection.h> - -// name of the program -#define PROGRAM_NAME "server" - -// maxiumum number of connected clients. Must be <=2^16. -#define DEFAULT_MAX_CLIENTS 30 -// client output control flow buffer size in packets -// it must hold: initdata, newclient's, endclient's (if other peers die when informing them) -// make it big enough to hold the initial packet burst (initdata, newclient's), -#define CLIENT_CONTROL_BUFFER_MIN_PACKETS (1 + 2*(MAX_CLIENTS - 1)) -// size of client-to-client buffers in packets -#define CLIENT_PEER_FLOW_BUFFER_MIN_PACKETS 10 -// after how long of not hearing anything from the client we disconnect it -#define CLIENT_NO_DATA_TIME_LIMIT 30000 -// SO_SNDBFUF socket option for clients -#define CLIENT_DEFAULT_SOCKET_SNDBUF 16384 -// reset time when a buffer runs out or when we get the resetpeer message -#define CLIENT_RESET_TIME 30000 - -// maxiumum listen addresses -#define MAX_LISTEN_ADDRS 16 - -//#define SIMULATE_OUT_OF_CONTROL_BUFFER 20 -//#define SIMULATE_OUT_OF_FLOW_BUFFER 100 - - -// performing SSL handshake -#define INITSTATUS_HANDSHAKE 1 -// waiting for clienthello -#define INITSTATUS_WAITHELLO 2 -// initialisation was complete -#define INITSTATUS_COMPLETE 3 - -#define INITSTATUS_HASLINK(status) ((status) == INITSTATUS_WAITHELLO || (status) == INITSTATUS_COMPLETE) - -struct client_data; -struct peer_know; - -struct peer_flow { - // source client - struct client_data *src_client; - // destination client - struct client_data *dest_client; - peerid_t dest_client_id; - // node in source client hash table (by destination), only when src_client != NULL - BAVLNode src_tree_node; - // node in source client list, only when src_client != NULL - LinkedList1Node src_list_node; - // node in destination client list - LinkedList1Node dest_list_node; - // output chain - int have_io; - PacketPassFairQueueFlow qflow; - PacketProtoFlow oflow; - BufferWriter *input; - int packet_len; - uint8_t *packet; - // reset timer - BTimer reset_timer; - // opposite flow - struct peer_flow *opposite; - // pair data - struct peer_know *know; - int accepted; - int resetting; -}; - -struct peer_know { - struct client_data *from; - struct client_data *to; - int relay_server; - int relay_client; - LinkedList1Node from_node; - LinkedList1Node to_node; - BPending inform_job; - BPending uninform_job; -}; - -struct client_data { - // socket - BConnection con; - BAddr addr; - - // SSL connection, if using SSL - PRFileDesc bottom_prfd; - PRFileDesc *ssl_prfd; - BSSLConnection sslcon; - - // initialization state - int initstatus; - - // client data if using SSL - uint8_t cert[SCID_NEWCLIENT_MAX_CERT_LEN]; - int cert_len; - uint8_t cert_old[SCID_NEWCLIENT_MAX_CERT_LEN]; - int cert_old_len; - char *common_name; - - // client version - int version; - - // no data timer - BTimer disconnect_timer; - - // client ID - peerid_t id; - - // node in clients linked list - LinkedList1Node list_node; - // node in clients tree (by ID) - BAVLNode tree_node; - - // knowledge lists - LinkedList1 know_out_list; - LinkedList1 know_in_list; - - // flows from us - LinkedList1 peer_out_flows_list; - BAVL peer_out_flows_tree; - - // whether it's being removed - int dying; - BPending dying_job; - - // input - PacketProtoDecoder input_decoder; - PacketPassInterface input_interface; - - // output common - PacketStreamSender output_sender; - PacketPassPriorityQueue output_priorityqueue; - - // output control flow - PacketPassPriorityQueueFlow output_control_qflow; - PacketProtoFlow output_control_oflow; - BufferWriter *output_control_input; - int output_control_packet_len; - uint8_t *output_control_packet; - - // output peers flow - PacketPassPriorityQueueFlow output_peers_qflow; - PacketPassFairQueue output_peers_fairqueue; - LinkedList1 output_peers_flows; -}; diff --git a/external/badvpn_dns/server_connection/CMakeLists.txt b/external/badvpn_dns/server_connection/CMakeLists.txt deleted file mode 100644 index 4ae12ad..0000000 --- a/external/badvpn_dns/server_connection/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(SERVERCONNECTION_SOURCES - ServerConnection.c - SCKeepaliveSource.c -) -badvpn_add_library(server_conection "system;flow;flowextra;nspr_support" "${NSPR_LIBRARIES};${NSS_LIBRARIES}" "${SERVERCONNECTION_SOURCES}") diff --git a/external/badvpn_dns/server_connection/SCKeepaliveSource.c b/external/badvpn_dns/server_connection/SCKeepaliveSource.c deleted file mode 100644 index 7c6469a..0000000 --- a/external/badvpn_dns/server_connection/SCKeepaliveSource.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file SCKeepaliveSource.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <protocol/scproto.h> -#include <misc/byteorder.h> - -#include "SCKeepaliveSource.h" - -static void output_handler_recv (SCKeepaliveSource *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - struct sc_header header; - header.type = htol8(SCID_KEEPALIVE); - memcpy(data, &header, sizeof(header)); - - PacketRecvInterface_Done(&o->output, sizeof(struct sc_header)); -} - -void SCKeepaliveSource_Init (SCKeepaliveSource *o, BPendingGroup *pg) -{ - // init output - PacketRecvInterface_Init(&o->output, sizeof(struct sc_header), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void SCKeepaliveSource_Free (SCKeepaliveSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * SCKeepaliveSource_GetOutput (SCKeepaliveSource *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/server_connection/SCKeepaliveSource.h b/external/badvpn_dns/server_connection/SCKeepaliveSource.h deleted file mode 100644 index 1c0951e..0000000 --- a/external/badvpn_dns/server_connection/SCKeepaliveSource.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file SCKeepaliveSource.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketRecvInterface} source which provides SCProto keepalive packets. - */ - -#ifndef BADVPN_SCKEEPALIVESOURCE_H -#define BADVPN_SCKEEPALIVESOURCE_H - -#include <base/DebugObject.h> -#include <flow/PacketRecvInterface.h> - -/** - * A {@link PacketRecvInterface} source which provides SCProto keepalive packets. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface output; -} SCKeepaliveSource; - -/** - * Initializes the object. - * - * @param o the object - * @param pg pending group - */ -void SCKeepaliveSource_Init (SCKeepaliveSource *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SCKeepaliveSource_Free (SCKeepaliveSource *o); - -/** - * Returns the output interface. - * The MTU of the output interface will be sizeof(struct sc_header). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SCKeepaliveSource_GetOutput (SCKeepaliveSource *o); - -#endif diff --git a/external/badvpn_dns/server_connection/ServerConnection.c b/external/badvpn_dns/server_connection/ServerConnection.c deleted file mode 100644 index f07e224..0000000 --- a/external/badvpn_dns/server_connection/ServerConnection.c +++ /dev/null @@ -1,669 +0,0 @@ -/** - * @file ServerConnection.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <stddef.h> - -#include <misc/debug.h> -#include <misc/strdup.h> -#include <base/BLog.h> - -#include <server_connection/ServerConnection.h> - -#include <generated/blog_channel_ServerConnection.h> - -#define STATE_CONNECTING 1 -#define STATE_WAITINIT 2 -#define STATE_COMPLETE 3 - -static void report_error (ServerConnection *o); -static void connector_handler (ServerConnection *o, int is_error); -static void pending_handler (ServerConnection *o); -static SECStatus client_auth_data_callback (ServerConnection *o, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey); -static void connection_handler (ServerConnection *o, int event); -static void sslcon_handler (ServerConnection *o, int event); -static void decoder_handler_error (ServerConnection *o); -static void input_handler_send (ServerConnection *o, uint8_t *data, int data_len); -static void packet_hello (ServerConnection *o, uint8_t *data, int data_len); -static void packet_newclient (ServerConnection *o, uint8_t *data, int data_len); -static void packet_endclient (ServerConnection *o, uint8_t *data, int data_len); -static void packet_inmsg (ServerConnection *o, uint8_t *data, int data_len); -static int start_packet (ServerConnection *o, void **data, int len); -static void end_packet (ServerConnection *o, uint8_t type); -static void newclient_job_handler (ServerConnection *o); - -void report_error (ServerConnection *o) -{ - DEBUGERROR(&o->d_err, o->handler_error(o->user)) -} - -void connector_handler (ServerConnection *o, int is_error) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == STATE_CONNECTING) - ASSERT(!o->buffers_released) - - // check connection attempt result - if (is_error) { - BLog(BLOG_ERROR, "connection failed"); - goto fail0; - } - - BLog(BLOG_NOTICE, "connected"); - - // init connection - if (!BConnection_Init(&o->con, BConnection_source_connector(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - // init connection interfaces - BConnection_SendAsync_Init(&o->con); - BConnection_RecvAsync_Init(&o->con); - - StreamPassInterface *send_iface = BConnection_SendAsync_GetIf(&o->con); - StreamRecvInterface *recv_iface = BConnection_RecvAsync_GetIf(&o->con); - - if (o->have_ssl) { - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&o->bottom_prfd, send_iface, recv_iface, o->twd, o->ssl_flags)) { - BLog(BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail0a; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(o->ssl_prfd = SSL_ImportFD(NULL, &o->bottom_prfd))) { - BLog(BLOG_ERROR, "SSL_ImportFD failed"); - ASSERT_FORCE(PR_Close(&o->bottom_prfd) == PR_SUCCESS) - goto fail0a; - } - - // set client mode - if (SSL_ResetHandshake(o->ssl_prfd, PR_FALSE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail1; - } - - // set server name - if (SSL_SetURL(o->ssl_prfd, o->server_name) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_SetURL failed"); - goto fail1; - } - - // set client certificate callback - if (SSL_GetClientAuthDataHook(o->ssl_prfd, (SSLGetClientAuthData)client_auth_data_callback, o) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail1; - } - - // init BSSLConnection - BSSLConnection_Init(&o->sslcon, o->ssl_prfd, 0, BReactor_PendingGroup(o->reactor), o, (BSSLConnection_handler)sslcon_handler); - - send_iface = BSSLConnection_GetSendIf(&o->sslcon); - recv_iface = BSSLConnection_GetRecvIf(&o->sslcon); - } - - // init input chain - PacketPassInterface_Init(&o->input_interface, SC_MAX_ENC, (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(o->reactor)); - if (!PacketProtoDecoder_Init(&o->input_decoder, recv_iface, &o->input_interface, BReactor_PendingGroup(o->reactor), o, (PacketProtoDecoder_handler_error)decoder_handler_error)) { - BLog(BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail2; - } - - // set job to send hello - // this needs to be in here because hello sending must be done after sending started (so we can write into the send buffer), - // but before receiving started (so we don't get into conflict with the user sending packets) - BPending_Init(&o->start_job, BReactor_PendingGroup(o->reactor), (BPending_handler)pending_handler, o); - BPending_Set(&o->start_job); - - // init keepalive output branch - SCKeepaliveSource_Init(&o->output_ka_zero, BReactor_PendingGroup(o->reactor)); - PacketProtoEncoder_Init(&o->output_ka_encoder, SCKeepaliveSource_GetOutput(&o->output_ka_zero), BReactor_PendingGroup(o->reactor)); - - // init output common - - // init sender - PacketStreamSender_Init(&o->output_sender, send_iface, PACKETPROTO_ENCLEN(SC_MAX_ENC), BReactor_PendingGroup(o->reactor)); - - // init keepalives - if (!KeepaliveIO_Init(&o->output_keepaliveio, o->reactor, PacketStreamSender_GetInput(&o->output_sender), PacketProtoEncoder_GetOutput(&o->output_ka_encoder), o->keepalive_interval)) { - BLog(BLOG_ERROR, "KeepaliveIO_Init failed"); - goto fail3; - } - - // init queue - PacketPassPriorityQueue_Init(&o->output_queue, KeepaliveIO_GetInput(&o->output_keepaliveio), BReactor_PendingGroup(o->reactor), 0); - - // init output local flow - - // init queue flow - PacketPassPriorityQueueFlow_Init(&o->output_local_qflow, &o->output_queue, 0); - - // init PacketProtoFlow - if (!PacketProtoFlow_Init(&o->output_local_oflow, SC_MAX_ENC, o->buffer_size, PacketPassPriorityQueueFlow_GetInput(&o->output_local_qflow), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "PacketProtoFlow_Init failed"); - goto fail4; - } - o->output_local_if = PacketProtoFlow_GetInput(&o->output_local_oflow); - - // have no output packet - o->output_local_packet_len = -1; - - // init output user flow - PacketPassPriorityQueueFlow_Init(&o->output_user_qflow, &o->output_queue, 1); - - // update state - o->state = STATE_WAITINIT; - - return; - -fail4: - PacketPassPriorityQueueFlow_Free(&o->output_local_qflow); - PacketPassPriorityQueue_Free(&o->output_queue); - KeepaliveIO_Free(&o->output_keepaliveio); -fail3: - PacketStreamSender_Free(&o->output_sender); - PacketProtoEncoder_Free(&o->output_ka_encoder); - SCKeepaliveSource_Free(&o->output_ka_zero); - BPending_Free(&o->start_job); - PacketProtoDecoder_Free(&o->input_decoder); -fail2: - PacketPassInterface_Free(&o->input_interface); - if (o->have_ssl) { - BSSLConnection_Free(&o->sslcon); -fail1: - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) - } -fail0a: - BConnection_RecvAsync_Free(&o->con); - BConnection_SendAsync_Free(&o->con); - BConnection_Free(&o->con); -fail0: - // report error - report_error(o); -} - -void pending_handler (ServerConnection *o) -{ - ASSERT(o->state == STATE_WAITINIT) - ASSERT(!o->buffers_released) - DebugObject_Access(&o->d_obj); - - // send hello - struct sc_client_hello omsg; - void *packet; - if (!start_packet(o, &packet, sizeof(omsg))) { - BLog(BLOG_ERROR, "no buffer for hello"); - report_error(o); - return; - } - omsg.version = htol16(SC_VERSION); - memcpy(packet, &omsg, sizeof(omsg)); - end_packet(o, SCID_CLIENTHELLO); -} - -SECStatus client_auth_data_callback (ServerConnection *o, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) -{ - ASSERT(o->have_ssl) - DebugObject_Access(&o->d_obj); - - CERTCertificate *newcert; - if (!(newcert = CERT_DupCertificate(o->client_cert))) { - return SECFailure; - } - - SECKEYPrivateKey *newkey; - if (!(newkey = SECKEY_CopyPrivateKey(o->client_key))) { - CERT_DestroyCertificate(newcert); - return SECFailure; - } - - *pRetCert = newcert; - *pRetKey = newkey; - return SECSuccess; -} - -void connection_handler (ServerConnection *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(!o->buffers_released) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - BLog(BLOG_INFO, "connection closed"); - } else { - BLog(BLOG_INFO, "connection error"); - } - - report_error(o); - return; -} - -void sslcon_handler (ServerConnection *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_ssl) - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(!o->buffers_released) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - BLog(BLOG_ERROR, "SSL error"); - - report_error(o); - return; -} - -void decoder_handler_error (ServerConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(!o->buffers_released) - - BLog(BLOG_ERROR, "decoder error"); - - report_error(o); - return; -} - -void input_handler_send (ServerConnection *o, uint8_t *data, int data_len) -{ - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(!o->buffers_released) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_ENC) - DebugObject_Access(&o->d_obj); - - // accept packet - PacketPassInterface_Done(&o->input_interface); - - // parse header - if (data_len < sizeof(struct sc_header)) { - BLog(BLOG_ERROR, "packet too short (no sc header)"); - report_error(o); - return; - } - struct sc_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t type = ltoh8(header.type); - - // call appropriate handler based on packet type - switch (type) { - case SCID_SERVERHELLO: - packet_hello(o, data, data_len); - return; - case SCID_NEWCLIENT: - packet_newclient(o, data, data_len); - return; - case SCID_ENDCLIENT: - packet_endclient(o, data, data_len); - return; - case SCID_INMSG: - packet_inmsg(o, data, data_len); - return; - default: - BLog(BLOG_ERROR, "unknown packet type %d", (int)type); - report_error(o); - return; - } -} - -void packet_hello (ServerConnection *o, uint8_t *data, int data_len) -{ - if (o->state != STATE_WAITINIT) { - BLog(BLOG_ERROR, "hello: not expected"); - report_error(o); - return; - } - - if (data_len != sizeof(struct sc_server_hello)) { - BLog(BLOG_ERROR, "hello: invalid length"); - report_error(o); - return; - } - struct sc_server_hello msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.id); - - // change state - o->state = STATE_COMPLETE; - - // report - o->handler_ready(o->user, id, msg.clientAddr); - return; -} - -void packet_newclient (ServerConnection *o, uint8_t *data, int data_len) -{ - if (o->state != STATE_COMPLETE) { - BLog(BLOG_ERROR, "newclient: not expected"); - report_error(o); - return; - } - - if (data_len < sizeof(struct sc_server_newclient) || data_len > sizeof(struct sc_server_newclient) + SCID_NEWCLIENT_MAX_CERT_LEN) { - BLog(BLOG_ERROR, "newclient: invalid length"); - report_error(o); - return; - } - - struct sc_server_newclient msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.id); - - // schedule reporting new client - o->newclient_data = data; - o->newclient_data_len = data_len; - BPending_Set(&o->newclient_job); - - // send acceptpeer - struct sc_client_acceptpeer omsg; - void *packet; - if (!start_packet(o, &packet, sizeof(omsg))) { - BLog(BLOG_ERROR, "newclient: out of buffer for acceptpeer"); - report_error(o); - return; - } - omsg.clientid = htol16(id); - memcpy(packet, &omsg, sizeof(omsg)); - end_packet(o, SCID_ACCEPTPEER); -} - -void packet_endclient (ServerConnection *o, uint8_t *data, int data_len) -{ - if (o->state != STATE_COMPLETE) { - BLog(BLOG_ERROR, "endclient: not expected"); - report_error(o); - return; - } - - if (data_len != sizeof(struct sc_server_endclient)) { - BLog(BLOG_ERROR, "endclient: invalid length"); - report_error(o); - return; - } - - struct sc_server_endclient msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t id = ltoh16(msg.id); - - // report - o->handler_endclient(o->user, id); - return; -} - -void packet_inmsg (ServerConnection *o, uint8_t *data, int data_len) -{ - if (o->state != STATE_COMPLETE) { - BLog(BLOG_ERROR, "inmsg: not expected"); - report_error(o); - return; - } - - if (data_len < sizeof(struct sc_server_inmsg)) { - BLog(BLOG_ERROR, "inmsg: missing header"); - report_error(o); - return; - } - - if (data_len > sizeof(struct sc_server_inmsg) + SC_MAX_MSGLEN) { - BLog(BLOG_ERROR, "inmsg: too long"); - report_error(o); - return; - } - - struct sc_server_inmsg msg; - memcpy(&msg, data, sizeof(msg)); - peerid_t peer_id = ltoh16(msg.clientid); - uint8_t *payload = data + sizeof(struct sc_server_inmsg); - int payload_len = data_len - sizeof(struct sc_server_inmsg); - - // report - o->handler_message(o->user, peer_id, payload, payload_len); - return; -} - -int start_packet (ServerConnection *o, void **data, int len) -{ - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(o->output_local_packet_len == -1) - ASSERT(len >= 0) - ASSERT(len <= SC_MAX_PAYLOAD) - ASSERT(data || len == 0) - - // obtain memory location - if (!BufferWriter_StartPacket(o->output_local_if, &o->output_local_packet)) { - BLog(BLOG_ERROR, "out of buffer"); - return 0; - } - - o->output_local_packet_len = len; - - if (data) { - *data = o->output_local_packet + sizeof(struct sc_header); - } - - return 1; -} - -void end_packet (ServerConnection *o, uint8_t type) -{ - ASSERT(o->state >= STATE_WAITINIT) - ASSERT(o->output_local_packet_len >= 0) - ASSERT(o->output_local_packet_len <= SC_MAX_PAYLOAD) - - // write header - struct sc_header header; - header.type = htol8(type); - memcpy(o->output_local_packet, &header, sizeof(header)); - - // finish writing packet - BufferWriter_EndPacket(o->output_local_if, sizeof(struct sc_header) + o->output_local_packet_len); - - o->output_local_packet_len = -1; -} - -int ServerConnection_Init ( - ServerConnection *o, - BReactor *reactor, - BThreadWorkDispatcher *twd, - BAddr addr, - int keepalive_interval, - int buffer_size, - int have_ssl, - int ssl_flags, - CERTCertificate *client_cert, - SECKEYPrivateKey *client_key, - const char *server_name, - void *user, - ServerConnection_handler_error handler_error, - ServerConnection_handler_ready handler_ready, - ServerConnection_handler_newclient handler_newclient, - ServerConnection_handler_endclient handler_endclient, - ServerConnection_handler_message handler_message -) -{ - ASSERT(keepalive_interval > 0) - ASSERT(buffer_size > 0) - ASSERT(have_ssl == 0 || have_ssl == 1) - ASSERT(!have_ssl || server_name) - - // init arguments - o->reactor = reactor; - o->twd = twd; - o->keepalive_interval = keepalive_interval; - o->buffer_size = buffer_size; - o->have_ssl = have_ssl; - if (have_ssl) { - o->ssl_flags = ssl_flags; - o->client_cert = client_cert; - o->client_key = client_key; - } - o->user = user; - o->handler_error = handler_error; - o->handler_ready = handler_ready; - o->handler_newclient = handler_newclient; - o->handler_endclient = handler_endclient; - o->handler_message = handler_message; - - o->server_name = NULL; - if (have_ssl && !(o->server_name = b_strdup(server_name))) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - if (!BConnection_AddressSupported(addr)) { - BLog(BLOG_ERROR, "BConnection_AddressSupported failed"); - goto fail1; - } - - // init connector - if (!BConnector_Init(&o->connector, addr, o->reactor, o, (BConnector_handler)connector_handler)) { - BLog(BLOG_ERROR, "BConnector_Init failed"); - goto fail1; - } - - // init newclient job - BPending_Init(&o->newclient_job, BReactor_PendingGroup(o->reactor), (BPending_handler)newclient_job_handler, o); - - // set state - o->state = STATE_CONNECTING; - o->buffers_released = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - free(o->server_name); -fail0: - return 0; -} - -void ServerConnection_Free (ServerConnection *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - if (o->state > STATE_CONNECTING) { - // allow freeing queue flows - PacketPassPriorityQueue_PrepareFree(&o->output_queue); - - // stop using any buffers before they get freed - if (o->have_ssl && !o->buffers_released) { - BSSLConnection_ReleaseBuffers(&o->sslcon); - } - - // free output user flow - PacketPassPriorityQueueFlow_Free(&o->output_user_qflow); - - // free output local flow - PacketProtoFlow_Free(&o->output_local_oflow); - PacketPassPriorityQueueFlow_Free(&o->output_local_qflow); - - // free output common - PacketPassPriorityQueue_Free(&o->output_queue); - KeepaliveIO_Free(&o->output_keepaliveio); - PacketStreamSender_Free(&o->output_sender); - - // free output keep-alive branch - PacketProtoEncoder_Free(&o->output_ka_encoder); - SCKeepaliveSource_Free(&o->output_ka_zero); - - // free job - BPending_Free(&o->start_job); - - // free input chain - PacketProtoDecoder_Free(&o->input_decoder); - PacketPassInterface_Free(&o->input_interface); - - // free SSL - if (o->have_ssl) { - BSSLConnection_Free(&o->sslcon); - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) - } - - // free connection interfaces - BConnection_RecvAsync_Free(&o->con); - BConnection_SendAsync_Free(&o->con); - - // free connection - BConnection_Free(&o->con); - } - - // free newclient job - BPending_Free(&o->newclient_job); - - // free connector - BConnector_Free(&o->connector); - - // free server name - free(o->server_name); -} - -void ServerConnection_ReleaseBuffers (ServerConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->buffers_released) - - if (o->state > STATE_CONNECTING && o->have_ssl) { - BSSLConnection_ReleaseBuffers(&o->sslcon); - } - - o->buffers_released = 1; -} - -PacketPassInterface * ServerConnection_GetSendInterface (ServerConnection *o) -{ - ASSERT(o->state == STATE_COMPLETE) - DebugError_AssertNoError(&o->d_err); - DebugObject_Access(&o->d_obj); - - return PacketPassPriorityQueueFlow_GetInput(&o->output_user_qflow); -} - -void newclient_job_handler (ServerConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == STATE_COMPLETE) - - struct sc_server_newclient msg; - memcpy(&msg, o->newclient_data, sizeof(msg)); - peerid_t id = ltoh16(msg.id); - int flags = ltoh16(msg.flags); - - uint8_t *cert_data = o->newclient_data + sizeof(msg); - int cert_len = o->newclient_data_len - sizeof(msg); - - // report new client - o->handler_newclient(o->user, id, flags, cert_data, cert_len); - return; -} diff --git a/external/badvpn_dns/server_connection/ServerConnection.h b/external/badvpn_dns/server_connection/ServerConnection.h deleted file mode 100644 index 1245c84..0000000 --- a/external/badvpn_dns/server_connection/ServerConnection.h +++ /dev/null @@ -1,289 +0,0 @@ -/** - * @file ServerConnection.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used to communicate with a VPN chat server. - */ - -#ifndef BADVPN_SERVERCONNECTION_SERVERCONNECTION_H -#define BADVPN_SERVERCONNECTION_SERVERCONNECTION_H - -#include <stdint.h> - -#include <prinit.h> -#include <prio.h> -#include <prerror.h> -#include <prtypes.h> -#include <nss.h> -#include <ssl.h> -#include <pk11func.h> -#include <cert.h> -#include <keyhi.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <protocol/scproto.h> -#include <protocol/msgproto.h> -#include <base/DebugObject.h> -#include <system/BConnection.h> -#include <flow/PacketProtoEncoder.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketPassPriorityQueue.h> -#include <flow/PacketProtoFlow.h> -#include <flowextra/KeepaliveIO.h> -#include <nspr_support/BSSLConnection.h> -#include <server_connection/SCKeepaliveSource.h> - -/** - * Handler function invoked when an error occurs. - * The object must be freed from withing this function. - * - * @param user value passed to {@link ServerConnection_Init} - */ -typedef void (*ServerConnection_handler_error) (void *user); - -/** - * Handler function invoked when the server becomes ready, i.e. - * the hello packet has been received. - * The object was in not ready state before. - * The object enters ready state before the handler is invoked. - * - * @param user value passed to {@link ServerConnection_Init} - * @param my_id our ID as reported by the server - * @param ext_ip the clientAddr field in the server's hello packet - */ -typedef void (*ServerConnection_handler_ready) (void *user, peerid_t my_id, uint32_t ext_ip); - -/** - * Handler function invoked when a newclient packet is received. - * The object was in ready state. - * - * @param user value passed to {@link ServerConnection_Init} - * @param peer_id ID of the peer - * @param flags flags field from the newclient message - * @param cert peer's certificate (if any) - * @param cert_len certificate length. Will be >=0. - */ -typedef void (*ServerConnection_handler_newclient) (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len); - -/** - * Handler function invoked when an enclient packet is received. - * The object was in ready state. - * - * @param user value passed to {@link ServerConnection_Init} - * @param peer_id ID of the peer - */ -typedef void (*ServerConnection_handler_endclient) (void *user, peerid_t peer_id); - -/** - * Handler function invoked when an inmsg packet is received. - * The object was in ready state. - * - * @param user value passed to {@link ServerConnection_Init} - * @param peer_id ID of the peer from which the message came - * @param data message payload - * @param data_len message length. Will be >=0. - */ -typedef void (*ServerConnection_handler_message) (void *user, peerid_t peer_id, uint8_t *data, int data_len); - -/** - * Object used to communicate with a VPN chat server. - */ -typedef struct { - // global resources - BReactor *reactor; - BThreadWorkDispatcher *twd; - - // keepalive interval - int keepalive_interval; - - // send buffer size - int buffer_size; - - // whether we use SSL - int have_ssl; - - // ssl flags - int ssl_flags; - - // client certificate if using SSL - CERTCertificate *client_cert; - - // client private key if using SSL - SECKEYPrivateKey *client_key; - - // server name if using SSL - char *server_name; - - // handlers - void *user; - ServerConnection_handler_error handler_error; - ServerConnection_handler_ready handler_ready; - ServerConnection_handler_newclient handler_newclient; - ServerConnection_handler_endclient handler_endclient; - ServerConnection_handler_message handler_message; - - // socket - BConnector connector; - BConnection con; - - // job to report new client after sending acceptpeer - BPending newclient_job; - uint8_t *newclient_data; - int newclient_data_len; - - // state - int state; - int buffers_released; - - // whether an error is being reported - int error; - - // defined when state > SERVERCONNECTION_STATE_CONNECTING - - // SSL file descriptor, defined only if using SSL - PRFileDesc bottom_prfd; - PRFileDesc *ssl_prfd; - BSSLConnection sslcon; - - // input - PacketProtoDecoder input_decoder; - PacketPassInterface input_interface; - - // keepalive output branch - SCKeepaliveSource output_ka_zero; - PacketProtoEncoder output_ka_encoder; - - // output common - PacketPassPriorityQueue output_queue; - KeepaliveIO output_keepaliveio; - PacketStreamSender output_sender; - - // output local flow - int output_local_packet_len; - uint8_t *output_local_packet; - BufferWriter *output_local_if; - PacketProtoFlow output_local_oflow; - PacketPassPriorityQueueFlow output_local_qflow; - - // output user flow - PacketPassPriorityQueueFlow output_user_qflow; - - // job to start client I/O - BPending start_job; - - DebugError d_err; - DebugObject d_obj; -} ServerConnection; - -/** - * Initializes the object. - * The object is initialized in not ready state. - * {@link BLog_Init} must have been done. - * {@link BNetwork_GlobalInit} must have been done. - * {@link BSSLConnection_GlobalInit} must have been done if using SSL. - * - * @param o the object - * @param reactor {@link BReactor} we live in - * @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL - * operations in threads. - * @param addr address to connect to - * @param keepalive_interval keep-alive sending interval. Must be >0. - * @param buffer_size minimum size of send buffer in number of packets. Must be >0. - * @param have_ssl whether to use SSL for connecting to the server. Must be 1 or 0. - * @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to - * request performing SSL operations in threads. - * @param client_cert if using SSL, client certificate to use. Must remain valid as - * long as this object is alive. - * @param client_key if using SSL, prvate ket to use. Must remain valid as - * long as this object is alive. - * @param server_name if using SSL, the name of the server. The string is copied. - * @param user value passed to callback functions - * @param handler_error error handler. The object must be freed from within the error - * handler before doing anything else with this object. - * @param handler_ready handler when the server becomes ready, i.e. the hello message has - * been received. - * @param handler_newclient handler when a newclient message has been received - * @param handler_endclient handler when an endclient message has been received - * @param handler_message handler when a peer message has been reveived - * @return 1 on success, 0 on failure - */ -int ServerConnection_Init ( - ServerConnection *o, - BReactor *reactor, - BThreadWorkDispatcher *twd, - BAddr addr, - int keepalive_interval, - int buffer_size, - int have_ssl, - int ssl_flags, - CERTCertificate *client_cert, - SECKEYPrivateKey *client_key, - const char *server_name, - void *user, - ServerConnection_handler_error handler_error, - ServerConnection_handler_ready handler_ready, - ServerConnection_handler_newclient handler_newclient, - ServerConnection_handler_endclient handler_endclient, - ServerConnection_handler_message handler_message -) WARN_UNUSED; - -/** - * Frees the object. - * {@link ServerConnection_ReleaseBuffers} must have been called if the - * send interface obtained from {@link ServerConnection_GetSendInterface} - * was used. - * - * @param o the object - */ -void ServerConnection_Free (ServerConnection *o); - -/** - * Stops using any buffers passed to the send interface obtained from - * {@link ServerConnection_GetSendInterface}. If the send interface - * has been used, this must be called at appropriate time before this - * object is freed. - */ -void ServerConnection_ReleaseBuffers (ServerConnection *o); - -/** - * Returns an interface for sending data to the server (just one). - * This goes directly into the link (i.e. TCP, possibly via SSL), so packets - * need to be manually encoded according to PacketProto. - * The interface must not be used after an error was reported. - * The object must be in ready state. - * Must not be called from the error handler. - * - * @param o the object - * @return the interface - */ -PacketPassInterface * ServerConnection_GetSendInterface (ServerConnection *o); - -#endif diff --git a/external/badvpn_dns/socksclient/BSocksClient.c b/external/badvpn_dns/socksclient/BSocksClient.c deleted file mode 100644 index 21415af..0000000 --- a/external/badvpn_dns/socksclient/BSocksClient.c +++ /dev/null @@ -1,608 +0,0 @@ -/** - * @file BSocksClient.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> - -#include <misc/byteorder.h> -#include <misc/balloc.h> -#include <base/BLog.h> - -#include <socksclient/BSocksClient.h> - -#include <generated/blog_channel_BSocksClient.h> - -#define STATE_CONNECTING 1 -#define STATE_SENDING_HELLO 2 -#define STATE_SENT_HELLO 3 -#define STATE_SENDING_PASSWORD 10 -#define STATE_SENT_PASSWORD 11 -#define STATE_SENDING_REQUEST 4 -#define STATE_SENT_REQUEST 5 -#define STATE_RECEIVED_REPLY_HEADER 6 -#define STATE_UP 7 - -static void report_error (BSocksClient *o, int error); -static void init_control_io (BSocksClient *o); -static void free_control_io (BSocksClient *o); -static void init_up_io (BSocksClient *o); -static void free_up_io (BSocksClient *o); -static int reserve_buffer (BSocksClient *o, bsize_t size); -static void start_receive (BSocksClient *o, uint8_t *dest, int total); -static void do_receive (BSocksClient *o); -static void connector_handler (BSocksClient* o, int is_error); -static void connection_handler (BSocksClient* o, int event); -static void recv_handler_done (BSocksClient *o, int data_len); -static void send_handler_done (BSocksClient *o); -static void auth_finished (BSocksClient *p); - -void report_error (BSocksClient *o, int error) -{ - DEBUGERROR(&o->d_err, o->handler(o->user, error)) -} - -void init_control_io (BSocksClient *o) -{ - // init receiving - BConnection_RecvAsync_Init(&o->con); - o->control.recv_if = BConnection_RecvAsync_GetIf(&o->con); - StreamRecvInterface_Receiver_Init(o->control.recv_if, (StreamRecvInterface_handler_done)recv_handler_done, o); - - // init sending - BConnection_SendAsync_Init(&o->con); - PacketStreamSender_Init(&o->control.send_sender, BConnection_SendAsync_GetIf(&o->con), INT_MAX, BReactor_PendingGroup(o->reactor)); - o->control.send_if = PacketStreamSender_GetInput(&o->control.send_sender); - PacketPassInterface_Sender_Init(o->control.send_if, (PacketPassInterface_handler_done)send_handler_done, o); -} - -void free_control_io (BSocksClient *o) -{ - // free sending - PacketStreamSender_Free(&o->control.send_sender); - BConnection_SendAsync_Free(&o->con); - - // free receiving - BConnection_RecvAsync_Free(&o->con); -} - -void init_up_io (BSocksClient *o) -{ - // init receiving - BConnection_RecvAsync_Init(&o->con); - - // init sending - BConnection_SendAsync_Init(&o->con); -} - -void free_up_io (BSocksClient *o) -{ - // free sending - BConnection_SendAsync_Free(&o->con); - - // free receiving - BConnection_RecvAsync_Free(&o->con); -} - -int reserve_buffer (BSocksClient *o, bsize_t size) -{ - if (size.is_overflow) { - BLog(BLOG_ERROR, "size overflow"); - return 0; - } - - char *buffer = (char *)BRealloc(o->buffer, size.value); - if (!buffer) { - BLog(BLOG_ERROR, "BRealloc failed"); - return 0; - } - - o->buffer = buffer; - - return 1; -} - -void start_receive (BSocksClient *o, uint8_t *dest, int total) -{ - ASSERT(total > 0) - - o->control.recv_dest = dest; - o->control.recv_len = 0; - o->control.recv_total = total; - - do_receive(o); -} - -void do_receive (BSocksClient *o) -{ - ASSERT(o->control.recv_len < o->control.recv_total) - - StreamRecvInterface_Receiver_Recv(o->control.recv_if, o->control.recv_dest + o->control.recv_len, o->control.recv_total - o->control.recv_len); -} - -void connector_handler (BSocksClient* o, int is_error) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == STATE_CONNECTING) - - // check connection result - if (is_error) { - BLog(BLOG_ERROR, "connection failed"); - goto fail0; - } - - // init connection - if (!BConnection_Init(&o->con, BConnection_source_connector(&o->connector), o->reactor, o, (BConnection_handler)connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - BLog(BLOG_DEBUG, "connected"); - - // init control I/O - init_control_io(o); - - // check number of methods - if (o->num_auth_info == 0 || o->num_auth_info > 255) { - BLog(BLOG_ERROR, "invalid number of authentication methods"); - goto fail1; - } - - // allocate buffer for sending hello - bsize_t size = bsize_add( - bsize_fromsize(sizeof(struct socks_client_hello_header)), - bsize_mul( - bsize_fromsize(o->num_auth_info), - bsize_fromsize(sizeof(struct socks_client_hello_method)) - ) - ); - if (!reserve_buffer(o, size)) { - goto fail1; - } - - // write hello header - struct socks_client_hello_header header; - header.ver = hton8(SOCKS_VERSION); - header.nmethods = hton8(o->num_auth_info); - memcpy(o->buffer, &header, sizeof(header)); - - // write hello methods - for (size_t i = 0; i < o->num_auth_info; i++) { - struct socks_client_hello_method method; - method.method = hton8(o->auth_info[i].auth_type); - memcpy(o->buffer + sizeof(header) + i * sizeof(method), &method, sizeof(method)); - } - - // send - PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)o->buffer, size.value); - - // set state - o->state = STATE_SENDING_HELLO; - - return; - -fail1: - free_control_io(o); - BConnection_Free(&o->con); -fail0: - report_error(o, BSOCKSCLIENT_EVENT_ERROR); - return; -} - -void connection_handler (BSocksClient* o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state != STATE_CONNECTING) - - if (o->state == STATE_UP && event == BCONNECTION_EVENT_RECVCLOSED) { - report_error(o, BSOCKSCLIENT_EVENT_ERROR_CLOSED); - return; - } - - report_error(o, BSOCKSCLIENT_EVENT_ERROR); - return; -} - -void recv_handler_done (BSocksClient *o, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->control.recv_total - o->control.recv_len) - DebugObject_Access(&o->d_obj); - - o->control.recv_len += data_len; - - if (o->control.recv_len < o->control.recv_total) { - do_receive(o); - return; - } - - switch (o->state) { - case STATE_SENT_HELLO: { - BLog(BLOG_DEBUG, "received hello"); - - struct socks_server_hello imsg; - memcpy(&imsg, o->buffer, sizeof(imsg)); - - if (ntoh8(imsg.ver) != SOCKS_VERSION) { - BLog(BLOG_NOTICE, "wrong version"); - goto fail; - } - - size_t auth_index; - for (auth_index = 0; auth_index < o->num_auth_info; auth_index++) { - if (o->auth_info[auth_index].auth_type == ntoh8(imsg.method)) { - break; - } - } - - if (auth_index == o->num_auth_info) { - BLog(BLOG_NOTICE, "server didn't accept any authentication method"); - goto fail; - } - - const struct BSocksClient_auth_info *ai = &o->auth_info[auth_index]; - - switch (ai->auth_type) { - case SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED: { - BLog(BLOG_DEBUG, "no authentication"); - - auth_finished(o); - } break; - - case SOCKS_METHOD_USERNAME_PASSWORD: { - BLog(BLOG_DEBUG, "password authentication"); - - if (ai->password.username_len == 0 || ai->password.username_len > 255 || - ai->password.password_len == 0 || ai->password.password_len > 255 - ) { - BLog(BLOG_NOTICE, "invalid username/password length"); - goto fail; - } - - // allocate password packet - bsize_t size = bsize_fromsize(1 + 1 + ai->password.username_len + 1 + ai->password.password_len); - if (!reserve_buffer(o, size)) { - goto fail; - } - - // write password packet - char *ptr = o->buffer; - *ptr++ = 1; - *ptr++ = ai->password.username_len; - memcpy(ptr, ai->password.username, ai->password.username_len); - ptr += ai->password.username_len; - *ptr++ = ai->password.password_len; - memcpy(ptr, ai->password.password, ai->password.password_len); - ptr += ai->password.password_len; - - // start sending - PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)o->buffer, size.value); - - // set state - o->state = STATE_SENDING_PASSWORD; - } break; - - default: ASSERT(0); - } - } break; - - case STATE_SENT_REQUEST: { - BLog(BLOG_DEBUG, "received reply header"); - - struct socks_reply_header imsg; - memcpy(&imsg, o->buffer, sizeof(imsg)); - - if (ntoh8(imsg.ver) != SOCKS_VERSION) { - BLog(BLOG_NOTICE, "wrong version"); - goto fail; - } - - if (ntoh8(imsg.rep) != SOCKS_REP_SUCCEEDED) { - BLog(BLOG_NOTICE, "reply not successful"); - goto fail; - } - - int addr_len; - switch (ntoh8(imsg.atyp)) { - case SOCKS_ATYP_IPV4: - addr_len = sizeof(struct socks_addr_ipv4); - break; - case SOCKS_ATYP_IPV6: - addr_len = sizeof(struct socks_addr_ipv6); - break; - default: - BLog(BLOG_NOTICE, "reply has unknown address type"); - goto fail; - } - - // receive the rest of the reply - start_receive(o, (uint8_t *)o->buffer + sizeof(imsg), addr_len); - - // set state - o->state = STATE_RECEIVED_REPLY_HEADER; - } break; - - case STATE_SENT_PASSWORD: { - BLog(BLOG_DEBUG, "received password reply"); - - if (o->buffer[0] != 1) { - BLog(BLOG_NOTICE, "password reply has unknown version"); - goto fail; - } - - if (o->buffer[1] != 0) { - BLog(BLOG_NOTICE, "password reply is negative"); - goto fail; - } - - auth_finished(o); - } break; - - case STATE_RECEIVED_REPLY_HEADER: { - BLog(BLOG_DEBUG, "received reply rest"); - - // free buffer - BFree(o->buffer); - o->buffer = NULL; - - // free control I/O - free_control_io(o); - - // init up I/O - init_up_io(o); - - // set state - o->state = STATE_UP; - - // call handler - o->handler(o->user, BSOCKSCLIENT_EVENT_UP); - return; - } break; - - default: - ASSERT(0); - } - - return; - -fail: - report_error(o, BSOCKSCLIENT_EVENT_ERROR); -} - -void send_handler_done (BSocksClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->buffer) - - switch (o->state) { - case STATE_SENDING_HELLO: { - BLog(BLOG_DEBUG, "sent hello"); - - // allocate buffer for receiving hello - bsize_t size = bsize_fromsize(sizeof(struct socks_server_hello)); - if (!reserve_buffer(o, size)) { - goto fail; - } - - // receive hello - start_receive(o, (uint8_t *)o->buffer, size.value); - - // set state - o->state = STATE_SENT_HELLO; - } break; - - case STATE_SENDING_REQUEST: { - BLog(BLOG_DEBUG, "sent request"); - - // allocate buffer for receiving reply - bsize_t size = bsize_add( - bsize_fromsize(sizeof(struct socks_reply_header)), - bsize_max(bsize_fromsize(sizeof(struct socks_addr_ipv4)), bsize_fromsize(sizeof(struct socks_addr_ipv6))) - ); - if (!reserve_buffer(o, size)) { - goto fail; - } - - // receive reply header - start_receive(o, (uint8_t *)o->buffer, sizeof(struct socks_reply_header)); - - // set state - o->state = STATE_SENT_REQUEST; - } break; - - case STATE_SENDING_PASSWORD: { - BLog(BLOG_DEBUG, "send password"); - - // allocate buffer for receiving reply - bsize_t size = bsize_fromsize(2); - if (!reserve_buffer(o, size)) { - goto fail; - } - - // receive reply header - start_receive(o, (uint8_t *)o->buffer, size.value); - - // set state - o->state = STATE_SENT_PASSWORD; - } break; - - default: - ASSERT(0); - } - - return; - -fail: - report_error(o, BSOCKSCLIENT_EVENT_ERROR); -} - -void auth_finished (BSocksClient *o) -{ - // allocate request buffer - bsize_t size = bsize_fromsize(sizeof(struct socks_request_header)); - switch (o->dest_addr.type) { - case BADDR_TYPE_IPV4: size = bsize_add(size, bsize_fromsize(sizeof(struct socks_addr_ipv4))); break; - case BADDR_TYPE_IPV6: size = bsize_add(size, bsize_fromsize(sizeof(struct socks_addr_ipv6))); break; - } - if (!reserve_buffer(o, size)) { - report_error(o, BSOCKSCLIENT_EVENT_ERROR); - return; - } - - // write request - struct socks_request_header header; - header.ver = hton8(SOCKS_VERSION); - header.cmd = hton8(SOCKS_CMD_CONNECT); - header.rsv = hton8(0); - switch (o->dest_addr.type) { - case BADDR_TYPE_IPV4: { - header.atyp = hton8(SOCKS_ATYP_IPV4); - struct socks_addr_ipv4 addr; - addr.addr = o->dest_addr.ipv4.ip; - addr.port = o->dest_addr.ipv4.port; - memcpy(o->buffer + sizeof(header), &addr, sizeof(addr)); - } break; - case BADDR_TYPE_IPV6: { - header.atyp = hton8(SOCKS_ATYP_IPV6); - struct socks_addr_ipv6 addr; - memcpy(addr.addr, o->dest_addr.ipv6.ip, sizeof(o->dest_addr.ipv6.ip)); - addr.port = o->dest_addr.ipv6.port; - memcpy(o->buffer + sizeof(header), &addr, sizeof(addr)); - } break; - default: - ASSERT(0); - } - memcpy(o->buffer, &header, sizeof(header)); - - // send request - PacketPassInterface_Sender_Send(o->control.send_if, (uint8_t *)o->buffer, size.value); - - // set state - o->state = STATE_SENDING_REQUEST; -} - -struct BSocksClient_auth_info BSocksClient_auth_none (void) -{ - struct BSocksClient_auth_info info; - info.auth_type = SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED; - return info; -} - -struct BSocksClient_auth_info BSocksClient_auth_password (const char *username, size_t username_len, const char *password, size_t password_len) -{ - struct BSocksClient_auth_info info; - info.auth_type = SOCKS_METHOD_USERNAME_PASSWORD; - info.password.username = username; - info.password.username_len = username_len; - info.password.password = password; - info.password.password_len = password_len; - return info; -} - -int BSocksClient_Init (BSocksClient *o, - BAddr server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info, - BAddr dest_addr, BSocksClient_handler handler, void *user, BReactor *reactor) -{ - ASSERT(!BAddr_IsInvalid(&server_addr)) - ASSERT(dest_addr.type == BADDR_TYPE_IPV4 || dest_addr.type == BADDR_TYPE_IPV6) -#ifndef NDEBUG - for (size_t i = 0; i < num_auth_info; i++) { - ASSERT(auth_info[i].auth_type == SOCKS_METHOD_NO_AUTHENTICATION_REQUIRED || - auth_info[i].auth_type == SOCKS_METHOD_USERNAME_PASSWORD) - } -#endif - - // init arguments - o->auth_info = auth_info; - o->num_auth_info = num_auth_info; - o->dest_addr = dest_addr; - o->handler = handler; - o->user = user; - o->reactor = reactor; - - // set no buffer - o->buffer = NULL; - - // init connector - if (!BConnector_Init(&o->connector, server_addr, o->reactor, o, (BConnector_handler)connector_handler)) { - BLog(BLOG_ERROR, "BConnector_Init failed"); - goto fail0; - } - - // set state - o->state = STATE_CONNECTING; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void BSocksClient_Free (BSocksClient *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - if (o->state != STATE_CONNECTING) { - if (o->state == STATE_UP) { - // free up I/O - free_up_io(o); - } else { - // free control I/O - free_control_io(o); - } - - // free connection - BConnection_Free(&o->con); - } - - // free connector - BConnector_Free(&o->connector); - - // free buffer - if (o->buffer) { - BFree(o->buffer); - } -} - -StreamPassInterface * BSocksClient_GetSendInterface (BSocksClient *o) -{ - ASSERT(o->state == STATE_UP) - DebugObject_Access(&o->d_obj); - - return BConnection_SendAsync_GetIf(&o->con); -} - -StreamRecvInterface * BSocksClient_GetRecvInterface (BSocksClient *o) -{ - ASSERT(o->state == STATE_UP) - DebugObject_Access(&o->d_obj); - - return BConnection_RecvAsync_GetIf(&o->con); -} diff --git a/external/badvpn_dns/socksclient/BSocksClient.h b/external/badvpn_dns/socksclient/BSocksClient.h deleted file mode 100644 index f19b3a8..0000000 --- a/external/badvpn_dns/socksclient/BSocksClient.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file BSocksClient.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * SOCKS5 client. TCP only, no authentication. - */ - -#ifndef BADVPN_SOCKS_BSOCKSCLIENT_H -#define BADVPN_SOCKS_BSOCKSCLIENT_H - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <misc/socks_proto.h> -#include <misc/packed.h> -#include <base/DebugObject.h> -#include <system/BConnection.h> -#include <flow/PacketStreamSender.h> - -#define BSOCKSCLIENT_EVENT_ERROR 1 -#define BSOCKSCLIENT_EVENT_UP 2 -#define BSOCKSCLIENT_EVENT_ERROR_CLOSED 3 - -/** - * Handler for events generated by the SOCKS client. - * - * @param user as in {@link BSocksClient_Init} - * @param event event type. One of BSOCKSCLIENT_EVENT_ERROR, BSOCKSCLIENT_EVENT_UP - * and BSOCKSCLIENT_EVENT_ERROR_CLOSED. - * If event is BSOCKSCLIENT_EVENT_UP, the object was previously in down - * state and has transitioned to up state; I/O can be done from this point on. - * If event is BSOCKSCLIENT_EVENT_ERROR or BSOCKSCLIENT_EVENT_ERROR_CLOSED, - * the object must be freed from within the job closure of this handler, - * and no further I/O must be attempted. - */ -typedef void (*BSocksClient_handler) (void *user, int event); - -struct BSocksClient_auth_info { - int auth_type; - union { - struct { - const char *username; - size_t username_len; - const char *password; - size_t password_len; - } password; - }; -}; - -typedef struct { - const struct BSocksClient_auth_info *auth_info; - size_t num_auth_info; - BAddr dest_addr; - BSocksClient_handler handler; - void *user; - BReactor *reactor; - int state; - char *buffer; - BConnector connector; - BConnection con; - union { - struct { - PacketPassInterface *send_if; - PacketStreamSender send_sender; - StreamRecvInterface *recv_if; - uint8_t *recv_dest; - int recv_len; - int recv_total; - } control; - }; - DebugError d_err; - DebugObject d_obj; -} BSocksClient; - -struct BSocksClient_auth_info BSocksClient_auth_none (void); -struct BSocksClient_auth_info BSocksClient_auth_password (const char *username, size_t username_len, const char *password, size_t password_len); - -/** - * Initializes the object. - * The object is initialized in down state. The object must transition to up - * state before the user may begin any I/O. - * - * @param o the object - * @param server_addr SOCKS5 server address - * @param dest_addr remote address - * @param handler handler for up and error events - * @param user value passed to handler - * @param reactor reactor we live in - * @return 1 on success, 0 on failure - */ -int BSocksClient_Init (BSocksClient *o, - BAddr server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info, - BAddr dest_addr, BSocksClient_handler handler, void *user, BReactor *reactor) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void BSocksClient_Free (BSocksClient *o); - -/** - * Returns the send interface. - * The object must be in up state. - * - * @param o the object - * @return send interface - */ -StreamPassInterface * BSocksClient_GetSendInterface (BSocksClient *o); - -/** - * Returns the receive interface. - * The object must be in up state. - * - * @param o the object - * @return receive interface - */ -StreamRecvInterface * BSocksClient_GetRecvInterface (BSocksClient *o); - -#endif diff --git a/external/badvpn_dns/socksclient/CMakeLists.txt b/external/badvpn_dns/socksclient/CMakeLists.txt deleted file mode 100644 index 7b88d8e..0000000 --- a/external/badvpn_dns/socksclient/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(socksclient "system;flow;flowextra" "" BSocksClient.c) diff --git a/external/badvpn_dns/stringmap/BStringMap.c b/external/badvpn_dns/stringmap/BStringMap.c deleted file mode 100644 index d53f10e..0000000 --- a/external/badvpn_dns/stringmap/BStringMap.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @file BStringMap.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/compare.h> - -#include <stringmap/BStringMap.h> - -static int string_comparator (void *unused, char **str1, char **str2) -{ - int c = strcmp(*str1, *str2); - return B_COMPARE(c, 0); -} - -static void free_entry (BStringMap *o, struct BStringMap_entry *e) -{ - BAVL_Remove(&o->tree, &e->tree_node); - free(e->value); - free(e->key); - free(e); -} - -void BStringMap_Init (BStringMap *o) -{ - // init tree - BAVL_Init(&o->tree, OFFSET_DIFF(struct BStringMap_entry, key, tree_node), (BAVL_comparator)string_comparator, NULL); - - DebugObject_Init(&o->d_obj); -} - -int BStringMap_InitCopy (BStringMap *o, const BStringMap *src) -{ - BStringMap_Init(o); - - const char *key = BStringMap_First(src); - while (key) { - if (!BStringMap_Set(o, key, BStringMap_Get(src, key))) { - goto fail1; - } - key = BStringMap_Next(src, key); - } - - return 1; - -fail1: - BStringMap_Free(o); - return 0; -} - -void BStringMap_Free (BStringMap *o) -{ - DebugObject_Free(&o->d_obj); - - // free entries - BAVLNode *tree_node; - while (tree_node = BAVL_GetFirst(&o->tree)) { - struct BStringMap_entry *e = UPPER_OBJECT(tree_node, struct BStringMap_entry, tree_node); - free_entry(o, e); - } -} - -const char * BStringMap_Get (const BStringMap *o, const char *key) -{ - DebugObject_Access(&o->d_obj); - ASSERT(key) - - // lookup - BAVLNode *tree_node = BAVL_LookupExact(&o->tree, &key); - if (!tree_node) { - return NULL; - } - struct BStringMap_entry *e = UPPER_OBJECT(tree_node, struct BStringMap_entry, tree_node); - - return e->value; -} - -int BStringMap_Set (BStringMap *o, const char *key, const char *value) -{ - DebugObject_Access(&o->d_obj); - ASSERT(key) - ASSERT(value) - - // alloc entry - struct BStringMap_entry *e = malloc(sizeof(*e)); - if (!e) { - goto fail0; - } - - // alloc and set key - if (!(e->key = malloc(strlen(key) + 1))) { - goto fail1; - } - strcpy(e->key, key); - - // alloc and set value - if (!(e->value = malloc(strlen(value) + 1))) { - goto fail2; - } - strcpy(e->value, value); - - // try inserting to tree - BAVLNode *ex_tree_node; - if (!BAVL_Insert(&o->tree, &e->tree_node, &ex_tree_node)) { - // remove existing entry - struct BStringMap_entry *ex_e = UPPER_OBJECT(ex_tree_node, struct BStringMap_entry, tree_node); - free_entry(o, ex_e); - - // insert new node - ASSERT_EXECUTE(BAVL_Insert(&o->tree, &e->tree_node, NULL)) - } - - return 1; - -fail2: - free(e->key); -fail1: - free(e); -fail0: - return 0; -} - -void BStringMap_Unset (BStringMap *o, const char *key) -{ - DebugObject_Access(&o->d_obj); - ASSERT(key) - - // lookup - BAVLNode *tree_node = BAVL_LookupExact(&o->tree, &key); - if (!tree_node) { - return; - } - struct BStringMap_entry *e = UPPER_OBJECT(tree_node, struct BStringMap_entry, tree_node); - - // remove - free_entry(o, e); -} - -const char * BStringMap_First (const BStringMap *o) -{ - DebugObject_Access(&o->d_obj); - - // get first - BAVLNode *tree_node = BAVL_GetFirst(&o->tree); - if (!tree_node) { - return NULL; - } - struct BStringMap_entry *e = UPPER_OBJECT(tree_node, struct BStringMap_entry, tree_node); - - return e->key; -} - -const char * BStringMap_Next (const BStringMap *o, const char *key) -{ - DebugObject_Access(&o->d_obj); - ASSERT(key) - ASSERT(BAVL_LookupExact(&o->tree, &key)) - - // get entry - struct BStringMap_entry *e = UPPER_OBJECT(BAVL_LookupExact(&o->tree, &key), struct BStringMap_entry, tree_node); - - // get next - BAVLNode *tree_node = BAVL_GetNext(&o->tree, &e->tree_node); - if (!tree_node) { - return NULL; - } - struct BStringMap_entry *next_e = UPPER_OBJECT(tree_node, struct BStringMap_entry, tree_node); - - return next_e->key; -} diff --git a/external/badvpn_dns/stringmap/BStringMap.h b/external/badvpn_dns/stringmap/BStringMap.h deleted file mode 100644 index 39b2071..0000000 --- a/external/badvpn_dns/stringmap/BStringMap.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file BStringMap.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STRINGMAP_BSTRINGMAP_H -#define BADVPN_STRINGMAP_BSTRINGMAP_H - -#include <misc/debug.h> -#include <structure/BAVL.h> -#include <base/DebugObject.h> - -struct BStringMap_entry { - char *key; - char *value; - BAVLNode tree_node; -}; - -typedef struct { - BAVL tree; - DebugObject d_obj; -} BStringMap; - -void BStringMap_Init (BStringMap *o); -int BStringMap_InitCopy (BStringMap *o, const BStringMap *src) WARN_UNUSED; -void BStringMap_Free (BStringMap *o); -const char * BStringMap_Get (const BStringMap *o, const char *key); -int BStringMap_Set (BStringMap *o, const char *key, const char *value) WARN_UNUSED; -void BStringMap_Unset (BStringMap *o, const char *key); -const char * BStringMap_First (const BStringMap *o); -const char * BStringMap_Next (const BStringMap *o, const char *key); - -#endif diff --git a/external/badvpn_dns/stringmap/CMakeLists.txt b/external/badvpn_dns/stringmap/CMakeLists.txt deleted file mode 100644 index 74dd8a1..0000000 --- a/external/badvpn_dns/stringmap/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(stringmap "" "" BStringMap.c) diff --git a/external/badvpn_dns/structure/BAVL.h b/external/badvpn_dns/structure/BAVL.h deleted file mode 100644 index 66993b3..0000000 --- a/external/badvpn_dns/structure/BAVL.h +++ /dev/null @@ -1,797 +0,0 @@ -/** - * @file BAVL.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * AVL tree. - */ - -#ifndef BADVPN_STRUCTURE_BAVL_H -#define BADVPN_STRUCTURE_BAVL_H - -//#define BAVL_DEBUG - -#include <stdint.h> -#include <stddef.h> - -#include <misc/debug.h> - -/** - * Handler function called by tree algorithms to compare two values. - * For any two values, the comparator must always return the same result. - * The <= relation defined by the comparator must be a total order. - * Values are obtained like that: - * - The value of a node in the tree, or a node that is being inserted is: - * (uint8_t *)node + offset. - * - The value being looked up is the same as given to the lookup function. - * - * @param user as in {@link BAVL_Init} - * @param val1 first value - * @param val2 second value - * @return -1 if val1 < val2, 0 if val1 = val2, 1 if val1 > val2 - */ -typedef int (*BAVL_comparator) (void *user, void *val1, void *val2); - -struct BAVLNode; - -/** - * AVL tree. - */ -typedef struct { - int offset; - BAVL_comparator comparator; - void *user; - struct BAVLNode *root; -} BAVL; - -/** - * AVL tree node. - */ -typedef struct BAVLNode { - struct BAVLNode *parent; - struct BAVLNode *link[2]; - int8_t balance; -#ifdef BAVL_COUNT - uint64_t count; -#endif -} BAVLNode; - -/** - * Initializes the tree. - * - * @param o tree to initialize - * @param offset offset of a value from its node - * @param comparator value comparator handler function - * @param user value to pass to comparator - */ -static void BAVL_Init (BAVL *o, int offset, BAVL_comparator comparator, void *user); - -/** - * Inserts a node into the tree. - * Must not be called from comparator. - * - * @param o the tree - * @param node uninitialized node to insert. Must have a valid value (its value - * may be passed to the comparator during insertion). - * @param ref if not NULL, will return (regardless if insertion succeeded): - * - the greatest node lesser than the inserted value, or (not in order) - * - the smallest node greater than the inserted value, or - * - NULL meaning there were no nodes in the tree. - * @param 1 on success, 0 if an element with an equal value is already in the tree - */ -static int BAVL_Insert (BAVL *o, BAVLNode *node, BAVLNode **ref); - -/** - * Removes a node from the tree. - * Must not be called from comparator. - * - * @param o the tree - * @param node node to remove - */ -static void BAVL_Remove (BAVL *o, BAVLNode *node); - -/** - * Checks if the tree is empty. - * Must not be called from comparator. - * - * @param o the tree - * @return 1 if empty, 0 if not - */ -static int BAVL_IsEmpty (const BAVL *o); - -/** - * Looks for a value in the tree. - * Must not be called from comparator. - * - * @param o the tree - * @param val value to look for - * @return If a node is in the thee with an equal value, that node. - * Else if the tree is not empty: - * - the greatest node lesser than the given value, or (not in order) - * - the smallest node greater than the given value. - * NULL if the tree is empty. - */ -static BAVLNode * BAVL_Lookup (const BAVL *o, void *val); - -/** - * Looks for a value in the tree. - * Must not be called from comparator. - * - * @param o the tree - * @param val value to look for - * @return If a node is in the thee with an equal value, that node. - * Else NULL. - */ -static BAVLNode * BAVL_LookupExact (const BAVL *o, void *val); - -/** - * Returns the smallest node in the tree, or NULL if the tree is empty. - * - * @param o the tree - * @return smallest node or NULL - */ -static BAVLNode * BAVL_GetFirst (const BAVL *o); - -/** - * Returns the greatest node in the tree, or NULL if the tree is empty. - * - * @param o the tree - * @return greatest node or NULL - */ -static BAVLNode * BAVL_GetLast (const BAVL *o); - -/** - * Returns the node that follows the given node, or NULL if it's the - * last node. - * - * @param o the tree - * @param n node - * @return next node, or NULL - */ -static BAVLNode * BAVL_GetNext (const BAVL *o, BAVLNode *n); - -/** - * Returns the node that precedes the given node, or NULL if it's the - * first node. - * - * @param o the tree - * @param n node - * @return previous node, or NULL - */ -static BAVLNode * BAVL_GetPrev (const BAVL *o, BAVLNode *n); - -#ifdef BAVL_COUNT -static uint64_t BAVL_Count (const BAVL *o); -static uint64_t BAVL_IndexOf (const BAVL *o, BAVLNode *n); -static BAVLNode * BAVL_GetAt (const BAVL *o, uint64_t index); -#endif - -static void BAVL_Verify (BAVL *o); - -#define BAVL_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) -#define BAVL_OPTNEG(_a, _neg) ((_neg) ? -(_a) : (_a)) - -static void * _BAVL_node_value (const BAVL *o, BAVLNode *n) -{ - return ((uint8_t *)n + o->offset); -} - -static int _BAVL_compare_values (const BAVL *o, void *v1, void *v2) -{ - int res = o->comparator(o->user, v1, v2); - - ASSERT(res == -1 || res == 0 || res == 1) - - return res; -} - -static int _BAVL_compare_nodes (BAVL *o, BAVLNode *n1, BAVLNode *n2) -{ - return _BAVL_compare_values(o, _BAVL_node_value(o, n1), _BAVL_node_value(o, n2)); -} - -#ifdef BAVL_AUTO_VERIFY -#define BAVL_ASSERT(_h) BAVL_Verify((_h)); -#else -#define BAVL_ASSERT(_h) -#endif - -static int _BAVL_assert_recurser (BAVL *o, BAVLNode *n) -{ - ASSERT_FORCE(n->balance >= -1) - ASSERT_FORCE(n->balance <= 1) - - int height_left = 0; - int height_right = 0; -#ifdef BAVL_COUNT - uint64_t count_left = 0; - uint64_t count_right = 0; -#endif - - // check left subtree - if (n->link[0]) { - // check parent link - ASSERT_FORCE(n->link[0]->parent == n) - // check binary search tree - ASSERT_FORCE(_BAVL_compare_nodes(o, n->link[0], n) == -1) - // recursively calculate height - height_left = _BAVL_assert_recurser(o, n->link[0]); -#ifdef BAVL_COUNT - count_left = n->link[0]->count; -#endif - } - - // check right subtree - if (n->link[1]) { - // check parent link - ASSERT_FORCE(n->link[1]->parent == n) - // check binary search tree - ASSERT_FORCE(_BAVL_compare_nodes(o, n->link[1], n) == 1) - // recursively calculate height - height_right = _BAVL_assert_recurser(o, n->link[1]); -#ifdef BAVL_COUNT - count_right = n->link[1]->count; -#endif - } - - // check balance factor - ASSERT_FORCE(n->balance == height_right - height_left) - -#ifdef BAVL_COUNT - // check count - ASSERT_FORCE(n->count == 1 + count_left + count_right) -#endif - - return (BAVL_MAX(height_left, height_right) + 1); -} - -#ifdef BAVL_COUNT -static void _BAVL_update_count_from_children (BAVLNode *n) -{ - n->count = 1 + (n->link[0] ? n->link[0]->count : 0) + (n->link[1] ? n->link[1]->count : 0); -} -#endif - -static void _BAVL_rotate (BAVL *tree, BAVLNode *r, uint8_t dir) -{ - BAVLNode *nr = r->link[!dir]; - - r->link[!dir] = nr->link[dir]; - if (r->link[!dir]) { - r->link[!dir]->parent = r; - } - nr->link[dir] = r; - nr->parent = r->parent; - if (nr->parent) { - nr->parent->link[r == r->parent->link[1]] = nr; - } else { - tree->root = nr; - } - r->parent = nr; - -#ifdef BAVL_COUNT - // update counts - _BAVL_update_count_from_children(r); // first r! - _BAVL_update_count_from_children(nr); -#endif -} - -static BAVLNode * _BAVL_subtree_max (BAVLNode *n) -{ - ASSERT(n) - while (n->link[1]) { - n = n->link[1]; - } - return n; -} - -static void _BAVL_replace_subtree (BAVL *tree, BAVLNode *dest, BAVLNode *n) -{ - ASSERT(dest) - - if (dest->parent) { - dest->parent->link[dest == dest->parent->link[1]] = n; - } else { - tree->root = n; - } - if (n) { - n->parent = dest->parent; - } - -#ifdef BAVL_COUNT - // update counts - for (BAVLNode *c = dest->parent; c; c = c->parent) { - ASSERT(c->count >= dest->count) - c->count -= dest->count; - if (n) { - ASSERT(n->count <= UINT64_MAX - c->count) - c->count += n->count; - } - } -#endif -} - -static void _BAVL_swap_nodes (BAVL *tree, BAVLNode *n1, BAVLNode *n2) -{ - if (n2->parent == n1 || n1->parent == n2) { - // when the nodes are directly connected we need special handling - // make sure n1 is above n2 - if (n1->parent == n2) { - BAVLNode *t = n1; - n1 = n2; - n2 = t; - } - - uint8_t side = (n2 == n1->link[1]); - BAVLNode *c = n1->link[!side]; - - if (n1->link[0] = n2->link[0]) { - n1->link[0]->parent = n1; - } - if (n1->link[1] = n2->link[1]) { - n1->link[1]->parent = n1; - } - - if (n2->parent = n1->parent) { - n2->parent->link[n1 == n1->parent->link[1]] = n2; - } else { - tree->root = n2; - } - - n2->link[side] = n1; - n1->parent = n2; - if (n2->link[!side] = c) { - c->parent = n2; - } - } else { - BAVLNode *temp; - - // swap parents - temp = n1->parent; - if (n1->parent = n2->parent) { - n1->parent->link[n2 == n2->parent->link[1]] = n1; - } else { - tree->root = n1; - } - if (n2->parent = temp) { - n2->parent->link[n1 == temp->link[1]] = n2; - } else { - tree->root = n2; - } - - // swap left children - temp = n1->link[0]; - if (n1->link[0] = n2->link[0]) { - n1->link[0]->parent = n1; - } - if (n2->link[0] = temp) { - n2->link[0]->parent = n2; - } - - // swap right children - temp = n1->link[1]; - if (n1->link[1] = n2->link[1]) { - n1->link[1]->parent = n1; - } - if (n2->link[1] = temp) { - n2->link[1]->parent = n2; - } - } - - // swap balance factors - int8_t b = n1->balance; - n1->balance = n2->balance; - n2->balance = b; - -#ifdef BAVL_COUNT - // swap counts - uint64_t c = n1->count; - n1->count = n2->count; - n2->count = c; -#endif -} - -static void _BAVL_rebalance (BAVL *o, BAVLNode *node, uint8_t side, int8_t deltac) -{ - ASSERT(side == 0 || side == 1) - ASSERT(deltac >= -1 && deltac <= 1) - ASSERT(node->balance >= -1 && node->balance <= 1) - - // if no subtree changed its height, no more rebalancing is needed - if (deltac == 0) { - return; - } - - // calculate how much our height changed - int8_t delta = BAVL_MAX(deltac, BAVL_OPTNEG(node->balance, side)) - BAVL_MAX(0, BAVL_OPTNEG(node->balance, side)); - ASSERT(delta >= -1 && delta <= 1) - - // update our balance factor - node->balance -= BAVL_OPTNEG(deltac, side); - - BAVLNode *child; - BAVLNode *gchild; - - // perform transformations if the balance factor is wrong - if (node->balance == 2 || node->balance == -2) { - uint8_t bside; - int8_t bsidef; - if (node->balance == 2) { - bside = 1; - bsidef = 1; - } else { - bside = 0; - bsidef = -1; - } - - ASSERT(node->link[bside]) - child = node->link[bside]; - switch (child->balance * bsidef) { - case 1: - _BAVL_rotate(o, node, !bside); - node->balance = 0; - child->balance = 0; - node = child; - delta -= 1; - break; - case 0: - _BAVL_rotate(o, node, !bside); - node->balance = 1 * bsidef; - child->balance = -1 * bsidef; - node = child; - break; - case -1: - ASSERT(child->link[!bside]) - gchild = child->link[!bside]; - _BAVL_rotate(o, child, bside); - _BAVL_rotate(o, node, !bside); - node->balance = -BAVL_MAX(0, gchild->balance * bsidef) * bsidef; - child->balance = BAVL_MAX(0, -gchild->balance * bsidef) * bsidef; - gchild->balance = 0; - node = gchild; - delta -= 1; - break; - default: - ASSERT(0); - } - } - - ASSERT(delta >= -1 && delta <= 1) - // Transformations above preserve this. Proof: - // - if a child subtree gained 1 height and rebalancing was needed, - // it was the heavier subtree. Then delta was was originally 1, because - // the heaviest subtree gained one height. If the transformation reduces - // delta by one, it becomes 0. - // - if a child subtree lost 1 height and rebalancing was needed, it - // was the lighter subtree. Then delta was originally 0, because - // the height of the heaviest subtree was unchanged. If the transformation - // reduces delta by one, it becomes -1. - - if (node->parent) { - _BAVL_rebalance(o, node->parent, node == node->parent->link[1], delta); - } -} - -void BAVL_Init (BAVL *o, int offset, BAVL_comparator comparator, void *user) -{ - o->offset = offset; - o->comparator = comparator; - o->user = user; - o->root = NULL; - - BAVL_ASSERT(o) -} - -int BAVL_Insert (BAVL *o, BAVLNode *node, BAVLNode **ref) -{ - // insert to root? - if (!o->root) { - o->root = node; - node->parent = NULL; - node->link[0] = NULL; - node->link[1] = NULL; - node->balance = 0; -#ifdef BAVL_COUNT - node->count = 1; -#endif - - BAVL_ASSERT(o) - - if (ref) { - *ref = NULL; - } - return 1; - } - - // find node to insert to - BAVLNode *c = o->root; - int side; - while (1) { - // compare - int comp = _BAVL_compare_nodes(o, node, c); - - // have we found a node that compares equal? - if (comp == 0) { - if (ref) { - *ref = c; - } - return 0; - } - - side = (comp == 1); - - // have we reached a leaf? - if (!c->link[side]) { - break; - } - - c = c->link[side]; - } - - // insert - c->link[side] = node; - node->parent = c; - node->link[0] = NULL; - node->link[1] = NULL; - node->balance = 0; -#ifdef BAVL_COUNT - node->count = 1; -#endif - -#ifdef BAVL_COUNT - // update counts - for (BAVLNode *p = c; p; p = p->parent) { - ASSERT(p->count < UINT64_MAX) - p->count++; - } -#endif - - // rebalance - _BAVL_rebalance(o, c, side, 1); - - BAVL_ASSERT(o) - - if (ref) { - *ref = c; - } - return 1; -} - -void BAVL_Remove (BAVL *o, BAVLNode *node) -{ - // if we have both subtrees, swap the node and the largest node - // in the left subtree, so we have at most one subtree - if (node->link[0] && node->link[1]) { - // find the largest node in the left subtree - BAVLNode *max = _BAVL_subtree_max(node->link[0]); - // swap the nodes - _BAVL_swap_nodes(o, node, max); - } - - // have at most one child now - ASSERT(!(node->link[0] && node->link[1])) - - BAVLNode *parent = node->parent; - BAVLNode *child = (node->link[0] ? node->link[0] : node->link[1]); - - if (parent) { - // remember on which side node is - int side = (node == parent->link[1]); - // replace node with child - _BAVL_replace_subtree(o, node, child); - // rebalance - _BAVL_rebalance(o, parent, side, -1); - } else { - // replace node with child - _BAVL_replace_subtree(o, node, child); - } - - BAVL_ASSERT(o) -} - -int BAVL_IsEmpty (const BAVL *o) -{ - return (!o->root); -} - -BAVLNode * BAVL_Lookup (const BAVL *o, void *val) -{ - if (!o->root) { - return NULL; - } - - BAVLNode *c = o->root; - while (1) { - // compare - int comp = _BAVL_compare_values(o, val, _BAVL_node_value(o, c)); - - // have we found a node that compares equal? - if (comp == 0) { - return c; - } - - int side = (comp == 1); - - // have we reached a leaf? - if (!c->link[side]) { - return c; - } - - c = c->link[side]; - } -} - -BAVLNode * BAVL_LookupExact (const BAVL *o, void *val) -{ - if (!o->root) { - return NULL; - } - - BAVLNode *c = o->root; - while (1) { - // compare - int comp = _BAVL_compare_values(o, val, _BAVL_node_value(o, c)); - - // have we found a node that compares equal? - if (comp == 0) { - return c; - } - - int side = (comp == 1); - - // have we reached a leaf? - if (!c->link[side]) { - return NULL; - } - - c = c->link[side]; - } -} - -BAVLNode * BAVL_GetFirst (const BAVL *o) -{ - if (!o->root) { - return NULL; - } - - BAVLNode *n = o->root; - while (n->link[0]) { - n = n->link[0]; - } - - return n; -} - -BAVLNode * BAVL_GetLast (const BAVL *o) -{ - if (!o->root) { - return NULL; - } - - BAVLNode *n = o->root; - while (n->link[1]) { - n = n->link[1]; - } - - return n; -} - -BAVLNode * BAVL_GetNext (const BAVL *o, BAVLNode *n) -{ - if (n->link[1]) { - n = n->link[1]; - while (n->link[0]) { - n = n->link[0]; - } - } else { - while (n->parent && n == n->parent->link[1]) { - n = n->parent; - } - n = n->parent; - } - - return n; -} - -BAVLNode * BAVL_GetPrev (const BAVL *o, BAVLNode *n) -{ - if (n->link[0]) { - n = n->link[0]; - while (n->link[1]) { - n = n->link[1]; - } - } else { - while (n->parent && n == n->parent->link[0]) { - n = n->parent; - } - n = n->parent; - } - - return n; -} - -#ifdef BAVL_COUNT - -static uint64_t BAVL_Count (const BAVL *o) -{ - return (o->root ? o->root->count : 0); -} - -static uint64_t BAVL_IndexOf (const BAVL *o, BAVLNode *n) -{ - uint64_t index = (n->link[0] ? n->link[0]->count : 0); - - for (BAVLNode *c = n; c->parent; c = c->parent) { - if (c == c->parent->link[1]) { - ASSERT(c->parent->count > c->count) - ASSERT(c->parent->count - c->count <= UINT64_MAX - index) - index += c->parent->count - c->count; - } - } - - return index; -} - -static BAVLNode * BAVL_GetAt (const BAVL *o, uint64_t index) -{ - if (index >= BAVL_Count(o)) { - return NULL; - } - - BAVLNode *c = o->root; - - while (1) { - ASSERT(c) - ASSERT(index < c->count) - - uint64_t left_count = (c->link[0] ? c->link[0]->count : 0); - - if (index == left_count) { - return c; - } - - if (index < left_count) { - c = c->link[0]; - } else { - c = c->link[1]; - index -= left_count + 1; - } - } -} - -#endif - -static void BAVL_Verify (BAVL *o) -{ - if (o->root) { - ASSERT(!o->root->parent) - _BAVL_assert_recurser(o, o->root); - } -} - -#endif diff --git a/external/badvpn_dns/structure/CAvl.h b/external/badvpn_dns/structure/CAvl.h deleted file mode 100644 index ea33a3e..0000000 --- a/external/badvpn_dns/structure/CAvl.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file CAvl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_CAVL_H -#define BADVPN_CAVL_H - -#include <misc/debug.h> -#include <misc/merge.h> - -#endif diff --git a/external/badvpn_dns/structure/CAvl_decl.h b/external/badvpn_dns/structure/CAvl_decl.h deleted file mode 100644 index 7d54a81..0000000 --- a/external/badvpn_dns/structure/CAvl_decl.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file CAvl_decl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CAvl_header.h" - -typedef struct { - CAvlLink root; -} CAvl; - -typedef struct { - CAvlEntry *ptr; - CAvlLink link; -} CAvlRef; - -static int CAvlIsNullRef (CAvlRef node); -static int CAvlIsValidRef (CAvlRef node); -static CAvlRef CAvlDeref (CAvlArg arg, CAvlLink link); - -static void CAvl_Init (CAvl *o); -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES -static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlRef node, CAvlRef *out_ref); -#else -static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlRef node, CAvlCount index); -#endif -static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlRef node); -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && !CAVL_PARAM_FEATURE_NOKEYS -static CAvlRef CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key); -static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key); -static CAvlRef CAvl_GetFirstGreater (const CAvl *o, CAvlArg arg, CAvlKey key); -static CAvlRef CAvl_GetLastLesser (const CAvl *o, CAvlArg arg, CAvlKey key); -static CAvlRef CAvl_GetFirstGreaterEqual (const CAvl *o, CAvlArg arg, CAvlKey key); -static CAvlRef CAvl_GetLastLesserEqual (const CAvl *o, CAvlArg arg, CAvlKey key); -#endif -static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg); -static CAvlRef CAvl_GetLast (const CAvl *o, CAvlArg arg); -static CAvlRef CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlRef node); -static CAvlRef CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlRef node); -static int CAvl_IsEmpty (const CAvl *o); -static void CAvl_Verify (const CAvl *o, CAvlArg arg); -#if CAVL_PARAM_FEATURE_COUNTS -static CAvlCount CAvl_Count (const CAvl *o, CAvlArg arg); -static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlRef node); -static CAvlRef CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index); -#endif -#if CAVL_PARAM_FEATURE_ASSOC -static CAvlAssoc CAvl_AssocSum (const CAvl *o, CAvlArg arg); -static CAvlAssoc CAvl_ExclusiveAssocPrefixSum (const CAvl *o, CAvlArg arg, CAvlRef node); -static CAvlRef CAvl_FindLastExclusiveAssocPrefixSumLesserEqual (const CAvl *o, CAvlArg arg, CAvlAssoc sum, int (*sum_less) (void *, CAvlAssoc, CAvlAssoc), void *user); -#endif - -#include "CAvl_footer.h" diff --git a/external/badvpn_dns/structure/CAvl_footer.h b/external/badvpn_dns/structure/CAvl_footer.h deleted file mode 100644 index 43b85c3..0000000 --- a/external/badvpn_dns/structure/CAvl_footer.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file CAvl_footer.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#undef CAVL_PARAM_NAME -#undef CAVL_PARAM_FEATURE_COUNTS -#undef CAVL_PARAM_FEATURE_KEYS_ARE_INDICES -#undef CAVL_PARAM_FEATURE_NOKEYS -#undef CAVL_PARAM_FEATURE_ASSOC -#undef CAVL_PARAM_TYPE_ENTRY -#undef CAVL_PARAM_TYPE_LINK -#undef CAVL_PARAM_TYPE_KEY -#undef CAVL_PARAM_TYPE_ARG -#undef CAVL_PARAM_TYPE_COUNT -#undef CAVL_PARAM_TYPE_ASSOC -#undef CAVL_PARAM_VALUE_COUNT_MAX -#undef CAVL_PARAM_VALUE_NULL -#undef CAVL_PARAM_VALUE_ASSOC_ZERO -#undef CAVL_PARAM_FUN_DEREF -#undef CAVL_PARAM_FUN_COMPARE_ENTRIES -#undef CAVL_PARAM_FUN_COMPARE_KEY_ENTRY -#undef CAVL_PARAM_FUN_ASSOC_VALUE -#undef CAVL_PARAM_FUN_ASSOC_OPER -#undef CAVL_PARAM_MEMBER_CHILD -#undef CAVL_PARAM_MEMBER_BALANCE -#undef CAVL_PARAM_MEMBER_PARENT -#undef CAVL_PARAM_MEMBER_COUNT -#undef CAVL_PARAM_MEMBER_ASSOC - -#undef CAvl -#undef CAvlEntry -#undef CAvlLink -#undef CAvlRef -#undef CAvlArg -#undef CAvlKey -#undef CAvlCount -#undef CAvlAssoc - -#undef CAvlIsNullRef -#undef CAvlIsValidRef -#undef CAvlDeref - -#undef CAvl_Init -#undef CAvl_Insert -#undef CAvl_InsertAt -#undef CAvl_Remove -#undef CAvl_Lookup -#undef CAvl_LookupExact -#undef CAvl_GetFirstGreater -#undef CAvl_GetLastLesser -#undef CAvl_GetFirstGreaterEqual -#undef CAvl_GetLastLesserEqual -#undef CAvl_GetFirst -#undef CAvl_GetLast -#undef CAvl_GetNext -#undef CAvl_GetPrev -#undef CAvl_IsEmpty -#undef CAvl_Verify -#undef CAvl_Count -#undef CAvl_IndexOf -#undef CAvl_GetAt -#undef CAvl_AssocSum -#undef CAvl_ExclusiveAssocPrefixSum -#undef CAvl_FindLastExclusiveAssocPrefixSumLesserEqual - -#undef CAvl_link -#undef CAvl_balance -#undef CAvl_parent -#undef CAvl_count -#undef CAvl_assoc -#undef CAvl_nulllink -#undef CAvl_nullref -#undef CAvl_compare_entries -#undef CAvl_compare_key_entry -#undef CAvl_compute_node_assoc -#undef CAvl_check_parent -#undef CAvl_verify_recurser -#undef CAvl_assert_tree -#undef CAvl_update_count_from_children -#undef CAvl_rotate -#undef CAvl_subtree_min -#undef CAvl_subtree_max -#undef CAvl_replace_subtree_fix_assoc -#undef CAvl_swap_for_remove -#undef CAvl_rebalance -#undef CAvl_child_count -#undef CAvl_MAX -#undef CAvl_OPTNEG diff --git a/external/badvpn_dns/structure/CAvl_header.h b/external/badvpn_dns/structure/CAvl_header.h deleted file mode 100644 index 91ea7df..0000000 --- a/external/badvpn_dns/structure/CAvl_header.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file CAvl_header.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Preprocessor inputs: -// CAVL_PARAM_NAME - name of this data structure -// CAVL_PARAM_FEATURE_COUNTS - whether to keep count information (0 or 1) -// CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - (0 or 1) whether to assume the keys are entry indices -// (number of entries lesser than given entry). If yes, CAVL_PARAM_TYPE_KEY is unused. -// Requires CAVL_PARAM_FEATURE_COUNTS. -// CAVL_PARAM_FEATURE_NOKEYS - define to 1 if there is no need for a lookup operation -// CAVL_PARAM_FEATURE_ASSOC - define to 1 for computation of an associative operation on subtrees. -// If enabled, the following macros must be defined: CAVL_PARAM_TYPE_ASSOC, -// CAVL_PARAM_VALUE_ASSOC_ZERO, CAVL_PARAM_FUN_ASSOC_VALUE, -// CAVL_PARAM_FUN_ASSOC_OPER, CAVL_PARAM_MEMBER_ASSOC. -// CAVL_PARAM_TYPE_ENTRY - type of entry -// CAVL_PARAM_TYPE_LINK - type of entry link (usually pointer or index) -// CAVL_PARAM_TYPE_KEY - type of key (only if not CAVL_PARAM_FEATURE_KEYS_ARE_INDICES and -// not CAVL_PARAM_FEATURE_NOKEYS) -// CAVL_PARAM_TYPE_ARG - type of argument pass through to callbacks -// CAVL_PARAM_TYPE_COUNT - type of count (only if CAVL_PARAM_FEATURE_COUNTS) -// CAVL_PARAM_TYPE_ASSOC - type of associative operation result -// CAVL_PARAM_VALUE_COUNT_MAX - maximum value of count (type is CAVL_PARAM_TYPE_COUNT) -// CAVL_PARAM_VALUE_NULL - value of invalid link (type is CAVL_PARAM_TYPE_LINK) -// CAVL_PARAM_VALUE_ASSOC_ZERO - zero value for associative operation (type is CAVL_PARAM_TYPE_ASSOC). -// This must be both a left- and right-identity for the associative operation. -// CAVL_PARAM_FUN_DEREF(arg, link) - dereference a non-null link; returns pointer to CAVL_PARAM_TYPE_LINK -// CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) - compare to entries; returns -1/0/1 -// CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) - compare key and entry; returns -1/0/1 -// CAVL_PARAM_FUN_ASSOC_VALUE(arg, entry) - get value of a node for associative operation. -// The result will be cast to CAVL_PARAM_TYPE_ASSOC. -// CAVL_PARAM_FUN_ASSOC_OPER(arg, value1, value2) - compute the associative operation on two values. -// The type of the two values is CAVL_PARAM_TYPE_ASSOC, and the result will be cast to -// CAVL_PARAM_TYPE_ASSOC. -// CAVL_PARAM_MEMBER_CHILD - name of the child member in entry (type is CAVL_PARAM_TYPE_LINK[2]) -// CAVL_PARAM_MEMBER_BALANCE - name of the balance member in entry (type is any signed integer) -// CAVL_PARAM_MEMBER_PARENT - name of the parent member in entry (type is CAVL_PARAM_TYPE_LINK) -// CAVL_PARAM_MEMBER_COUNT - name of the count member in entry (type is CAVL_PARAM_TYPE_COUNT) -// (only if CAVL_PARAM_FEATURE_COUNTS) -// CAVL_PARAM_MEMBER_ASSOC - name of assoc member in entry (type is CAVL_PARAM_TYPE_ASSOC) - -#ifndef BADVPN_CAVL_H -#error CAvl.h has not been included -#endif - -#if CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && !CAVL_PARAM_FEATURE_COUNTS -#error CAVL_PARAM_FEATURE_KEYS_ARE_INDICES requires CAVL_PARAM_FEATURE_COUNTS -#endif - -#if CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && CAVL_PARAM_FEATURE_NOKEYS -#error CAVL_PARAM_FEATURE_KEYS_ARE_INDICES and CAVL_PARAM_FEATURE_NOKEYS cannot be used together -#endif - -// types -#define CAvl CAVL_PARAM_NAME -#define CAvlEntry CAVL_PARAM_TYPE_ENTRY -#define CAvlLink CAVL_PARAM_TYPE_LINK -#define CAvlRef MERGE(CAVL_PARAM_NAME, Ref) -#define CAvlArg CAVL_PARAM_TYPE_ARG -#define CAvlKey CAVL_PARAM_TYPE_KEY -#define CAvlCount CAVL_PARAM_TYPE_COUNT -#define CAvlAssoc CAVL_PARAM_TYPE_ASSOC - -// non-object public functions -#define CAvlIsNullRef MERGE(CAvl, IsNullRef) -#define CAvlIsValidRef MERGE(CAvl, IsValidRef) -#define CAvlDeref MERGE(CAvl, Deref) - -// public functions -#define CAvl_Init MERGE(CAvl, _Init) -#define CAvl_Insert MERGE(CAvl, _Insert) -#define CAvl_InsertAt MERGE(CAvl, _InsertAt) -#define CAvl_Remove MERGE(CAvl, _Remove) -#define CAvl_Lookup MERGE(CAvl, _Lookup) -#define CAvl_LookupExact MERGE(CAvl, _LookupExact) -#define CAvl_GetFirstGreater MERGE(CAvl, _GetFirstGreater) -#define CAvl_GetLastLesser MERGE(CAvl, _GetLastLesser) -#define CAvl_GetFirstGreaterEqual MERGE(CAvl, _GetFirstGreaterEqual) -#define CAvl_GetLastLesserEqual MERGE(CAvl, _GetLastLesserEqual) -#define CAvl_GetFirst MERGE(CAvl, _GetFirst) -#define CAvl_GetLast MERGE(CAvl, _GetLast) -#define CAvl_GetNext MERGE(CAvl, _GetNext) -#define CAvl_GetPrev MERGE(CAvl, _GetPrev) -#define CAvl_IsEmpty MERGE(CAvl, _IsEmpty) -#define CAvl_Verify MERGE(CAvl, _Verify) -#define CAvl_Count MERGE(CAvl, _Count) -#define CAvl_IndexOf MERGE(CAvl, _IndexOf) -#define CAvl_GetAt MERGE(CAvl, _GetAt) -#define CAvl_AssocSum MERGE(CAvl, _AssocSum) -#define CAvl_ExclusiveAssocPrefixSum MERGE(CAvl, _ExclusiveAssocPrefixSum) -#define CAvl_FindLastExclusiveAssocPrefixSumLesserEqual MERGE(CAvl, _FindLastExclusiveAssocPrefixSumLesserEqual) - -// private stuff -#define CAvl_link(entry) ((entry).ptr->CAVL_PARAM_MEMBER_CHILD) -#define CAvl_balance(entry) ((entry).ptr->CAVL_PARAM_MEMBER_BALANCE) -#define CAvl_parent(entry) ((entry).ptr->CAVL_PARAM_MEMBER_PARENT) -#define CAvl_count(entry) ((entry).ptr->CAVL_PARAM_MEMBER_COUNT) -#define CAvl_assoc(entry) ((entry).ptr->CAVL_PARAM_MEMBER_ASSOC) -#define CAvl_nulllink MERGE(CAvl, __nulllink) -#define CAvl_nullref MERGE(CAvl, __nullref) -#define CAvl_compare_entries MERGE(CAVL_PARAM_NAME, _compare_entries) -#define CAvl_compare_key_entry MERGE(CAVL_PARAM_NAME, _compare_key_entry) -#define CAvl_compute_node_assoc MERGE(CAVL_PARAM_NAME, _compute_node_assoc) -#define CAvl_check_parent MERGE(CAVL_PARAM_NAME, _check_parent) -#define CAvl_verify_recurser MERGE(CAVL_PARAM_NAME, _verify_recurser) -#define CAvl_assert_tree MERGE(CAVL_PARAM_NAME, _assert_tree) -#define CAvl_update_count_from_children MERGE(CAVL_PARAM_NAME, _update_count_from_children) -#define CAvl_rotate MERGE(CAVL_PARAM_NAME, _rotate) -#define CAvl_subtree_min MERGE(CAVL_PARAM_NAME, _subtree_min) -#define CAvl_subtree_max MERGE(CAVL_PARAM_NAME, _subtree_max) -#define CAvl_replace_subtree_fix_assoc MERGE(CAVL_PARAM_NAME, _replace_subtree_fix_counts) -#define CAvl_swap_for_remove MERGE(CAVL_PARAM_NAME, _swap_entries) -#define CAvl_rebalance MERGE(CAVL_PARAM_NAME, _rebalance) -#define CAvl_child_count MERGE(CAvl, __child_count) -#define CAvl_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) -#define CAvl_OPTNEG(_a, _neg) ((_neg) ? -(_a) : (_a)) diff --git a/external/badvpn_dns/structure/CAvl_impl.h b/external/badvpn_dns/structure/CAvl_impl.h deleted file mode 100644 index 984bdea..0000000 --- a/external/badvpn_dns/structure/CAvl_impl.h +++ /dev/null @@ -1,949 +0,0 @@ -/** - * @file CAvl_impl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CAvl_header.h" - -static CAvlLink CAvl_nulllink (void) -{ - return CAVL_PARAM_VALUE_NULL; -} - -static CAvlRef CAvl_nullref (void) -{ - CAvlRef n; - n.link = CAVL_PARAM_VALUE_NULL; - n.ptr = NULL; - return n; -} - -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - -static int CAvl_compare_entries (CAvlArg arg, CAvlRef node1, CAvlRef node2) -{ - int res = CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, node1, node2); - ASSERT(res >= -1) - ASSERT(res <= 1) - - return res; -} - -#if !CAVL_PARAM_FEATURE_NOKEYS - -static int CAvl_compare_key_entry (CAvlArg arg, CAvlKey key1, CAvlRef node2) -{ - int res = CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, node2); - ASSERT(res >= -1) - ASSERT(res <= 1) - - return res; -} - -#endif - -#endif - -#if CAVL_PARAM_FEATURE_ASSOC - -static CAvlAssoc CAvl_compute_node_assoc (CAvlArg arg, CAvlRef node) -{ - CAvlAssoc sum = CAVL_PARAM_FUN_ASSOC_VALUE(arg, node); - if (CAvl_link(node)[0] != CAvl_nulllink()) { - sum = CAVL_PARAM_FUN_ASSOC_OPER(arg, CAvl_assoc(CAvlDeref(arg, CAvl_link(node)[0])), sum); - } - if (CAvl_link(node)[1] != CAvl_nulllink()) { - sum = CAVL_PARAM_FUN_ASSOC_OPER(arg, sum, CAvl_assoc(CAvlDeref(arg, CAvl_link(node)[1]))); - } - return sum; -} - -#endif - -static int CAvl_check_parent (CAvlRef p, CAvlRef c) -{ - return (p.link == CAvl_parent(c)) && (p.link == CAvl_nulllink() || c.link == CAvl_link(p)[0] || c.link == CAvl_link(p)[1]); -} - -static int CAvl_verify_recurser (CAvlArg arg, CAvlRef n) -{ - ASSERT_FORCE(CAvl_balance(n) >= -1) - ASSERT_FORCE(CAvl_balance(n) <= 1) - - int height_left = 0; - int height_right = 0; -#if CAVL_PARAM_FEATURE_COUNTS - CAvlCount count_left = 0; - CAvlCount count_right = 0; -#endif - - // check left subtree - if (CAvl_link(n)[0] != CAvl_nulllink()) { - // check parent link - ASSERT_FORCE(CAvl_parent(CAvlDeref(arg, CAvl_link(n)[0])) == n.link) - // check binary search tree -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - ASSERT_FORCE(CAvl_compare_entries(arg, CAvlDeref(arg, CAvl_link(n)[0]), n) == -1) -#endif - // recursively calculate height - height_left = CAvl_verify_recurser(arg, CAvlDeref(arg, CAvl_link(n)[0])); -#if CAVL_PARAM_FEATURE_COUNTS - count_left = CAvl_count(CAvlDeref(arg, CAvl_link(n)[0])); -#endif - } - - // check right subtree - if (CAvl_link(n)[1] != CAvl_nulllink()) { - // check parent link - ASSERT_FORCE(CAvl_parent(CAvlDeref(arg, CAvl_link(n)[1])) == n.link) - // check binary search tree -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - ASSERT_FORCE(CAvl_compare_entries(arg, CAvlDeref(arg, CAvl_link(n)[1]), n) == 1) -#endif - // recursively calculate height - height_right = CAvl_verify_recurser(arg, CAvlDeref(arg, CAvl_link(n)[1])); -#if CAVL_PARAM_FEATURE_COUNTS - count_right = CAvl_count(CAvlDeref(arg, CAvl_link(n)[1])); -#endif - } - - // check balance factor - ASSERT_FORCE(CAvl_balance(n) == height_right - height_left) - -#if CAVL_PARAM_FEATURE_COUNTS - // check count - ASSERT_FORCE(CAvl_count(n) == 1 + count_left + count_right) -#endif - -#if CAVL_PARAM_FEATURE_ASSOC - // check assoc - ASSERT_FORCE(CAvl_assoc(n) == CAvl_compute_node_assoc(arg, n)) -#endif - - return CAvl_MAX(height_left, height_right) + 1; -} - -static void CAvl_assert_tree (CAvl *o, CAvlArg arg) -{ -#ifdef CAVL_AUTO_VERIFY - CAvl_Verify(o, arg); -#endif -} - -#if CAVL_PARAM_FEATURE_COUNTS -static void CAvl_update_count_from_children (CAvlArg arg, CAvlRef n) -{ - CAvlCount left_count = CAvl_link(n)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[0])) : 0; - CAvlCount right_count = CAvl_link(n)[1] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[1])) : 0; - CAvl_count(n) = 1 + left_count + right_count; -} -#endif - -static void CAvl_rotate (CAvl *o, CAvlArg arg, CAvlRef r, uint8_t dir, CAvlRef r_parent) -{ - ASSERT(CAvl_check_parent(r_parent, r)) - CAvlRef nr = CAvlDeref(arg, CAvl_link(r)[!dir]); - - CAvl_link(r)[!dir] = CAvl_link(nr)[dir]; - if (CAvl_link(r)[!dir] != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(r)[!dir])) = r.link; - } - CAvl_link(nr)[dir] = r.link; - CAvl_parent(nr) = r_parent.link; - if (r_parent.link != CAvl_nulllink()) { - CAvl_link(r_parent)[r.link == CAvl_link(r_parent)[1]] = nr.link; - } else { - o->root = nr.link; - } - CAvl_parent(r) = nr.link; - -#if CAVL_PARAM_FEATURE_COUNTS - CAvl_update_count_from_children(arg, r); - CAvl_update_count_from_children(arg, nr); -#endif - -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(r) = CAvl_compute_node_assoc(arg, r); - CAvl_assoc(nr) = CAvl_compute_node_assoc(arg, nr); -#endif -} - -static CAvlRef CAvl_subtree_min (CAvlArg arg, CAvlRef n) -{ - ASSERT(n.link != CAvl_nulllink()) - - while (CAvl_link(n)[0] != CAvl_nulllink()) { - n = CAvlDeref(arg, CAvl_link(n)[0]); - } - - return n; -} - -static CAvlRef CAvl_subtree_max (CAvlArg arg, CAvlRef n) -{ - ASSERT(n.link != CAvl_nulllink()) - - while (CAvl_link(n)[1] != CAvl_nulllink()) { - n = CAvlDeref(arg, CAvl_link(n)[1]); - } - - return n; -} - -static void CAvl_replace_subtree_fix_assoc (CAvl *o, CAvlArg arg, CAvlRef dest, CAvlRef n, CAvlRef dest_parent) -{ - ASSERT(dest.link != CAvl_nulllink()) - ASSERT(CAvl_check_parent(dest_parent, dest)) - - if (dest_parent.link != CAvl_nulllink()) { - CAvl_link(dest_parent)[dest.link == CAvl_link(dest_parent)[1]] = n.link; - } else { - o->root = n.link; - } - if (n.link != CAvl_nulllink()) { - CAvl_parent(n) = CAvl_parent(dest); - } - -#if CAVL_PARAM_FEATURE_COUNTS || CAVL_PARAM_FEATURE_ASSOC - for (CAvlRef c = dest_parent; c.link != CAvl_nulllink(); c = CAvlDeref(arg, CAvl_parent(c))) { -#if CAVL_PARAM_FEATURE_COUNTS - ASSERT(CAvl_count(c) >= CAvl_count(dest)) - CAvl_count(c) -= CAvl_count(dest); - if (n.link != CAvl_nulllink()) { - ASSERT(CAvl_count(n) <= CAVL_PARAM_VALUE_COUNT_MAX - CAvl_count(c)) - CAvl_count(c) += CAvl_count(n); - } -#endif -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(c) = CAvl_compute_node_assoc(arg, c); -#endif - } -#endif -} - -static void CAvl_swap_for_remove (CAvl *o, CAvlArg arg, CAvlRef node, CAvlRef enode, CAvlRef node_parent, CAvlRef enode_parent) -{ - ASSERT(CAvl_check_parent(node_parent, node)) - ASSERT(CAvl_check_parent(enode_parent, enode)) - - if (enode_parent.link == node.link) { - // when the nodes are directly connected we need special handling - - uint8_t side = (enode.link == CAvl_link(node)[1]); - CAvlRef c = CAvlDeref(arg, CAvl_link(node)[!side]); - - if ((CAvl_link(node)[0] = CAvl_link(enode)[0]) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(node)[0])) = node.link; - } - if ((CAvl_link(node)[1] = CAvl_link(enode)[1]) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(node)[1])) = node.link; - } - - CAvl_parent(enode) = CAvl_parent(node); - if (node_parent.link != CAvl_nulllink()) { - CAvl_link(node_parent)[node.link == CAvl_link(node_parent)[1]] = enode.link; - } else { - o->root = enode.link; - } - - CAvl_link(enode)[side] = node.link; - CAvl_parent(node) = enode.link; - if ((CAvl_link(enode)[!side] = c.link) != CAvl_nulllink()) { - CAvl_parent(c) = enode.link; - } - } else { - CAvlRef temp; - - // swap parents - temp = node_parent; - CAvl_parent(node) = CAvl_parent(enode); - if (enode_parent.link != CAvl_nulllink()) { - CAvl_link(enode_parent)[enode.link == CAvl_link(enode_parent)[1]] = node.link; - } else { - o->root = node.link; - } - CAvl_parent(enode) = temp.link; - if (temp.link != CAvl_nulllink()) { - CAvl_link(temp)[node.link == CAvl_link(temp)[1]] = enode.link; - } else { - o->root = enode.link; - } - - // swap left children - temp = CAvlDeref(arg, CAvl_link(node)[0]); - if ((CAvl_link(node)[0] = CAvl_link(enode)[0]) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(node)[0])) = node.link; - } - if ((CAvl_link(enode)[0] = temp.link) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(enode)[0])) = enode.link; - } - - // swap right children - temp = CAvlDeref(arg, CAvl_link(node)[1]); - if ((CAvl_link(node)[1] = CAvl_link(enode)[1]) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(node)[1])) = node.link; - } - if ((CAvl_link(enode)[1] = temp.link) != CAvl_nulllink()) { - CAvl_parent(CAvlDeref(arg, CAvl_link(enode)[1])) = enode.link; - } - } - - // swap balance factors - int8_t b = CAvl_balance(node); - CAvl_balance(node) = CAvl_balance(enode); - CAvl_balance(enode) = b; - -#if CAVL_PARAM_FEATURE_COUNTS - // swap counts - CAvlCount c = CAvl_count(node); - CAvl_count(node) = CAvl_count(enode); - CAvl_count(enode) = c; -#endif - - // not fixing assoc values here because CAvl_replace_subtree_fix_assoc() will do it -} - -static void CAvl_rebalance (CAvl *o, CAvlArg arg, CAvlRef node, uint8_t side, int8_t deltac) -{ - ASSERT(side == 0 || side == 1) - ASSERT(deltac >= -1 && deltac <= 1) - ASSERT(CAvl_balance(node) >= -1 && CAvl_balance(node) <= 1) - - // if no subtree changed its height, no more rebalancing is needed - if (deltac == 0) { - return; - } - - // calculate how much our height changed - int8_t delta = CAvl_MAX(deltac, CAvl_OPTNEG(CAvl_balance(node), side)) - CAvl_MAX(0, CAvl_OPTNEG(CAvl_balance(node), side)); - ASSERT(delta >= -1 && delta <= 1) - - // update our balance factor - CAvl_balance(node) -= CAvl_OPTNEG(deltac, side); - - CAvlRef child; - CAvlRef gchild; - - // perform transformations if the balance factor is wrong - if (CAvl_balance(node) == 2 || CAvl_balance(node) == -2) { - uint8_t bside; - int8_t bsidef; - if (CAvl_balance(node) == 2) { - bside = 1; - bsidef = 1; - } else { - bside = 0; - bsidef = -1; - } - - ASSERT(CAvl_link(node)[bside] != CAvl_nulllink()) - child = CAvlDeref(arg, CAvl_link(node)[bside]); - - switch (CAvl_balance(child) * bsidef) { - case 1: - CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node))); - CAvl_balance(node) = 0; - CAvl_balance(child) = 0; - node = child; - delta -= 1; - break; - case 0: - CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node))); - CAvl_balance(node) = 1 * bsidef; - CAvl_balance(child) = -1 * bsidef; - node = child; - break; - case -1: - ASSERT(CAvl_link(child)[!bside] != CAvl_nulllink()) - gchild = CAvlDeref(arg, CAvl_link(child)[!bside]); - CAvl_rotate(o, arg, child, bside, node); - CAvl_rotate(o, arg, node, !bside, CAvlDeref(arg, CAvl_parent(node))); - CAvl_balance(node) = -CAvl_MAX(0, CAvl_balance(gchild) * bsidef) * bsidef; - CAvl_balance(child) = CAvl_MAX(0, -CAvl_balance(gchild) * bsidef) * bsidef; - CAvl_balance(gchild) = 0; - node = gchild; - delta -= 1; - break; - default: - ASSERT(0); - } - } - - ASSERT(delta >= -1 && delta <= 1) - // Transformations above preserve this. Proof: - // - if a child subtree gained 1 height and rebalancing was needed, - // it was the heavier subtree. Then delta was was originally 1, because - // the heaviest subtree gained one height. If the transformation reduces - // delta by one, it becomes 0. - // - if a child subtree lost 1 height and rebalancing was needed, it - // was the lighter subtree. Then delta was originally 0, because - // the height of the heaviest subtree was unchanged. If the transformation - // reduces delta by one, it becomes -1. - - if (CAvl_parent(node) != CAvl_nulllink()) { - CAvlRef node_parent = CAvlDeref(arg, CAvl_parent(node)); - CAvl_rebalance(o, arg, node_parent, node.link == CAvl_link(node_parent)[1], delta); - } -} - -#if CAVL_PARAM_FEATURE_KEYS_ARE_INDICES -static CAvlCount CAvl_child_count (CAvlArg arg, CAvlRef n, int dir) -{ - return (CAvl_link(n)[dir] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(n)[dir])) : 0); -} -#endif - -static int CAvlIsNullRef (CAvlRef node) -{ - return node.link == CAvl_nulllink(); -} - -static int CAvlIsValidRef (CAvlRef node) -{ - return node.link != CAvl_nulllink(); -} - -static CAvlRef CAvlDeref (CAvlArg arg, CAvlLink link) -{ - if (link == CAvl_nulllink()) { - return CAvl_nullref(); - } - - CAvlRef n; - n.ptr = CAVL_PARAM_FUN_DEREF(arg, link); - n.link = link; - - ASSERT(n.ptr) - - return n; -} - -static void CAvl_Init (CAvl *o) -{ - o->root = CAvl_nulllink(); -} - -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES - -static int CAvl_Insert (CAvl *o, CAvlArg arg, CAvlRef node, CAvlRef *out_ref) -{ - ASSERT(node.link != CAvl_nulllink()) -#if CAVL_PARAM_FEATURE_COUNTS - ASSERT(CAvl_Count(o, arg) < CAVL_PARAM_VALUE_COUNT_MAX) -#endif - - // insert to root? - if (o->root == CAvl_nulllink()) { - o->root = node.link; - CAvl_parent(node) = CAvl_nulllink(); - CAvl_link(node)[0] = CAvl_nulllink(); - CAvl_link(node)[1] = CAvl_nulllink(); - CAvl_balance(node) = 0; -#if CAVL_PARAM_FEATURE_COUNTS - CAvl_count(node) = 1; -#endif -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(node) = CAVL_PARAM_FUN_ASSOC_VALUE(arg, node); -#endif - - CAvl_assert_tree(o, arg); - - if (out_ref) { - *out_ref = CAvl_nullref(); - } - return 1; - } - - CAvlRef c = CAvlDeref(arg, o->root); - int side; - while (1) { - int comp = CAvl_compare_entries(arg, node, c); - - if (comp == 0) { - if (out_ref) { - *out_ref = c; - } - return 0; - } - - side = (comp == 1); - - if (CAvl_link(c)[side] == CAvl_nulllink()) { - break; - } - - c = CAvlDeref(arg, CAvl_link(c)[side]); - } - - CAvl_link(c)[side] = node.link; - CAvl_parent(node) = c.link; - CAvl_link(node)[0] = CAvl_nulllink(); - CAvl_link(node)[1] = CAvl_nulllink(); - CAvl_balance(node) = 0; -#if CAVL_PARAM_FEATURE_COUNTS - CAvl_count(node) = 1; -#endif -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(node) = CAVL_PARAM_FUN_ASSOC_VALUE(arg, node); -#endif - -#if CAVL_PARAM_FEATURE_COUNTS || CAVL_PARAM_FEATURE_ASSOC - for (CAvlRef p = c; p.link != CAvl_nulllink(); p = CAvlDeref(arg, CAvl_parent(p))) { -#if CAVL_PARAM_FEATURE_COUNTS - CAvl_count(p)++; -#endif -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(p) = CAvl_compute_node_assoc(arg, p); -#endif - } -#endif - - CAvl_rebalance(o, arg, c, side, 1); - - CAvl_assert_tree(o, arg); - - if (out_ref) { - *out_ref = c; - } - return 1; -} - -#else - -static void CAvl_InsertAt (CAvl *o, CAvlArg arg, CAvlRef node, CAvlCount index) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(index <= CAvl_Count(o, arg)) - ASSERT(CAvl_Count(o, arg) < CAVL_PARAM_VALUE_COUNT_MAX) - - // insert to root? - if (o->root == CAvl_nulllink()) { - o->root = node.link; - CAvl_parent(node) = CAvl_nulllink(); - CAvl_link(node)[0] = CAvl_nulllink(); - CAvl_link(node)[1] = CAvl_nulllink(); - CAvl_balance(node) = 0; - CAvl_count(node) = 1; -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(node) = CAVL_PARAM_FUN_ASSOC_VALUE(arg, node); -#endif - - CAvl_assert_tree(o, arg); - return; - } - - CAvlRef c = CAvlDeref(arg, o->root); - CAvlCount c_idx = CAvl_child_count(arg, c, 0); - int side; - while (1) { - side = (index > c_idx); - - if (CAvl_link(c)[side] == CAvl_nulllink()) { - break; - } - - c = CAvlDeref(arg, CAvl_link(c)[side]); - - if (side == 0) { - c_idx -= 1 + CAvl_child_count(arg, c, 1); - } else { - c_idx += 1 + CAvl_child_count(arg, c, 0); - } - } - - CAvl_link(c)[side] = node.link; - CAvl_parent(node) = c.link; - CAvl_link(node)[0] = CAvl_nulllink(); - CAvl_link(node)[1] = CAvl_nulllink(); - CAvl_balance(node) = 0; - CAvl_count(node) = 1; -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(node) = CAVL_PARAM_FUN_ASSOC_VALUE(arg, node); -#endif - - for (CAvlRef p = c; p.link != CAvl_nulllink(); p = CAvlDeref(arg, CAvl_parent(p))) { - CAvl_count(p)++; -#if CAVL_PARAM_FEATURE_ASSOC - CAvl_assoc(p) = CAvl_compute_node_assoc(arg, p); -#endif - } - - CAvl_rebalance(o, arg, c, side, 1); - - CAvl_assert_tree(o, arg); - return; -} - -#endif - -static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlRef node) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(o->root != CAvl_nulllink()) - - if (CAvl_link(node)[0] != CAvl_nulllink() && CAvl_link(node)[1] != CAvl_nulllink()) { - CAvlRef max = CAvl_subtree_max(arg, CAvlDeref(arg, CAvl_link(node)[0])); - CAvl_swap_for_remove(o, arg, node, max, CAvlDeref(arg, CAvl_parent(node)), CAvlDeref(arg, CAvl_parent(max))); - } - - ASSERT(CAvl_link(node)[0] == CAvl_nulllink() || CAvl_link(node)[1] == CAvl_nulllink()) - - CAvlRef paren = CAvlDeref(arg, CAvl_parent(node)); - CAvlRef child = (CAvl_link(node)[0] != CAvl_nulllink() ? CAvlDeref(arg, CAvl_link(node)[0]) : CAvlDeref(arg, CAvl_link(node)[1])); - - if (paren.link != CAvl_nulllink()) { - int side = (node.link == CAvl_link(paren)[1]); - CAvl_replace_subtree_fix_assoc(o, arg, node, child, paren); - CAvl_rebalance(o, arg, paren, side, -1); - } else { - CAvl_replace_subtree_fix_assoc(o, arg, node, child, paren); - } - - CAvl_assert_tree(o, arg); -} - -#if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && !CAVL_PARAM_FEATURE_NOKEYS - -static CAvlRef CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - if (o->root == CAvl_nulllink()) { - return CAvl_nullref(); - } - - CAvlRef c = CAvlDeref(arg, o->root); - while (1) { - // compare - int comp = CAvl_compare_key_entry(arg, key, c); - - // have we found a node that compares equal? - if (comp == 0) { - return c; - } - - int side = (comp == 1); - - // have we reached a leaf? - if (CAvl_link(c)[side] == CAvl_nulllink()) { - return c; - } - - c = CAvlDeref(arg, CAvl_link(c)[side]); - } -} - -static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - if (o->root == CAvl_nulllink()) { - return CAvl_nullref(); - } - - CAvlRef c = CAvlDeref(arg, o->root); - while (1) { - // compare - int comp = CAvl_compare_key_entry(arg, key, c); - - // have we found a node that compares equal? - if (comp == 0) { - return c; - } - - int side = (comp == 1); - - // have we reached a leaf? - if (CAvl_link(c)[side] == CAvl_nulllink()) { - return CAvl_nullref(); - } - - c = CAvlDeref(arg, CAvl_link(c)[side]); - } -} - -static CAvlRef CAvl_GetFirstGreater (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - CAvlRef c = CAvl_Lookup(o, arg, key); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - - if (CAvl_compare_key_entry(arg, key, c) >= 0) { - c = CAvl_GetNext(o, arg, c); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - } - - ASSERT(CAvl_compare_key_entry(arg, key, c) < 0); - - return c; -} - -static CAvlRef CAvl_GetLastLesser (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - CAvlRef c = CAvl_Lookup(o, arg, key); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - - if (CAvl_compare_key_entry(arg, key, c) <= 0) { - c = CAvl_GetPrev(o, arg, c); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - } - - ASSERT(CAvl_compare_key_entry(arg, key, c) > 0); - - return c; -} - -static CAvlRef CAvl_GetFirstGreaterEqual (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - CAvlRef c = CAvl_Lookup(o, arg, key); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - - if (CAvl_compare_key_entry(arg, key, c) > 0) { - c = CAvl_GetNext(o, arg, c); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - } - - ASSERT(CAvl_compare_key_entry(arg, key, c) <= 0); - - return c; -} - -static CAvlRef CAvl_GetLastLesserEqual (const CAvl *o, CAvlArg arg, CAvlKey key) -{ - CAvlRef c = CAvl_Lookup(o, arg, key); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - - if (CAvl_compare_key_entry(arg, key, c) < 0) { - c = CAvl_GetPrev(o, arg, c); - if (CAvlIsNullRef(c)) { - return CAvl_nullref(); - } - } - - ASSERT(CAvl_compare_key_entry(arg, key, c) >= 0); - - return c; -} - -#endif - -static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg) -{ - if (o->root == CAvl_nulllink()) { - return CAvl_nullref(); - } - - return CAvl_subtree_min(arg, CAvlDeref(arg, o->root)); -} - -static CAvlRef CAvl_GetLast (const CAvl *o, CAvlArg arg) -{ - if (o->root == CAvl_nulllink()) { - return CAvl_nullref(); - } - - return CAvl_subtree_max(arg, CAvlDeref(arg, o->root)); -} - -static CAvlRef CAvl_GetNext (const CAvl *o, CAvlArg arg, CAvlRef node) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(o->root != CAvl_nulllink()) - - if (CAvl_link(node)[1] != CAvl_nulllink()) { - node = CAvlDeref(arg, CAvl_link(node)[1]); - while (CAvl_link(node)[0] != CAvl_nulllink()) { - node = CAvlDeref(arg, CAvl_link(node)[0]); - } - } else { - while (CAvl_parent(node) != CAvl_nulllink() && node.link == CAvl_link(CAvlDeref(arg, CAvl_parent(node)))[1]) { - node = CAvlDeref(arg, CAvl_parent(node)); - } - node = CAvlDeref(arg, CAvl_parent(node)); - } - - return node; -} - -static CAvlRef CAvl_GetPrev (const CAvl *o, CAvlArg arg, CAvlRef node) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(o->root != CAvl_nulllink()) - - if (CAvl_link(node)[0] != CAvl_nulllink()) { - node = CAvlDeref(arg, CAvl_link(node)[0]); - while (CAvl_link(node)[1] != CAvl_nulllink()) { - node = CAvlDeref(arg, CAvl_link(node)[1]); - } - } else { - while (CAvl_parent(node) != CAvl_nulllink() && node.link == CAvl_link(CAvlDeref(arg, CAvl_parent(node)))[0]) { - node = CAvlDeref(arg, CAvl_parent(node)); - } - node = CAvlDeref(arg, CAvl_parent(node)); - } - - return node; -} - -static int CAvl_IsEmpty (const CAvl *o) -{ - return o->root == CAvl_nulllink(); -} - -static void CAvl_Verify (const CAvl *o, CAvlArg arg) -{ - if (o->root != CAvl_nulllink()) { - CAvlRef root = CAvlDeref(arg, o->root); - ASSERT(CAvl_parent(root) == CAvl_nulllink()) - CAvl_verify_recurser(arg, root); - } -} - -#if CAVL_PARAM_FEATURE_COUNTS - -static CAvlCount CAvl_Count (const CAvl *o, CAvlArg arg) -{ - return (o->root != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, o->root)) : 0); -} - -static CAvlCount CAvl_IndexOf (const CAvl *o, CAvlArg arg, CAvlRef node) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(o->root != CAvl_nulllink()) - - CAvlCount index = (CAvl_link(node)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(node)[0])) : 0); - - CAvlRef paren = CAvlDeref(arg, CAvl_parent(node)); - - for (CAvlRef c = node; paren.link != CAvl_nulllink(); c = paren, paren = CAvlDeref(arg, CAvl_parent(c))) { - if (c.link == CAvl_link(paren)[1]) { - ASSERT(CAvl_count(paren) > CAvl_count(c)) - ASSERT(CAvl_count(paren) - CAvl_count(c) <= CAVL_PARAM_VALUE_COUNT_MAX - index) - index += CAvl_count(paren) - CAvl_count(c); - } - } - - return index; -} - -static CAvlRef CAvl_GetAt (const CAvl *o, CAvlArg arg, CAvlCount index) -{ - if (index >= CAvl_Count(o, arg)) { - return CAvl_nullref(); - } - - CAvlRef c = CAvlDeref(arg, o->root); - - while (1) { - ASSERT(c.link != CAvl_nulllink()) - ASSERT(index < CAvl_count(c)) - - CAvlCount left_count = (CAvl_link(c)[0] != CAvl_nulllink() ? CAvl_count(CAvlDeref(arg, CAvl_link(c)[0])) : 0); - - if (index == left_count) { - return c; - } - - if (index < left_count) { - c = CAvlDeref(arg, CAvl_link(c)[0]); - } else { - c = CAvlDeref(arg, CAvl_link(c)[1]); - index -= left_count + 1; - } - } -} - -#endif - -#if CAVL_PARAM_FEATURE_ASSOC - -static CAvlAssoc CAvl_AssocSum (const CAvl *o, CAvlArg arg) -{ - if (o->root == CAvl_nulllink()) { - return CAVL_PARAM_VALUE_ASSOC_ZERO; - } - CAvlRef root = CAvlDeref(arg, o->root); - return CAvl_assoc(root); -} - -static CAvlAssoc CAvl_ExclusiveAssocPrefixSum (const CAvl *o, CAvlArg arg, CAvlRef node) -{ - ASSERT(node.link != CAvl_nulllink()) - ASSERT(o->root != CAvl_nulllink()) - - CAvlAssoc sum = (CAvl_link(node)[0] != CAvl_nulllink() ? CAvl_assoc(CAvlDeref(arg, CAvl_link(node)[0])) : CAVL_PARAM_VALUE_ASSOC_ZERO); - - CAvlRef paren = CAvlDeref(arg, CAvl_parent(node)); - - for (CAvlRef c = node; paren.link != CAvl_nulllink(); c = paren, paren = CAvlDeref(arg, CAvl_parent(c))) { - if (c.link == CAvl_link(paren)[1]) { - CAvlAssoc c_val = CAVL_PARAM_FUN_ASSOC_VALUE(arg, paren); - sum = CAVL_PARAM_FUN_ASSOC_OPER(arg, c_val, sum); - if (CAvl_link(paren)[0] != CAvl_nulllink()) { - sum = CAVL_PARAM_FUN_ASSOC_OPER(arg, CAvl_assoc(CAvlDeref(arg, CAvl_link(paren)[0])), sum); - } - } - } - - return sum; -} - -static CAvlRef CAvl_FindLastExclusiveAssocPrefixSumLesserEqual (const CAvl *o, CAvlArg arg, CAvlAssoc sum, int (*sum_less) (void *, CAvlAssoc, CAvlAssoc), void *user) -{ - CAvlRef result = CAvl_nullref(); - CAvlRef c = CAvlDeref(arg, o->root); - CAvlAssoc sum_offset = CAVL_PARAM_VALUE_ASSOC_ZERO; - - while (c.link != CAvl_nulllink()) { - CAvlAssoc left_sum = (CAvl_link(c)[0] != CAvl_nulllink() ? CAvl_assoc(CAvlDeref(arg, CAvl_link(c)[0])) : CAVL_PARAM_VALUE_ASSOC_ZERO); - CAvlAssoc c_prefixsum = CAVL_PARAM_FUN_ASSOC_OPER(arg, sum_offset, left_sum); - - if (sum_less(user, sum, c_prefixsum)) { - c = CAvlDeref(arg, CAvl_link(c)[0]); - } else { - result = c; - CAvlAssoc c_val = CAVL_PARAM_FUN_ASSOC_VALUE(arg, c); - sum_offset = CAVL_PARAM_FUN_ASSOC_OPER(arg, c_prefixsum, c_val); - c = CAvlDeref(arg, CAvl_link(c)[1]); - } - } - - return result; -} - -#endif - -#include "CAvl_footer.h" diff --git a/external/badvpn_dns/structure/CHash.h b/external/badvpn_dns/structure/CHash.h deleted file mode 100644 index 45fef7a..0000000 --- a/external/badvpn_dns/structure/CHash.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file CHash.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_CHASH_H -#define BADVPN_CHASH_H - -#include <stdlib.h> - -#include <misc/debug.h> -#include <misc/merge.h> -#include <misc/balloc.h> - -#endif diff --git a/external/badvpn_dns/structure/CHash_decl.h b/external/badvpn_dns/structure/CHash_decl.h deleted file mode 100644 index d47702a..0000000 --- a/external/badvpn_dns/structure/CHash_decl.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file CHash_decl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CHash_header.h" - -typedef struct { - CHashLink *buckets; - size_t num_buckets; -} CHash; - -typedef struct { - CHashEntry *ptr; - CHashLink link; -} CHashRef; - -static CHashLink CHashNullLink (void); -static CHashRef CHashNullRef (void); -static int CHashIsNullLink (CHashLink link); -static int CHashIsNullRef (CHashRef ref); -static CHashRef CHashDerefMayNull (CHashArg arg, CHashLink link); -static CHashRef CHashDerefNonNull (CHashArg arg, CHashLink link); - -static int CHash_Init (CHash *o, size_t num_buckets); -static void CHash_Free (CHash *o); -static int CHash_Insert (CHash *o, CHashArg arg, CHashRef entry, CHashRef *out_existing); -static void CHash_InsertMulti (CHash *o, CHashArg arg, CHashRef entry); -static void CHash_Remove (CHash *o, CHashArg arg, CHashRef entry); -static CHashRef CHash_Lookup (const CHash *o, CHashArg arg, CHashKey key); -static CHashRef CHash_GetNextEqual (const CHash *o, CHashArg arg, CHashRef entry); -static int CHash_MultiplyBuckets (CHash *o, CHashArg arg, int exp); -static void CHash_Verify (const CHash *o, CHashArg arg); - -#include "CHash_footer.h" diff --git a/external/badvpn_dns/structure/CHash_footer.h b/external/badvpn_dns/structure/CHash_footer.h deleted file mode 100644 index cb95daf..0000000 --- a/external/badvpn_dns/structure/CHash_footer.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file CHash_footer.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// preprocessor inputs -#undef CHASH_PARAM_NAME -#undef CHASH_PARAM_ENTRY -#undef CHASH_PARAM_LINK -#undef CHASH_PARAM_KEY -#undef CHASH_PARAM_ARG -#undef CHASH_PARAM_NULL -#undef CHASH_PARAM_DEREF -#undef CHASH_PARAM_ENTRYHASH -#undef CHASH_PARAM_KEYHASH -#undef CHASH_PARAM_ENTRYHASH_IS_CHEAP -#undef CHASH_PARAM_COMPARE_ENTRIES -#undef CHASH_PARAM_COMPARE_KEY_ENTRY -#undef CHASH_PARAM_ENTRY_NEXT - -// types -#undef CHash -#undef CHashEntry -#undef CHashLink -#undef CHashRef -#undef CHashArg -#undef CHashKey - -// non-object public functions -#undef CHashNullLink -#undef CHashNullRef -#undef CHashIsNullLink -#undef CHashIsNullRef -#undef CHashDerefMayNull -#undef CHashDerefNonNull - -// public functions -#undef CHash_Init -#undef CHash_Free -#undef CHash_Insert -#undef CHash_InsertMulti -#undef CHash_Remove -#undef CHash_Lookup -#undef CHash_GetNextEqual -#undef CHash_MultiplyBuckets -#undef CHash_Verify - -// private things -#undef CHash_next -#undef CHash_assert_valid_entry diff --git a/external/badvpn_dns/structure/CHash_header.h b/external/badvpn_dns/structure/CHash_header.h deleted file mode 100644 index 27800ac..0000000 --- a/external/badvpn_dns/structure/CHash_header.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file CHash_header.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Preprocessor inputs: -// CHASH_PARAM_NAME - name of this data structure -// CHASH_PARAM_ENTRY - type of entry -// CHASH_PARAM_LINK - type of entry link (usually a pointer or index to an array) -// CHASH_PARAM_KEY - type of key -// CHASH_PARAM_ARG - type of argument pass through to comparisons -// CHASH_PARAM_NULL - invalid link -// CHASH_PARAM_DEREF(arg, link) - dereference a non-null link -// CHASH_PARAM_ENTRYHASH(arg, entry) - hash function for entries; returns size_t -// CHASH_PARAM_KEYHASH(arg, key) - hash function for keys; returns size_t -// CHASH_PARAM_ENTRYHASH_IS_CHEAP - define to 1 if CHASH_PARAM_ENTRYHASH is cheap (e.g. hashes are precomputed) -// CHASH_PARAM_COMPARE_ENTRIES(arg, entry1, entry2) - compares two entries; returns 1 for equality, 0 otherwise -// CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key1, entry2) - compares key and entry; returns 1 for equality, 0 otherwise -// CHASH_PARAM_ENTRY_NEXT - next member in entry - -#ifndef BADVPN_CHASH_H -#error CHash.h has not been included -#endif - -// types -#define CHash CHASH_PARAM_NAME -#define CHashEntry CHASH_PARAM_ENTRY -#define CHashLink CHASH_PARAM_LINK -#define CHashRef MERGE(CHash, Ref) -#define CHashArg CHASH_PARAM_ARG -#define CHashKey CHASH_PARAM_KEY - -// non-object public functions -#define CHashNullLink MERGE(CHash, NullLink) -#define CHashNullRef MERGE(CHash, NullRef) -#define CHashIsNullLink MERGE(CHash, IsNullLink) -#define CHashIsNullRef MERGE(CHash, IsNullRef) -#define CHashDerefMayNull MERGE(CHash, DerefMayNull) -#define CHashDerefNonNull MERGE(CHash, DerefNonNull) - -// public functions -#define CHash_Init MERGE(CHash, _Init) -#define CHash_Free MERGE(CHash, _Free) -#define CHash_Insert MERGE(CHash, _Insert) -#define CHash_InsertMulti MERGE(CHash, _InsertMulti) -#define CHash_Remove MERGE(CHash, _Remove) -#define CHash_Lookup MERGE(CHash, _Lookup) -#define CHash_GetNextEqual MERGE(CHash, _GetNextEqual) -#define CHash_MultiplyBuckets MERGE(CHash, _MultiplyBuckets) -#define CHash_Verify MERGE(CHash, _Verify) - -// private things -#define CHash_next(entry) ((entry).ptr->CHASH_PARAM_ENTRY_NEXT) -#define CHash_assert_valid_entry MERGE(CHash, _assert_valid_entry) diff --git a/external/badvpn_dns/structure/CHash_impl.h b/external/badvpn_dns/structure/CHash_impl.h deleted file mode 100644 index 0bded84..0000000 --- a/external/badvpn_dns/structure/CHash_impl.h +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @file CHash_impl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "CHash_header.h" - -static void CHash_assert_valid_entry (CHashArg arg, CHashRef entry) -{ - ASSERT(entry.link != CHashNullLink()) - ASSERT(entry.ptr == CHASH_PARAM_DEREF(arg, entry.link)) -} - -static CHashLink CHashNullLink (void) -{ - return CHASH_PARAM_NULL; -} - -static CHashRef CHashNullRef (void) -{ - CHashRef entry = {NULL, CHashNullLink()}; - return entry; -} - -static int CHashIsNullLink (CHashLink link) -{ - return (link == CHashNullLink()); -} - -static int CHashIsNullRef (CHashRef ref) -{ - return CHashIsNullLink(ref.link); -} - -static CHashRef CHashDerefMayNull (CHashArg arg, CHashLink link) -{ - if (link == CHashNullLink()) { - return CHashNullRef(); - } - - CHashRef entry = {CHASH_PARAM_DEREF(arg, link), link}; - ASSERT(entry.ptr) - - return entry; -} - -static CHashRef CHashDerefNonNull (CHashArg arg, CHashLink link) -{ - ASSERT(link != CHashNullLink()) - - CHashRef entry = {CHASH_PARAM_DEREF(arg, link), link}; - ASSERT(entry.ptr) - - return entry; -} - -static int CHash_Init (CHash *o, size_t num_buckets) -{ - if (num_buckets == 0) { - num_buckets = 1; - } - - o->num_buckets = num_buckets; - - o->buckets = (CHashLink *)BAllocArray(o->num_buckets, sizeof(o->buckets[0])); - if (!o->buckets) { - return 0; - } - - for (size_t i = 0; i < o->num_buckets; i++) { - o->buckets[i] = CHashNullLink(); - } - - return 1; -} - -static void CHash_Free (CHash *o) -{ - BFree(o->buckets); -} - -static int CHash_Insert (CHash *o, CHashArg arg, CHashRef entry, CHashRef *out_existing) -{ - CHash_assert_valid_entry(arg, entry); - - size_t index = CHASH_PARAM_ENTRYHASH(arg, entry) % o->num_buckets; - - CHashLink link = o->buckets[index]; - while (link != CHashNullLink()) { - CHashRef cur = CHashDerefNonNull(arg, link); - if (CHASH_PARAM_COMPARE_ENTRIES(arg, cur, entry)) { - if (out_existing) { - *out_existing = cur; - } - return 0; - } - link = CHash_next(cur); - } - - CHash_next(entry) = o->buckets[index]; - o->buckets[index] = entry.link; - - return 1; -} - -static void CHash_InsertMulti (CHash *o, CHashArg arg, CHashRef entry) -{ - CHash_assert_valid_entry(arg, entry); - - size_t index = CHASH_PARAM_ENTRYHASH(arg, entry) % o->num_buckets; - - CHashRef prev = CHashNullRef(); - CHashLink link = o->buckets[index]; - while (link != CHashNullLink()) { - CHashRef cur = CHashDerefNonNull(arg, link); - if (CHASH_PARAM_COMPARE_ENTRIES(arg, cur, entry)) { - break; - } - prev = cur; - link = CHash_next(cur); - } - - if (link == CHashNullLink() || prev.link == CHashNullLink()) { - CHash_next(entry) = o->buckets[index]; - o->buckets[index] = entry.link; - } else { - CHash_next(entry) = link; - CHash_next(prev) = entry.link; - } -} - -static void CHash_Remove (CHash *o, CHashArg arg, CHashRef entry) -{ - CHash_assert_valid_entry(arg, entry); - - size_t index = CHASH_PARAM_ENTRYHASH(arg, entry) % o->num_buckets; - - CHashRef prev = CHashNullRef(); - CHashLink link = o->buckets[index]; - while (link != entry.link) { - CHashRef cur = CHashDerefNonNull(arg, link); - prev = cur; - link = CHash_next(cur); - ASSERT(link != CHashNullLink()) - } - - if (prev.link == CHashNullLink()) { - o->buckets[index] = CHash_next(entry); - } else { - CHash_next(prev) = CHash_next(entry); - } -} - -static CHashRef CHash_Lookup (const CHash *o, CHashArg arg, CHashKey key) -{ - size_t hash = CHASH_PARAM_KEYHASH(arg, key); - size_t index = hash % o->num_buckets; - - CHashLink link = o->buckets[index]; - while (link != CHashNullLink()) { - CHashRef cur = CHashDerefNonNull(arg, link); -#if CHASH_PARAM_ENTRYHASH_IS_CHEAP - if (CHASH_PARAM_ENTRYHASH(arg, cur) == hash && CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key, cur)) { -#else - if (CHASH_PARAM_COMPARE_KEY_ENTRY(arg, key, cur)) { -#endif - return cur; - } - link = CHash_next(cur); - } - - return CHashNullRef(); -} - -static CHashRef CHash_GetNextEqual (const CHash *o, CHashArg arg, CHashRef entry) -{ - CHash_assert_valid_entry(arg, entry); - - CHashLink next = CHash_next(entry); - - if (next == CHashNullLink()) { - return CHashNullRef(); - } - - CHashRef next_ref = CHashDerefNonNull(arg, next); - if (!CHASH_PARAM_COMPARE_ENTRIES(arg, next_ref, entry)) { - return CHashNullRef(); - } - - return next_ref; -} - -static int CHash_MultiplyBuckets (CHash *o, CHashArg arg, int exp) -{ - ASSERT(exp > 0) - - size_t new_num_buckets = o->num_buckets; - while (exp-- > 0) { - if (new_num_buckets > SIZE_MAX / 2) { - return 0; - } - new_num_buckets *= 2; - } - - CHashLink *new_buckets = (CHashLink *)BReallocArray(o->buckets, new_num_buckets, sizeof(new_buckets[0])); - if (!new_buckets) { - return 0; - } - o->buckets = new_buckets; - - for (size_t i = o->num_buckets; i < new_num_buckets; i++) { - o->buckets[i] = CHashNullLink(); - } - - for (size_t i = 0; i < o->num_buckets; i++) { - CHashRef prev = CHashNullRef(); - CHashLink link = o->buckets[i]; - - while (link != CHashNullLink()) { - CHashRef cur = CHashDerefNonNull(arg, link); - link = CHash_next(cur); - - size_t new_index = CHASH_PARAM_ENTRYHASH(arg, cur) % new_num_buckets; - if (new_index == i) { - prev = cur; - continue; - } - - if (CHashIsNullRef(prev)) { - o->buckets[i] = CHash_next(cur); - } else { - CHash_next(prev) = CHash_next(cur); - } - - CHash_next(cur) = o->buckets[new_index]; - o->buckets[new_index] = cur.link; - } - } - - for (size_t i = o->num_buckets; i < new_num_buckets; i++) { - CHashLink new_bucket_link = CHashNullLink(); - - CHashLink link = o->buckets[i]; - while (link != CHashNullLink()) { - CHashRef cur = CHashDerefNonNull(arg, link); - link = CHash_next(cur); - - CHash_next(cur) = new_bucket_link; - new_bucket_link = cur.link; - } - - o->buckets[i] = new_bucket_link; - } - - o->num_buckets = new_num_buckets; - - return 1; -} - -static void CHash_Verify (const CHash *o, CHashArg arg) -{ - ASSERT_FORCE(o->num_buckets > 0) - ASSERT_FORCE(o->buckets) - - for (size_t i = 0; i < o->num_buckets; i++) { - CHashRef cur = CHashDerefMayNull(arg, o->buckets[i]); - CHashRef same_first = cur; - - while (!CHashIsNullRef(cur)) { - size_t index = CHASH_PARAM_ENTRYHASH(arg, cur) % o->num_buckets; - ASSERT_FORCE(index == i) - - if (!CHASH_PARAM_COMPARE_ENTRIES(arg, cur, same_first)) { - same_first = cur; - } - - CHashRef ccur = CHashDerefNonNull(arg, o->buckets[i]); - while (ccur.link != same_first.link) { - ASSERT_FORCE(!CHASH_PARAM_COMPARE_ENTRIES(arg, ccur, cur)) - ccur = CHashDerefMayNull(arg, CHash_next(ccur)); - } - - cur = CHashDerefMayNull(arg, CHash_next(cur)); - } - } -} - -#include "CHash_footer.h" diff --git a/external/badvpn_dns/structure/ChunkBuffer2.h b/external/badvpn_dns/structure/ChunkBuffer2.h deleted file mode 100644 index 98073ad..0000000 --- a/external/badvpn_dns/structure/ChunkBuffer2.h +++ /dev/null @@ -1,317 +0,0 @@ -/** - * @file ChunkBuffer2.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Circular packet buffer - */ - -#ifndef BADVPN_STRUCTURE_CHUNKBUFFER2_H -#define BADVPN_STRUCTURE_CHUNKBUFFER2_H - -#include <stdint.h> -#include <stdlib.h> -#include <limits.h> - -#include <misc/balign.h> -#include <misc/debug.h> - -#ifndef NDEBUG -#define CHUNKBUFFER2_ASSERT_BUFFER(_buf) _ChunkBuffer2_assert_buffer(_buf); -#define CHUNKBUFFER2_ASSERT_IO(_buf) _ChunkBuffer2_assert_io(_buf); -#else -#define CHUNKBUFFER2_ASSERT_BUFFER(_buf) -#define CHUNKBUFFER2_ASSERT_IO(_buf) -#endif - -struct ChunkBuffer2_block { - int len; -}; - -typedef struct { - struct ChunkBuffer2_block *buffer; - int size; - int wrap; - int start; - int used; - int mtu; - uint8_t *input_dest; - int input_avail; - uint8_t *output_dest; - int output_avail; -} ChunkBuffer2; - -// calculates a buffer size needed to hold at least 'num' packets long at least 'chunk_len' -static int ChunkBuffer2_calc_blocks (int chunk_len, int num); - -// initialize -static void ChunkBuffer2_Init (ChunkBuffer2 *buf, struct ChunkBuffer2_block *buffer, int blocks, int mtu); - -// submit a packet written to the buffer -static void ChunkBuffer2_SubmitPacket (ChunkBuffer2 *buf, int len); - -// remove the first packet -static void ChunkBuffer2_ConsumePacket (ChunkBuffer2 *buf); - -static int _ChunkBuffer2_end (ChunkBuffer2 *buf) -{ - if (buf->used >= buf->wrap - buf->start) { - return (buf->used - (buf->wrap - buf->start)); - } else { - return (buf->start + buf->used); - } -} - -#ifndef NDEBUG - -static void _ChunkBuffer2_assert_buffer (ChunkBuffer2 *buf) -{ - ASSERT(buf->size > 0) - ASSERT(buf->wrap > 0) - ASSERT(buf->wrap <= buf->size) - ASSERT(buf->start >= 0) - ASSERT(buf->start < buf->wrap) - ASSERT(buf->used >= 0) - ASSERT(buf->used <= buf->wrap) - ASSERT(buf->wrap == buf->size || buf->used >= buf->wrap - buf->start) - ASSERT(buf->mtu >= 0) -} - -static void _ChunkBuffer2_assert_io (ChunkBuffer2 *buf) -{ - // check input - - int end = _ChunkBuffer2_end(buf); - - if (buf->size - end - 1 < buf->mtu) { - // it will never be possible to write a MTU long packet here - ASSERT(!buf->input_dest) - ASSERT(buf->input_avail == -1) - } else { - // calculate number of free blocks - int free; - if (buf->used >= buf->wrap - buf->start) { - free = buf->start - end; - } else { - free = buf->size - end; - } - - if (free > 0) { - // got space at least for a header. More space will become available as packets are - // read from the buffer, up to MTU. - ASSERT(buf->input_dest == (uint8_t *)&buf->buffer[end + 1]) - ASSERT(buf->input_avail == (free - 1) * sizeof(struct ChunkBuffer2_block)) - } else { - // no space - ASSERT(!buf->input_dest) - ASSERT(buf->input_avail == -1) - } - } - - // check output - - if (buf->used > 0) { - int datalen = buf->buffer[buf->start].len; - ASSERT(datalen >= 0) - int blocklen = bdivide_up(datalen, sizeof(struct ChunkBuffer2_block)); - ASSERT(blocklen <= buf->used - 1) - ASSERT(blocklen <= buf->wrap - buf->start - 1) - ASSERT(buf->output_dest == (uint8_t *)&buf->buffer[buf->start + 1]) - ASSERT(buf->output_avail == datalen) - } else { - ASSERT(!buf->output_dest) - ASSERT(buf->output_avail == -1) - } -} - -#endif - -static void _ChunkBuffer2_update_input (ChunkBuffer2 *buf) -{ - int end = _ChunkBuffer2_end(buf); - - if (buf->size - end - 1 < buf->mtu) { - // it will never be possible to write a MTU long packet here - buf->input_dest = NULL; - buf->input_avail = -1; - return; - } - - // calculate number of free blocks - int free; - if (buf->used >= buf->wrap - buf->start) { - free = buf->start - end; - } else { - free = buf->size - end; - } - - if (free > 0) { - // got space at least for a header. More space will become available as packets are - // read from the buffer, up to MTU. - buf->input_dest = (uint8_t *)&buf->buffer[end + 1]; - buf->input_avail = (free - 1) * sizeof(struct ChunkBuffer2_block); - } else { - // no space - buf->input_dest = NULL; - buf->input_avail = -1; - } -} - -static void _ChunkBuffer2_update_output (ChunkBuffer2 *buf) -{ - if (buf->used > 0) { - int datalen = buf->buffer[buf->start].len; - ASSERT(datalen >= 0) -#ifndef NDEBUG - int blocklen = bdivide_up(datalen, sizeof(struct ChunkBuffer2_block)); - ASSERT(blocklen <= buf->used - 1) - ASSERT(blocklen <= buf->wrap - buf->start - 1) -#endif - buf->output_dest = (uint8_t *)&buf->buffer[buf->start + 1]; - buf->output_avail = datalen; - } else { - buf->output_dest = NULL; - buf->output_avail = -1; - } -} - -int ChunkBuffer2_calc_blocks (int chunk_len, int num) -{ - int chunk_data_blocks = bdivide_up(chunk_len, sizeof(struct ChunkBuffer2_block)); - - if (chunk_data_blocks > INT_MAX - 1) { - return -1; - } - int chunk_blocks = 1 + chunk_data_blocks; - - if (num > INT_MAX - 1) { - return -1; - } - int num_chunks = num + 1; - - if (chunk_blocks > INT_MAX / num_chunks) { - return -1; - } - int blocks = chunk_blocks * num_chunks; - - return blocks; -} - -void ChunkBuffer2_Init (ChunkBuffer2 *buf, struct ChunkBuffer2_block *buffer, int blocks, int mtu) -{ - ASSERT(blocks > 0) - ASSERT(mtu >= 0) - - buf->buffer = buffer; - buf->size = blocks; - buf->wrap = blocks; - buf->start = 0; - buf->used = 0; - buf->mtu = bdivide_up(mtu, sizeof(struct ChunkBuffer2_block)); - - CHUNKBUFFER2_ASSERT_BUFFER(buf) - - _ChunkBuffer2_update_input(buf); - _ChunkBuffer2_update_output(buf); - - CHUNKBUFFER2_ASSERT_IO(buf) -} - -void ChunkBuffer2_SubmitPacket (ChunkBuffer2 *buf, int len) -{ - ASSERT(buf->input_dest) - ASSERT(len >= 0) - ASSERT(len <= buf->input_avail) - - CHUNKBUFFER2_ASSERT_BUFFER(buf) - CHUNKBUFFER2_ASSERT_IO(buf) - - int end = _ChunkBuffer2_end(buf); - int blocklen = bdivide_up(len, sizeof(struct ChunkBuffer2_block)); - - ASSERT(blocklen <= buf->size - end - 1) - ASSERT(buf->used < buf->wrap - buf->start || blocklen <= buf->start - end - 1) - - buf->buffer[end].len = len; - buf->used += 1 + blocklen; - - if (buf->used <= buf->wrap - buf->start && buf->mtu > buf->size - (end + 1 + blocklen) - 1) { - buf->wrap = end + 1 + blocklen; - } - - CHUNKBUFFER2_ASSERT_BUFFER(buf) - - // update input - _ChunkBuffer2_update_input(buf); - - // update output - if (buf->used == 1 + blocklen) { - _ChunkBuffer2_update_output(buf); - } - - CHUNKBUFFER2_ASSERT_IO(buf) -} - -void ChunkBuffer2_ConsumePacket (ChunkBuffer2 *buf) -{ - ASSERT(buf->output_dest) - - CHUNKBUFFER2_ASSERT_BUFFER(buf) - CHUNKBUFFER2_ASSERT_IO(buf) - - ASSERT(1 <= buf->wrap - buf->start) - ASSERT(1 <= buf->used) - - int blocklen = bdivide_up(buf->buffer[buf->start].len, sizeof(struct ChunkBuffer2_block)); - - ASSERT(blocklen <= buf->wrap - buf->start - 1) - ASSERT(blocklen <= buf->used - 1) - - int data_wrapped = (buf->used >= buf->wrap - buf->start); - - buf->start += 1 + blocklen; - buf->used -= 1 + blocklen; - if (buf->start == buf->wrap) { - buf->start = 0; - buf->wrap = buf->size; - } - - CHUNKBUFFER2_ASSERT_BUFFER(buf) - - // update input - if (data_wrapped) { - _ChunkBuffer2_update_input(buf); - } - - // update output - _ChunkBuffer2_update_output(buf); - - CHUNKBUFFER2_ASSERT_IO(buf) -} - -#endif diff --git a/external/badvpn_dns/structure/IndexedList.h b/external/badvpn_dns/structure/IndexedList.h deleted file mode 100644 index ca611e9..0000000 --- a/external/badvpn_dns/structure/IndexedList.h +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file IndexedList.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A data structure similar to a list, but with efficient index-based access. - */ - -#ifndef BADVPN_INDEXEDLIST_H -#define BADVPN_INDEXEDLIST_H - -#include <stddef.h> -#include <stdint.h> - -#include <misc/offset.h> -#include <misc/debug.h> -#include <structure/CAvl.h> - -typedef struct IndexedList_s IndexedList; -typedef struct IndexedListNode_s IndexedListNode; - -typedef IndexedListNode *IndexedList__tree_link; - -#include "IndexedList_tree.h" -#include <structure/CAvl_decl.h> - -struct IndexedList_s { - IndexedList__Tree tree; -}; - -struct IndexedListNode_s { - IndexedListNode *tree_child[2]; - IndexedListNode *tree_parent; - int8_t tree_balance; - uint64_t tree_count; -}; - -/** - * Initializes the indexed list. - * - * @param o uninitialized list object to initialize - */ -static void IndexedList_Init (IndexedList *o); - -/** - * Inserts a node into the indexed list. - * - * @param o indexed list to insert into - * @param node uninitialized node to insert - * @param index index to insert at (starting with zero). Any existing elements - * at or after this index will be shifted forward, i.e. their - * indices will be incremented by one. Must be <=count. - */ -static void IndexedList_InsertAt (IndexedList *o, IndexedListNode *node, uint64_t index); - -/** - * Removes a nove from the indexed list. - * - * @param o indexed list to remove from - * @param node node in the list to remove - */ -static void IndexedList_Remove (IndexedList *o, IndexedListNode *node); - -/** - * Returns the number of nodes in the indexed list. - * - * @param o indexed list - * @return number of nodes - */ -static uint64_t IndexedList_Count (IndexedList *o); - -/** - * Returns the index of a node in the indexed list. - * - * @param o indexed list - * @param node node in the list to get index of - * @return index of the node - */ -static uint64_t IndexedList_IndexOf (IndexedList *o, IndexedListNode *node); - -/** - * Returns the node at the specified index in the indexed list. - * - * @param o indexed list - * @param index index of the node to return. Must be < count. - * @return node at the specified index - */ -static IndexedListNode * IndexedList_GetAt (IndexedList *o, uint64_t index); - -/** - * Returns the first node, or NULL if the list is empty. - * - * @param o indexed list - * @return first node, or NULL - */ -static IndexedListNode * IndexedList_GetFirst (IndexedList *o); - -/** - * Returns the last node, or NULL if the list is empty. - * - * @param o indexed list - * @return last node, or NULL - */ -static IndexedListNode * IndexedList_GetLast (IndexedList *o); - -/** - * Returns the next node of a given node, or NULL this is the last node. - * - * @param o indexed list - * @param node existing node - * @return next node, or NULL - */ -static IndexedListNode * IndexedList_GetNext (IndexedList *o, IndexedListNode *node); - -/** - * Returns the previous node of a given node, or NULL this is the first node. - * - * @param o indexed list - * @param node existing node - * @return previous node, or NULL - */ -static IndexedListNode * IndexedList_GetPrev (IndexedList *o, IndexedListNode *node); - -#include "IndexedList_tree.h" -#include <structure/CAvl_impl.h> - -static IndexedListNode * IndexedList__deref (IndexedList__TreeRef ref) -{ - return ref.link; -} - -static void IndexedList_Init (IndexedList *o) -{ - IndexedList__Tree_Init(&o->tree); -} - -static void IndexedList_InsertAt (IndexedList *o, IndexedListNode *node, uint64_t index) -{ - ASSERT(index <= IndexedList__Tree_Count(&o->tree, 0)) - ASSERT(IndexedList__Tree_Count(&o->tree, 0) < UINT64_MAX - 1) - - uint64_t orig_count = IndexedList__Tree_Count(&o->tree, 0); - B_USE(orig_count) - - IndexedList__Tree_InsertAt(&o->tree, 0, IndexedList__TreeDeref(0, node), index); - - ASSERT(IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__TreeDeref(0, node)) == index) - ASSERT(IndexedList__Tree_Count(&o->tree, 0) == orig_count + 1) -} - -static void IndexedList_Remove (IndexedList *o, IndexedListNode *node) -{ - IndexedList__Tree_Remove(&o->tree, 0, IndexedList__TreeDeref(0, node)); -} - -static uint64_t IndexedList_Count (IndexedList *o) -{ - return IndexedList__Tree_Count(&o->tree, 0); -} - -static uint64_t IndexedList_IndexOf (IndexedList *o, IndexedListNode *node) -{ - return IndexedList__Tree_IndexOf(&o->tree, 0, IndexedList__TreeDeref(0, node)); -} - -static IndexedListNode * IndexedList_GetAt (IndexedList *o, uint64_t index) -{ - ASSERT(index < IndexedList__Tree_Count(&o->tree, 0)) - - IndexedList__TreeRef ref = IndexedList__Tree_GetAt(&o->tree, 0, index); - ASSERT(!IndexedList__TreeIsNullRef(ref)) - - return ref.ptr; -} - -static IndexedListNode * IndexedList_GetFirst (IndexedList *o) -{ - return IndexedList__deref(IndexedList__Tree_GetFirst(&o->tree, 0)); -} - -static IndexedListNode * IndexedList_GetLast (IndexedList *o) -{ - return IndexedList__deref(IndexedList__Tree_GetLast(&o->tree, 0)); -} - -static IndexedListNode * IndexedList_GetNext (IndexedList *o, IndexedListNode *node) -{ - ASSERT(node) - - return IndexedList__deref(IndexedList__Tree_GetNext(&o->tree, 0, IndexedList__TreeDeref(0, node))); -} - -static IndexedListNode * IndexedList_GetPrev (IndexedList *o, IndexedListNode *node) -{ - ASSERT(node) - - return IndexedList__deref(IndexedList__Tree_GetPrev(&o->tree, 0, IndexedList__TreeDeref(0, node))); -} - -#endif diff --git a/external/badvpn_dns/structure/IndexedList_tree.h b/external/badvpn_dns/structure/IndexedList_tree.h deleted file mode 100644 index 130f00f..0000000 --- a/external/badvpn_dns/structure/IndexedList_tree.h +++ /dev/null @@ -1,15 +0,0 @@ -#define CAVL_PARAM_NAME IndexedList__Tree -#define CAVL_PARAM_FEATURE_COUNTS 1 -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 1 -#define CAVL_PARAM_FEATURE_NOKEYS 0 -#define CAVL_PARAM_TYPE_ENTRY IndexedListNode -#define CAVL_PARAM_TYPE_LINK IndexedList__tree_link -#define CAVL_PARAM_TYPE_ARG int -#define CAVL_PARAM_TYPE_COUNT uint64_t -#define CAVL_PARAM_VALUE_COUNT_MAX UINT64_MAX -#define CAVL_PARAM_VALUE_NULL ((IndexedList__tree_link)NULL) -#define CAVL_PARAM_FUN_DEREF(arg, link) (link) -#define CAVL_PARAM_MEMBER_CHILD tree_child -#define CAVL_PARAM_MEMBER_BALANCE tree_balance -#define CAVL_PARAM_MEMBER_PARENT tree_parent -#define CAVL_PARAM_MEMBER_COUNT tree_count diff --git a/external/badvpn_dns/structure/LinkedList0.h b/external/badvpn_dns/structure/LinkedList0.h deleted file mode 100644 index feef4d7..0000000 --- a/external/badvpn_dns/structure/LinkedList0.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file LinkedList0.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Very simple doubly linked list, with only a 'first' pointer an no 'last' - * pointer. - */ - -#ifndef BADVPN_STRUCTURE_LINKEDLIST0_H -#define BADVPN_STRUCTURE_LINKEDLIST0_H - -#include <stddef.h> - -#include <misc/debug.h> - -/** - * Linked list node. - */ -typedef struct LinkedList0Node_t -{ - struct LinkedList0Node_t *p; - struct LinkedList0Node_t *n; -} LinkedList0Node; - -/** - * Simple doubly linked list. - */ -typedef struct -{ - LinkedList0Node *first; -} LinkedList0; - -/** - * Initializes the linked list. - * - * @param list list to initialize - */ -static void LinkedList0_Init (LinkedList0 *list); - -/** - * Determines if the list is empty. - * - * @param list the list - * @return 1 if empty, 0 if not - */ -static int LinkedList0_IsEmpty (LinkedList0 *list); - -/** - * Returns the first node of the list. - * - * @param list the list - * @return first node of the list, or NULL if the list is empty - */ -static LinkedList0Node * LinkedList0_GetFirst (LinkedList0 *list); - -/** - * Inserts a node to the beginning of the list. - * - * @param list the list - * @param node uninitialized node to insert - */ -static void LinkedList0_Prepend (LinkedList0 *list, LinkedList0Node *node); - -/** - * Inserts a node before a given node. - * - * @param list the list - * @param node uninitialized node to insert - * @param target node in the list to insert before - */ -static void LinkedList0_InsertBefore (LinkedList0 *list, LinkedList0Node *node, LinkedList0Node *target); - -/** - * Inserts a node after a given node. - * - * @param list the list - * @param node uninitialized node to insert - * @param target node in the list to insert after - */ -static void LinkedList0_InsertAfter (LinkedList0 *list, LinkedList0Node *node, LinkedList0Node *target); - -/** - * Removes a node from the list. - * - * @param list the list - * @param node node to remove - */ -static void LinkedList0_Remove (LinkedList0 *list, LinkedList0Node *node); - -/** - * Returns the next node of a given node. - * - * @param node reference node - * @return next node, or NULL if none - */ -static LinkedList0Node * LinkedList0Node_Next (LinkedList0Node *node); - -/** - * Returns the previous node of a given node. - * - * @param node reference node - * @return previous node, or NULL if none - */ -static LinkedList0Node * LinkedList0Node_Prev (LinkedList0Node *node); - -void LinkedList0_Init (LinkedList0 *list) -{ - list->first = NULL; -} - -int LinkedList0_IsEmpty (LinkedList0 *list) -{ - return (!list->first); -} - -LinkedList0Node * LinkedList0_GetFirst (LinkedList0 *list) -{ - return (list->first); -} - -void LinkedList0_Prepend (LinkedList0 *list, LinkedList0Node *node) -{ - node->p = NULL; - node->n = list->first; - if (list->first) { - list->first->p = node; - } - list->first = node; -} - -void LinkedList0_InsertBefore (LinkedList0 *list, LinkedList0Node *node, LinkedList0Node *target) -{ - node->p = target->p; - node->n = target; - if (target->p) { - target->p->n = node; - } else { - list->first = node; - } - target->p = node; -} - -void LinkedList0_InsertAfter (LinkedList0 *list, LinkedList0Node *node, LinkedList0Node *target) -{ - node->p = target; - node->n = target->n; - if (target->n) { - target->n->p = node; - } - target->n = node; -} - -void LinkedList0_Remove (LinkedList0 *list, LinkedList0Node *node) -{ - // remove from list - if (node->p) { - node->p->n = node->n; - } else { - list->first = node->n; - } - if (node->n) { - node->n->p = node->p; - } -} - -LinkedList0Node * LinkedList0Node_Next (LinkedList0Node *node) -{ - return node->n; -} - -LinkedList0Node * LinkedList0Node_Prev (LinkedList0Node *node) -{ - return node->p; -} - -#endif diff --git a/external/badvpn_dns/structure/LinkedList1.h b/external/badvpn_dns/structure/LinkedList1.h deleted file mode 100644 index bdb7161..0000000 --- a/external/badvpn_dns/structure/LinkedList1.h +++ /dev/null @@ -1,275 +0,0 @@ -/** - * @file LinkedList1.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Simple doubly linked list. - */ - -#ifndef BADVPN_STRUCTURE_LINKEDLIST1_H -#define BADVPN_STRUCTURE_LINKEDLIST1_H - -#include <stddef.h> - -#include <misc/debug.h> - -/** - * Linked list node. - */ -typedef struct LinkedList1Node_t -{ - struct LinkedList1Node_t *p; - struct LinkedList1Node_t *n; -} LinkedList1Node; - -/** - * Simple doubly linked list. - */ -typedef struct -{ - LinkedList1Node *first; - LinkedList1Node *last; -} LinkedList1; - -/** - * Initializes the linked list. - * - * @param list list to initialize - */ -static void LinkedList1_Init (LinkedList1 *list); - -/** - * Determines if the list is empty. - * - * @param list the list - * @return 1 if empty, 0 if not - */ -static int LinkedList1_IsEmpty (LinkedList1 *list); - -/** - * Returns the first node of the list. - * - * @param list the list - * @return first node of the list, or NULL if the list is empty - */ -static LinkedList1Node * LinkedList1_GetFirst (LinkedList1 *list); - -/** - * Returns the last node of the list. - * - * @param list the list - * @return last node of the list, or NULL if the list is empty - */ -static LinkedList1Node * LinkedList1_GetLast (LinkedList1 *list); - -/** - * Inserts a node to the beginning of the list. - * - * @param list the list - * @param node uninitialized node to insert - */ -static void LinkedList1_Prepend (LinkedList1 *list, LinkedList1Node *node); - -/** - * Inserts a node to the end of the list. - * - * @param list the list - * @param node uninitialized node to insert - */ -static void LinkedList1_Append (LinkedList1 *list, LinkedList1Node *node); - -/** - * Inserts a node before a given node. - * - * @param list the list - * @param node uninitialized node to insert - * @param target node in the list to insert before - */ -static void LinkedList1_InsertBefore (LinkedList1 *list, LinkedList1Node *node, LinkedList1Node *target); - -/** - * Inserts a node after a given node. - * - * @param list the list - * @param node uninitialized node to insert - * @param target node in the list to insert after - */ -static void LinkedList1_InsertAfter (LinkedList1 *list, LinkedList1Node *node, LinkedList1Node *target); - -/** - * Removes a node from the list. - * - * @param list the list - * @param node node to remove - */ -static void LinkedList1_Remove (LinkedList1 *list, LinkedList1Node *node); - -/** - * Inserts the nodes in the list \a ins_list into this list, after the node \a target. - * If \a target is NULL, the nodes are inserted to the beginning. - * Note that because the first and last node in \a ins_list are modified - * (unless the list is empty), \a ins_list is invalidated and must no longer - * be used to access the inserted nodes. - */ -static void LinkedList1_InsertListAfter (LinkedList1 *list, LinkedList1 ins_list, LinkedList1Node *target); - -/** - * Returns the next node of a given node. - * - * @param node reference node - * @return next node, or NULL if none - */ -static LinkedList1Node * LinkedList1Node_Next (LinkedList1Node *node); - -/** - * Returns the previous node of a given node. - * - * @param node reference node - * @return previous node, or NULL if none - */ -static LinkedList1Node * LinkedList1Node_Prev (LinkedList1Node *node); - -void LinkedList1_Init (LinkedList1 *list) -{ - list->first = NULL; - list->last = NULL; -} - -int LinkedList1_IsEmpty (LinkedList1 *list) -{ - return (!list->first); -} - -LinkedList1Node * LinkedList1_GetFirst (LinkedList1 *list) -{ - return (list->first); -} - -LinkedList1Node * LinkedList1_GetLast (LinkedList1 *list) -{ - return (list->last); -} - -void LinkedList1_Prepend (LinkedList1 *list, LinkedList1Node *node) -{ - node->p = NULL; - node->n = list->first; - if (list->first) { - list->first->p = node; - } else { - list->last = node; - } - list->first = node; -} - -void LinkedList1_Append (LinkedList1 *list, LinkedList1Node *node) -{ - node->p = list->last; - node->n = NULL; - if (list->last) { - list->last->n = node; - } else { - list->first = node; - } - list->last = node; -} - -void LinkedList1_InsertBefore (LinkedList1 *list, LinkedList1Node *node, LinkedList1Node *target) -{ - node->p = target->p; - node->n = target; - if (target->p) { - target->p->n = node; - } else { - list->first = node; - } - target->p = node; -} - -void LinkedList1_InsertAfter (LinkedList1 *list, LinkedList1Node *node, LinkedList1Node *target) -{ - node->p = target; - node->n = target->n; - if (target->n) { - target->n->p = node; - } else { - list->last = node; - } - target->n = node; -} - -void LinkedList1_Remove (LinkedList1 *list, LinkedList1Node *node) -{ - // remove from list - if (node->p) { - node->p->n = node->n; - } else { - list->first = node->n; - } - if (node->n) { - node->n->p = node->p; - } else { - list->last = node->p; - } -} - -void LinkedList1_InsertListAfter (LinkedList1 *list, LinkedList1 ins_list, LinkedList1Node *target) -{ - if (!ins_list.first) { - return; - } - - LinkedList1Node *t_next = (target ? target->n : list->first); - - ins_list.first->p = target; - ins_list.last->n = t_next; - - if (target) { - target->n = ins_list.first; - } else { - list->first = ins_list.first; - } - - if (t_next) { - t_next->p = ins_list.last; - } else { - list->last = ins_list.last; - } -} - -LinkedList1Node * LinkedList1Node_Next (LinkedList1Node *node) -{ - return node->n; -} - -LinkedList1Node * LinkedList1Node_Prev (LinkedList1Node *node) -{ - return node->p; -} - -#endif diff --git a/external/badvpn_dns/structure/LinkedList3.h b/external/badvpn_dns/structure/LinkedList3.h deleted file mode 100644 index 8f54cdb..0000000 --- a/external/badvpn_dns/structure/LinkedList3.h +++ /dev/null @@ -1,362 +0,0 @@ -/** - * @file LinkedList3.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Doubly linked list that support multiple iterations and removing - * aritrary elements during iteration, without a central object to - * represent the list. - */ - -#ifndef BADVPN_STRUCTURE_LINKEDLIST3_H -#define BADVPN_STRUCTURE_LINKEDLIST3_H - -#include <stddef.h> -#include <stdint.h> - -#include <misc/debug.h> - -struct _LinkedList3Iterator; - -/** - * Linked list node. - */ -typedef struct _LinkedList3Node { - struct _LinkedList3Node *p; - struct _LinkedList3Node *n; - struct _LinkedList3Iterator *it; -} LinkedList3Node; - -/** - * Linked list iterator. - */ -typedef struct _LinkedList3Iterator { - int8_t dir; - struct _LinkedList3Node *e; - struct _LinkedList3Iterator *pi; - struct _LinkedList3Iterator *ni; -} LinkedList3Iterator; - -/** - * Initializes a list node to form a new list consisting of a - * single node. - * - * @param node list node structure to initialize. The node must remain - * available until it is freed with {@link LinkedList3Node_Free}, - * or the list is no longer required. - */ -static void LinkedList3Node_InitLonely (LinkedList3Node *node); - -/** - * Initializes a list node to go after an existing node. - * - * @param node list node structure to initialize. The node must remain - * available until it is freed with {@link LinkedList3Node_Free}, - * or the list is no longer required. - * @param ref existing list node - */ -static void LinkedList3Node_InitAfter (LinkedList3Node *node, LinkedList3Node *ref); - -/** - * Initializes a list node to go before an existing node. - * - * @param node list node structure to initialize. The node must remain - * available until it is freed with {@link LinkedList3Node_Free}, - * or the list is no longer required. - * @param ref existing list node - */ -static void LinkedList3Node_InitBefore (LinkedList3Node *node, LinkedList3Node *ref); - -/** - * Frees a list node, removing it a list (if there were other nodes - * in the list). - * - * @param node list node to free - */ -static void LinkedList3Node_Free (LinkedList3Node *node); - -/** - * Determines if a list node is a single node in a list. - * - * @param node list node - * @return 1 if the node ia a single node, 0 if not - */ -static int LinkedList3Node_IsLonely (LinkedList3Node *node); - -/** - * Returnes the node preceding this node (if there is one), - * the node following this node (if there is one), or NULL, - * respectively. - * - * @param node list node - * @return neighbour node or NULL if none - */ -static LinkedList3Node * LinkedList3Node_PrevOrNext (LinkedList3Node *node); - -/** - * Returnes the node following this node (if there is one), - * the node preceding this node (if there is one), or NULL, - * respectively. - * - * @param node list node - * @return neighbour node or NULL if none - */ -static LinkedList3Node * LinkedList3Node_NextOrPrev (LinkedList3Node *node); - -/** - * Returns the node preceding this node, or NULL if there is none. - * - * @param node list node - * @return left neighbour, or NULL if none - */ -static LinkedList3Node * LinkedList3Node_Prev (LinkedList3Node *node); - -/** - * Returns the node following this node, or NULL if there is none. - * - * @param node list node - * @return right neighbour, or NULL if none - */ -static LinkedList3Node * LinkedList3Node_Next (LinkedList3Node *node); - -/** - * Returns the first node in the list which this node is part of. - * It is found by iterating the list from this node to the beginning. - * - * @param node list node - * @return first node in the list - */ -static LinkedList3Node * LinkedList3Node_First (LinkedList3Node *node); - -/** - * Returns the last node in the list which this node is part of. - * It is found by iterating the list from this node to the end. - * - * @param node list node - * @return last node in the list - */ -static LinkedList3Node * LinkedList3Node_Last (LinkedList3Node *node); - -/** - * Initializes a linked list iterator. - * The iterator structure must remain available until either of these occurs: - * - the list is no longer needed, or - * - the iterator is freed with {@link LinkedList3Iterator_Free}, or - * - the iterator reaches the end of iteration. - * - * @param it uninitialized iterator to initialize - * @param e initial position of the iterator. NULL for end of iteration. - * @param dir direction of iteration. Must be 1 (forward) or -1 (backward). - */ -static void LinkedList3Iterator_Init (LinkedList3Iterator *it, LinkedList3Node *e, int dir); - -/** - * Frees a linked list iterator. - * - * @param it iterator to free - */ -static void LinkedList3Iterator_Free (LinkedList3Iterator *it); - -/** - * Moves the iterator one node forward or backward (depending on its direction), or, - * if it's at the last or first node (depending on the direction), it reaches - * the end of iteration, or, if it's at the end of iteration, it remains there. - * Returns the the previous position. - * - * @param it the iterator - * @return node on the position of iterator before it was (possibly) moved, or NULL - * if it was at the end of iteration - */ -static LinkedList3Node * LinkedList3Iterator_Next (LinkedList3Iterator *it); - -void LinkedList3Node_InitLonely (LinkedList3Node *node) -{ - node->p = NULL; - node->n = NULL; - node->it = NULL; -} - -void LinkedList3Node_InitAfter (LinkedList3Node *node, LinkedList3Node *ref) -{ - ASSERT(ref) - - node->p = ref; - node->n = ref->n; - ref->n = node; - if (node->n) { - node->n->p = node; - } - node->it = NULL; -} - -void LinkedList3Node_InitBefore (LinkedList3Node *node, LinkedList3Node *ref) -{ - ASSERT(ref) - - node->n = ref; - node->p = ref->p; - ref->p = node; - if (node->p) { - node->p->n = node; - } - node->it = NULL; -} - -void LinkedList3Node_Free (LinkedList3Node *node) -{ - // jump iterators - while (node->it) { - LinkedList3Iterator_Next(node->it); - } - - if (node->p) { - node->p->n = node->n; - } - if (node->n) { - node->n->p = node->p; - } -} - -int LinkedList3Node_IsLonely (LinkedList3Node *node) -{ - return (!node->p && !node->n); -} - -LinkedList3Node * LinkedList3Node_PrevOrNext (LinkedList3Node *node) -{ - if (node->p) { - return node->p; - } - if (node->n) { - return node->n; - } - return NULL; -} - -LinkedList3Node * LinkedList3Node_NextOrPrev (LinkedList3Node *node) -{ - if (node->n) { - return node->n; - } - if (node->p) { - return node->p; - } - return NULL; -} - -LinkedList3Node * LinkedList3Node_Prev (LinkedList3Node *node) -{ - return node->p; -} - -LinkedList3Node * LinkedList3Node_Next (LinkedList3Node *node) -{ - return node->n; -} - -LinkedList3Node * LinkedList3Node_First (LinkedList3Node *node) -{ - while (node->p) { - node = node->p; - } - - return node; -} - -LinkedList3Node * LinkedList3Node_Last (LinkedList3Node *node) -{ - while (node->n) { - node = node->n; - } - - return node; -} - -void LinkedList3Iterator_Init (LinkedList3Iterator *it, LinkedList3Node *e, int dir) -{ - ASSERT(dir == -1 || dir == 1) - - it->dir = dir; - it->e = e; - - if (e) { - // link into node's iterator list - it->pi = NULL; - it->ni = e->it; - if (e->it) { - e->it->pi = it; - } - e->it = it; - } -} - -void LinkedList3Iterator_Free (LinkedList3Iterator *it) -{ - if (it->e) { - // remove from node's iterator list - if (it->ni) { - it->ni->pi = it->pi; - } - if (it->pi) { - it->pi->ni = it->ni; - } else { - it->e->it = it->ni; - } - } -} - -LinkedList3Node * LinkedList3Iterator_Next (LinkedList3Iterator *it) -{ - // remember original entry - LinkedList3Node *orig = it->e; - - // jump to next entry - if (it->e) { - // get next entry - LinkedList3Node *next = NULL; // to remove warning - switch (it->dir) { - case 1: - next = it->e->n; - break; - case -1: - next = it->e->p; - break; - default: - ASSERT(0); - } - // destroy interator - LinkedList3Iterator_Free(it); - // re-initialize at next entry - LinkedList3Iterator_Init(it, next, it->dir); - } - - // return original entry - return orig; -} - -#endif diff --git a/external/badvpn_dns/structure/SAvl.h b/external/badvpn_dns/structure/SAvl.h deleted file mode 100644 index 6ea1399..0000000 --- a/external/badvpn_dns/structure/SAvl.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file SAvl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SAVL_H -#define BADVPN_SAVL_H - -#include <stddef.h> -#include <stdint.h> - -#include <structure/CAvl.h> -#include <misc/merge.h> -#include <misc/debug.h> - -#endif diff --git a/external/badvpn_dns/structure/SAvl_decl.h b/external/badvpn_dns/structure/SAvl_decl.h deleted file mode 100644 index 8a13e49..0000000 --- a/external/badvpn_dns/structure/SAvl_decl.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file SAvl_decl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SAvl_header.h" - -typedef SAvlEntry *SAvl__TreeLink; - -#include "SAvl_tree.h" -#include <structure/CAvl_decl.h> - -typedef struct { - SAvl__Tree tree; -} SAvl; - -typedef struct { - SAvlEntry *child[2]; - SAvlEntry *parent; - int8_t balance; -#if SAVL_PARAM_FEATURE_COUNTS - SAvlCount count; -#endif -} SAvlNode; - -static void SAvl_Init (SAvl *o); -static int SAvl_Insert (SAvl *o, SAvlArg arg, SAvlEntry *entry, SAvlEntry **out_existing); -static void SAvl_Remove (SAvl *o, SAvlArg arg, SAvlEntry *entry); -#if !SAVL_PARAM_FEATURE_NOKEYS -static SAvlEntry * SAvl_Lookup (const SAvl *o, SAvlArg arg, SAvlKey key); -static SAvlEntry * SAvl_LookupExact (const SAvl *o, SAvlArg arg, SAvlKey key); -static SAvlEntry * SAvl_GetFirstGreater (const SAvl *o, SAvlArg arg, SAvlKey key); -static SAvlEntry * SAvl_GetLastLesser (const SAvl *o, SAvlArg arg, SAvlKey key); -static SAvlEntry * SAvl_GetFirstGreaterEqual (const SAvl *o, SAvlArg arg, SAvlKey key); -static SAvlEntry * SAvl_GetLastLesserEqual (const SAvl *o, SAvlArg arg, SAvlKey key); -#endif -static SAvlEntry * SAvl_GetFirst (const SAvl *o, SAvlArg arg); -static SAvlEntry * SAvl_GetLast (const SAvl *o, SAvlArg arg); -static SAvlEntry * SAvl_GetNext (const SAvl *o, SAvlArg arg, SAvlEntry *entry); -static SAvlEntry * SAvl_GetPrev (const SAvl *o, SAvlArg arg, SAvlEntry *entry); -static int SAvl_IsEmpty (const SAvl *o); -static void SAvl_Verify (const SAvl *o, SAvlArg arg); -#if SAVL_PARAM_FEATURE_COUNTS -static SAvlCount SAvl_Count (const SAvl *o, SAvlArg arg); -static SAvlCount SAvl_IndexOf (const SAvl *o, SAvlArg arg, SAvlEntry *entry); -static SAvlEntry * SAvl_GetAt (const SAvl *o, SAvlArg arg, SAvlCount index); -#endif - -#include "SAvl_footer.h" diff --git a/external/badvpn_dns/structure/SAvl_footer.h b/external/badvpn_dns/structure/SAvl_footer.h deleted file mode 100644 index ad90e40..0000000 --- a/external/badvpn_dns/structure/SAvl_footer.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file SAvl_footer.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#undef SAVL_PARAM_NAME -#undef SAVL_PARAM_FEATURE_COUNTS -#undef SAVL_PARAM_FEATURE_NOKEYS -#undef SAVL_PARAM_TYPE_ENTRY -#undef SAVL_PARAM_TYPE_KEY -#undef SAVL_PARAM_TYPE_ARG -#undef SAVL_PARAM_TYPE_COUNT -#undef SAVL_PARAM_VALUE_COUNT_MAX -#undef SAVL_PARAM_FUN_COMPARE_ENTRIES -#undef SAVL_PARAM_FUN_COMPARE_KEY_ENTRY -#undef SAVL_PARAM_MEMBER_NODE - -#undef SAvl -#undef SAvlEntry -#undef SAvlArg -#undef SAvlKey -#undef SAvlCount -#undef SAvlNode - -#undef SAvl_Init -#undef SAvl_Insert -#undef SAvl_Remove -#undef SAvl_Lookup -#undef SAvl_LookupExact -#undef SAvl_GetFirstGreater -#undef SAvl_GetLastLesser -#undef SAvl_GetFirstGreaterEqual -#undef SAvl_GetLastLesserEqual -#undef SAvl_GetFirst -#undef SAvl_GetLast -#undef SAvl_GetNext -#undef SAvl_GetPrev -#undef SAvl_IsEmpty -#undef SAvl_Verify -#undef SAvl_Count -#undef SAvl_IndexOf -#undef SAvl_GetAt - -#undef SAvl__Tree -#undef SAvl__TreeRef -#undef SAvl__TreeLink -#undef SAvl__TreeDeref -#undef SAvl__Tree_Init -#undef SAvl__Tree_Insert -#undef SAvl__Tree_Remove -#undef SAvl__Tree_Lookup -#undef SAvl__Tree_LookupExact -#undef SAvl__Tree_GetFirstGreater -#undef SAvl__Tree_GetLastLesser -#undef SAvl__Tree_GetFirstGreaterEqual -#undef SAvl__Tree_GetLastLesserEqual -#undef SAvl__Tree_GetFirst -#undef SAvl__Tree_GetLast -#undef SAvl__Tree_GetNext -#undef SAvl__Tree_GetPrev -#undef SAvl__Tree_IsEmpty -#undef SAvl__Tree_Verify -#undef SAvl__Tree_Count -#undef SAvl__Tree_IndexOf -#undef SAvl__Tree_GetAt diff --git a/external/badvpn_dns/structure/SAvl_header.h b/external/badvpn_dns/structure/SAvl_header.h deleted file mode 100644 index 5d7d9b1..0000000 --- a/external/badvpn_dns/structure/SAvl_header.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file SAvl_header.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Preprocessor inputs. All types must be typedef names unless stated otherwise. -// SAVL_PARAM_NAME - name of this data structure -// SAVL_PARAM_FEATURE_COUNTS - whether to keep count information (0 or 1) -// SAVL_PARAM_FEATURE_NOKEYS - define to 1 if there is no need for a lookup operation -// SAVL_PARAM_TYPE_ENTRY - type of entry. This can also be a struct (e.g.: struct Foo). -// SAVL_PARAM_TYPE_KEY - type of key (ignored if SAVL_PARAM_FEATURE_NOKEYS) -// SAVL_PARAM_TYPE_ARG - type of argument pass through to callbacks -// SAVL_PARAM_TYPE_COUNT - type of count (only if SAVL_PARAM_FEATURE_COUNTS) -// SAVL_PARAM_VALUE_COUNT_MAX - maximum value of count (of type SAVL_PARAM_TYPE_COUNT) (only if SAVL_PARAM_FEATURE_COUNTS) -// SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) - compare two entries; returns -1/0/1 -// SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) - compare key and entry; returns -1/0/1 (ignored if SAVL_PARAM_FEATURE_NOKEYS) -// SAVL_PARAM_MEMBER_NODE - node member in entry - -// types -#define SAvl SAVL_PARAM_NAME -#define SAvlEntry SAVL_PARAM_TYPE_ENTRY -#define SAvlArg SAVL_PARAM_TYPE_ARG -#define SAvlKey SAVL_PARAM_TYPE_KEY -#define SAvlCount SAVL_PARAM_TYPE_COUNT -#define SAvlNode MERGE(SAvl, Node) - -// public functions -#define SAvl_Init MERGE(SAvl, _Init) -#define SAvl_Insert MERGE(SAvl, _Insert) -#define SAvl_Remove MERGE(SAvl, _Remove) -#define SAvl_Lookup MERGE(SAvl, _Lookup) -#define SAvl_LookupExact MERGE(SAvl, _LookupExact) -#define SAvl_GetFirstGreater MERGE(SAvl, _GetFirstGreater) -#define SAvl_GetLastLesser MERGE(SAvl, _GetLastLesser) -#define SAvl_GetFirstGreaterEqual MERGE(SAvl, _GetFirstGreaterEqual) -#define SAvl_GetLastLesserEqual MERGE(SAvl, _GetLastLesserEqual) -#define SAvl_GetFirst MERGE(SAvl, _GetFirst) -#define SAvl_GetLast MERGE(SAvl, _GetLast) -#define SAvl_GetNext MERGE(SAvl, _GetNext) -#define SAvl_GetPrev MERGE(SAvl, _GetPrev) -#define SAvl_IsEmpty MERGE(SAvl, _IsEmpty) -#define SAvl_Verify MERGE(SAvl, _Verify) -#define SAvl_Count MERGE(SAvl, _Count) -#define SAvl_IndexOf MERGE(SAvl, _IndexOf) -#define SAvl_GetAt MERGE(SAvl, _GetAt) - -// internal stuff -#define SAvl__Tree MERGE(SAvl, __Tree) -#define SAvl__TreeRef MERGE(SAvl, __TreeRef) -#define SAvl__TreeLink MERGE(SAvl, __TreeLink) -#define SAvl__TreeDeref MERGE(SAvl, __TreeDeref) -#define SAvl__Tree_Init MERGE(SAvl, __Tree_Init) -#define SAvl__Tree_Insert MERGE(SAvl, __Tree_Insert) -#define SAvl__Tree_Remove MERGE(SAvl, __Tree_Remove) -#define SAvl__Tree_Lookup MERGE(SAvl, __Tree_Lookup) -#define SAvl__Tree_LookupExact MERGE(SAvl, __Tree_LookupExact) -#define SAvl__Tree_GetFirstGreater MERGE(SAvl, __Tree_GetFirstGreater) -#define SAvl__Tree_GetLastLesser MERGE(SAvl, __Tree_GetLastLesser) -#define SAvl__Tree_GetFirstGreaterEqual MERGE(SAvl, __Tree_GetFirstGreaterEqual) -#define SAvl__Tree_GetLastLesserEqual MERGE(SAvl, __Tree_GetLastLesserEqual) -#define SAvl__Tree_GetFirst MERGE(SAvl, __Tree_GetFirst) -#define SAvl__Tree_GetLast MERGE(SAvl, __Tree_GetLast) -#define SAvl__Tree_GetNext MERGE(SAvl, __Tree_GetNext) -#define SAvl__Tree_GetPrev MERGE(SAvl, __Tree_GetPrev) -#define SAvl__Tree_IsEmpty MERGE(SAvl, __Tree_IsEmpty) -#define SAvl__Tree_Verify MERGE(SAvl, __Tree_Verify) -#define SAvl__Tree_Count MERGE(SAvl, __Tree_Count) -#define SAvl__Tree_IndexOf MERGE(SAvl, __Tree_IndexOf) -#define SAvl__Tree_GetAt MERGE(SAvl, __Tree_GetAt) diff --git a/external/badvpn_dns/structure/SAvl_impl.h b/external/badvpn_dns/structure/SAvl_impl.h deleted file mode 100644 index 0d3973a..0000000 --- a/external/badvpn_dns/structure/SAvl_impl.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file SAvl_impl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SAvl_header.h" - -#include "SAvl_tree.h" -#include <structure/CAvl_impl.h> - -static void SAvl_Init (SAvl *o) -{ - SAvl__Tree_Init(&o->tree); -} - -static int SAvl_Insert (SAvl *o, SAvlArg arg, SAvlEntry *entry, SAvlEntry **out_existing) -{ - ASSERT(entry) -#if SAVL_PARAM_FEATURE_COUNTS - ASSERT(SAvl_Count(o, arg) < SAVL_PARAM_VALUE_COUNT_MAX) -#endif - - SAvl__TreeRef out_ref; - int res = SAvl__Tree_Insert(&o->tree, arg, SAvl__TreeDeref(arg, entry), &out_ref); - - if (out_existing) { - *out_existing = out_ref.link; - } - - return res; -} - -static void SAvl_Remove (SAvl *o, SAvlArg arg, SAvlEntry *entry) -{ - ASSERT(entry) - - SAvl__Tree_Remove(&o->tree, arg, SAvl__TreeDeref(arg, entry)); -} - -#if !SAVL_PARAM_FEATURE_NOKEYS - -static SAvlEntry * SAvl_Lookup (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_Lookup(&o->tree, arg, key); - return ref.link; -} - -static SAvlEntry * SAvl_LookupExact (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_LookupExact(&o->tree, arg, key); - return ref.link; -} - -static SAvlEntry * SAvl_GetFirstGreater (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_GetFirstGreater(&o->tree, arg, key); - return ref.link; -} - -static SAvlEntry * SAvl_GetLastLesser (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_GetLastLesser(&o->tree, arg, key); - return ref.link; -} - -static SAvlEntry * SAvl_GetFirstGreaterEqual (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_GetFirstGreaterEqual(&o->tree, arg, key); - return ref.link; -} - -static SAvlEntry * SAvl_GetLastLesserEqual (const SAvl *o, SAvlArg arg, SAvlKey key) -{ - SAvl__TreeRef ref = SAvl__Tree_GetLastLesserEqual(&o->tree, arg, key); - return ref.link; -} - -#endif - -static SAvlEntry * SAvl_GetFirst (const SAvl *o, SAvlArg arg) -{ - SAvl__TreeRef ref = SAvl__Tree_GetFirst(&o->tree, arg); - return ref.link; -} - -static SAvlEntry * SAvl_GetLast (const SAvl *o, SAvlArg arg) -{ - SAvl__TreeRef ref = SAvl__Tree_GetLast(&o->tree, arg); - return ref.link; -} - -static SAvlEntry * SAvl_GetNext (const SAvl *o, SAvlArg arg, SAvlEntry *entry) -{ - ASSERT(entry) - - SAvl__TreeRef ref = SAvl__Tree_GetNext(&o->tree, arg, SAvl__TreeDeref(arg, entry)); - return ref.link; -} - -static SAvlEntry * SAvl_GetPrev (const SAvl *o, SAvlArg arg, SAvlEntry *entry) -{ - ASSERT(entry) - - SAvl__TreeRef ref = SAvl__Tree_GetPrev(&o->tree, arg, SAvl__TreeDeref(arg, entry)); - return ref.link; -} - -static int SAvl_IsEmpty (const SAvl *o) -{ - return SAvl__Tree_IsEmpty(&o->tree); -} - -static void SAvl_Verify (const SAvl *o, SAvlArg arg) -{ - return SAvl__Tree_Verify(&o->tree, arg); -} - -#if SAVL_PARAM_FEATURE_COUNTS - -static SAvlCount SAvl_Count (const SAvl *o, SAvlArg arg) -{ - return SAvl__Tree_Count(&o->tree, arg); -} - -static SAvlCount SAvl_IndexOf (const SAvl *o, SAvlArg arg, SAvlEntry *entry) -{ - ASSERT(entry) - - return SAvl__Tree_IndexOf(&o->tree, arg, SAvl__TreeDeref(arg, entry)); -} - -static SAvlEntry * SAvl_GetAt (const SAvl *o, SAvlArg arg, SAvlCount index) -{ - SAvl__TreeRef ref = SAvl__Tree_GetAt(&o->tree, arg, index); - return ref.link; -} - -#endif - -#include "SAvl_footer.h" diff --git a/external/badvpn_dns/structure/SAvl_tree.h b/external/badvpn_dns/structure/SAvl_tree.h deleted file mode 100644 index 5e5b18b..0000000 --- a/external/badvpn_dns/structure/SAvl_tree.h +++ /dev/null @@ -1,18 +0,0 @@ -#define CAVL_PARAM_NAME SAvl__Tree -#define CAVL_PARAM_FEATURE_COUNTS SAVL_PARAM_FEATURE_COUNTS -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0 -#define CAVL_PARAM_FEATURE_NOKEYS SAVL_PARAM_FEATURE_NOKEYS -#define CAVL_PARAM_TYPE_ENTRY SAvlEntry -#define CAVL_PARAM_TYPE_LINK SAvl__TreeLink -#define CAVL_PARAM_TYPE_KEY SAvlKey -#define CAVL_PARAM_TYPE_ARG SAvlArg -#define CAVL_PARAM_TYPE_COUNT SAvlCount -#define CAVL_PARAM_VALUE_COUNT_MAX SAVL_PARAM_VALUE_COUNT_MAX -#define CAVL_PARAM_VALUE_NULL ((SAvl__TreeLink)NULL) -#define CAVL_PARAM_FUN_DEREF(arg, link) (link) -#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) SAVL_PARAM_FUN_COMPARE_ENTRIES((arg), (entry1).link, (entry2).link) -#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) SAVL_PARAM_FUN_COMPARE_KEY_ENTRY((arg), (key1), (entry2).link) -#define CAVL_PARAM_MEMBER_CHILD SAVL_PARAM_MEMBER_NODE . child -#define CAVL_PARAM_MEMBER_BALANCE SAVL_PARAM_MEMBER_NODE . balance -#define CAVL_PARAM_MEMBER_PARENT SAVL_PARAM_MEMBER_NODE . parent -#define CAVL_PARAM_MEMBER_COUNT SAVL_PARAM_MEMBER_NODE . count diff --git a/external/badvpn_dns/structure/SLinkedList.h b/external/badvpn_dns/structure/SLinkedList.h deleted file mode 100644 index 1edb016..0000000 --- a/external/badvpn_dns/structure/SLinkedList.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file SLinkedList.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SLINKEDLIST_H -#define BADVPN_SLINKEDLIST_H - -#include <stddef.h> - -#include <misc/merge.h> -#include <misc/debug.h> - -#endif diff --git a/external/badvpn_dns/structure/SLinkedList_decl.h b/external/badvpn_dns/structure/SLinkedList_decl.h deleted file mode 100644 index 4a0ade4..0000000 --- a/external/badvpn_dns/structure/SLinkedList_decl.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @file SLinkedList_decl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SLinkedList_header.h" - -typedef struct { - SLinkedListEntry *first; -#if SLINKEDLIST_PARAM_FEATURE_LAST - SLinkedListEntry *last; -#endif -} SLinkedList; - -typedef struct { - SLinkedListEntry *prev; - SLinkedListEntry *next; -} SLinkedListNode; - -static void SLinkedListMarkRemoved (SLinkedListEntry *entry); -static int SLinkedListIsRemoved (SLinkedListEntry *entry); - -static void SLinkedList_Init (SLinkedList *o); -static SLinkedListEntry * SLinkedList_Next (SLinkedList *o, SLinkedListEntry *entry); -static SLinkedListEntry * SLinkedList_Prev (SLinkedList *o, SLinkedListEntry *entry); -static void SLinkedList_Prepend (SLinkedList *o, SLinkedListEntry *entry); -#if SLINKEDLIST_PARAM_FEATURE_LAST -static void SLinkedList_Append (SLinkedList *o, SLinkedListEntry *entry); -#endif -static void SLinkedList_InsertBefore (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *before_entry); -static void SLinkedList_InsertAfter (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *after_entry); -static void SLinkedList_Remove (SLinkedList *o, SLinkedListEntry *entry); -static void SLinkedList_RemoveFirst (SLinkedList *o); -#if SLINKEDLIST_PARAM_FEATURE_LAST -static void SLinkedList_RemoveLast (SLinkedList *o); -#endif -static SLinkedListEntry * SLinkedList_First (const SLinkedList *o); -#if SLINKEDLIST_PARAM_FEATURE_LAST -static SLinkedListEntry * SLinkedList_Last (const SLinkedList *o); -#endif -static int SLinkedList_IsEmpty (const SLinkedList *o); - -#include "SLinkedList_footer.h" diff --git a/external/badvpn_dns/structure/SLinkedList_footer.h b/external/badvpn_dns/structure/SLinkedList_footer.h deleted file mode 100644 index 10ab1e3..0000000 --- a/external/badvpn_dns/structure/SLinkedList_footer.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file SLinkedList_footer.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#undef SLINKEDLIST_PARAM_NAME -#undef SLINKEDLIST_PARAM_FEATURE_LAST -#undef SLINKEDLIST_PARAM_TYPE_ENTRY -#undef SLINKEDLIST_PARAM_MEMBER_NODE - -#undef SLinkedList -#undef SLinkedListEntry -#undef SLinkedListNode - -#undef SLinkedListMarkRemoved -#undef SLinkedListIsRemoved - -#undef SLinkedList_Init -#undef SLinkedList_Next -#undef SLinkedList_Prev -#undef SLinkedList_Prepend -#undef SLinkedList_Append -#undef SLinkedList_InsertBefore -#undef SLinkedList_InsertAfter -#undef SLinkedList_Remove -#undef SLinkedList_RemoveFirst -#undef SLinkedList_RemoveLast -#undef SLinkedList_First -#undef SLinkedList_Last -#undef SLinkedList_IsEmpty - -#undef SLinkedList_prev -#undef SLinkedList_next diff --git a/external/badvpn_dns/structure/SLinkedList_header.h b/external/badvpn_dns/structure/SLinkedList_header.h deleted file mode 100644 index 4a0fd54..0000000 --- a/external/badvpn_dns/structure/SLinkedList_header.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file SLinkedList_header.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Preprocessor inputs: -// SLINKEDLIST_PARAM_NAME - name of this data structure -// SLINKEDLIST_PARAM_FEATURE_LAST - whether to keep track of the last entry in the list (0/1) -// SLINKEDLIST_PARAM_TYPE_ENTRY - type of entry -// SLINKEDLIST_PARAM_MEMBER_NODE - name of the node member in entry - -// types -#define SLinkedList SLINKEDLIST_PARAM_NAME -#define SLinkedListEntry SLINKEDLIST_PARAM_TYPE_ENTRY -#define SLinkedListNode MERGE(SLinkedList, Node) - -// non-object public functions -#define SLinkedListMarkRemoved MERGE(SLinkedList, MarkRemoved) -#define SLinkedListIsRemoved MERGE(SLinkedList, IsRemoved) - -// public functions -#define SLinkedList_Init MERGE(SLinkedList, _Init) -#define SLinkedList_Next MERGE(SLinkedList, _Next) -#define SLinkedList_Prev MERGE(SLinkedList, _Prev) -#define SLinkedList_Prepend MERGE(SLinkedList, _Prepend) -#define SLinkedList_Append MERGE(SLinkedList, _Append) -#define SLinkedList_InsertBefore MERGE(SLinkedList, _InsertBefore) -#define SLinkedList_InsertAfter MERGE(SLinkedList, _InsertAfter) -#define SLinkedList_Remove MERGE(SLinkedList, _Remove) -#define SLinkedList_RemoveFirst MERGE(SLinkedList, _RemoveFirst) -#define SLinkedList_RemoveLast MERGE(SLinkedList, _RemoveLast) -#define SLinkedList_First MERGE(SLinkedList, _First) -#define SLinkedList_Last MERGE(SLinkedList, _Last) -#define SLinkedList_IsEmpty MERGE(SLinkedList, _IsEmpty) - -// private things -#define SLinkedList_prev(entry) ((entry)->SLINKEDLIST_PARAM_MEMBER_NODE . prev) -#define SLinkedList_next(entry) ((entry)->SLINKEDLIST_PARAM_MEMBER_NODE . next) diff --git a/external/badvpn_dns/structure/SLinkedList_impl.h b/external/badvpn_dns/structure/SLinkedList_impl.h deleted file mode 100644 index 1bbce9a..0000000 --- a/external/badvpn_dns/structure/SLinkedList_impl.h +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file SLinkedList_impl.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SLinkedList_header.h" - -static void SLinkedListMarkRemoved (SLinkedListEntry *entry) -{ - ASSERT(entry) - - SLinkedList_next(entry) = entry; -} - -static int SLinkedListIsRemoved (SLinkedListEntry *entry) -{ - ASSERT(entry) - - return (entry == SLinkedList_next(entry)); -} - -static void SLinkedList_Init (SLinkedList *o) -{ - o->first = NULL; -} - -static SLinkedListEntry * SLinkedList_Next (SLinkedList *o, SLinkedListEntry *entry) -{ - ASSERT(entry) - - return SLinkedList_next(entry); -} - -static SLinkedListEntry * SLinkedList_Prev (SLinkedList *o, SLinkedListEntry *entry) -{ - ASSERT(entry) - - return (entry == o->first) ? NULL : SLinkedList_prev(entry); -} - -static void SLinkedList_Prepend (SLinkedList *o, SLinkedListEntry *entry) -{ - ASSERT(entry) - - SLinkedList_next(entry) = o->first; - if (o->first) { - SLinkedList_prev(o->first) = entry; - } else { -#if SLINKEDLIST_PARAM_FEATURE_LAST - o->last = entry; -#endif - } - o->first = entry; -} - -#if SLINKEDLIST_PARAM_FEATURE_LAST -static void SLinkedList_Append (SLinkedList *o, SLinkedListEntry *entry) -{ - ASSERT(entry) - - SLinkedList_next(entry) = NULL; - if (o->first) { - SLinkedList_prev(entry) = o->last; - SLinkedList_next(o->last) = entry; - } else { - o->first = entry; - } - o->last = entry; -} -#endif - -static void SLinkedList_InsertBefore (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *before_entry) -{ - ASSERT(entry) - ASSERT(before_entry) - - SLinkedList_next(entry) = before_entry; - if (before_entry != o->first) { - SLinkedList_prev(entry) = SLinkedList_prev(before_entry); - SLinkedList_next(SLinkedList_prev(before_entry)) = entry; - } else { - o->first = entry; - } - SLinkedList_prev(before_entry) = entry; -} - -static void SLinkedList_InsertAfter (SLinkedList *o, SLinkedListEntry *entry, SLinkedListEntry *after_entry) -{ - ASSERT(entry) - ASSERT(after_entry) - - SLinkedList_next(entry) = SLinkedList_next(after_entry); - SLinkedList_prev(entry) = after_entry; - if (SLinkedList_next(after_entry)) { - SLinkedList_prev(SLinkedList_next(after_entry)) = entry; - } else { -#if SLINKEDLIST_PARAM_FEATURE_LAST - o->last = entry; -#endif - } - SLinkedList_next(after_entry) = entry; -} - -static void SLinkedList_Remove (SLinkedList *o, SLinkedListEntry *entry) -{ - if (entry != o->first) { - SLinkedList_next(SLinkedList_prev(entry)) = SLinkedList_next(entry); - if (SLinkedList_next(entry)) { - SLinkedList_prev(SLinkedList_next(entry)) = SLinkedList_prev(entry); - } else { -#if SLINKEDLIST_PARAM_FEATURE_LAST - o->last = SLinkedList_prev(entry); -#endif - } - } else { - o->first = SLinkedList_next(entry); - } -} - -static void SLinkedList_RemoveFirst (SLinkedList *o) -{ - ASSERT(o->first) - - o->first = SLinkedList_next(o->first); -} - -#if SLINKEDLIST_PARAM_FEATURE_LAST -static void SLinkedList_RemoveLast (SLinkedList *o) -{ - ASSERT(o->first) - - if (o->last == o->first) { - o->first = NULL; - } else { - SLinkedList_next(SLinkedList_prev(o->last)) = NULL; - o->last = SLinkedList_prev(o->last); - } -} -#endif - -static SLinkedListEntry * SLinkedList_First (const SLinkedList *o) -{ - return o->first; -} - -#if SLINKEDLIST_PARAM_FEATURE_LAST -static SLinkedListEntry * SLinkedList_Last (const SLinkedList *o) -{ - return (!o->first ? NULL : o->last); -} -#endif - -static int SLinkedList_IsEmpty (const SLinkedList *o) -{ - return !o->first; -} - -#include "SLinkedList_footer.h" diff --git a/external/badvpn_dns/system/BAddr.h b/external/badvpn_dns/system/BAddr.h deleted file mode 100644 index a5f3f10..0000000 --- a/external/badvpn_dns/system/BAddr.h +++ /dev/null @@ -1,808 +0,0 @@ -/** - * @file BAddr.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Network address abstractions. - */ - -#ifndef BADVPN_SYSTEM_BADDR_H -#define BADVPN_SYSTEM_BADDR_H - -#include <stdint.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#ifdef BADVPN_USE_WINAPI -#include <ws2tcpip.h> -#else -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif - -#include <misc/byteorder.h> -#include <misc/debug.h> -#include <misc/print_macros.h> -#include <misc/read_write_int.h> -#include <misc/compare.h> - -#define BADDR_TYPE_NONE 0 -#define BADDR_TYPE_IPV4 1 -#define BADDR_TYPE_IPV6 2 -#ifdef BADVPN_LINUX - #define BADDR_TYPE_PACKET 5 -#endif - -#define BADDR_MAX_ADDR_LEN 128 - -#define BIPADDR_MAX_PRINT_LEN 40 -#define BADDR_MAX_PRINT_LEN 120 - -#define BADDR_PACKET_HEADER_TYPE_ETHERNET 1 - -#define BADDR_PACKET_PACKET_TYPE_HOST 1 -#define BADDR_PACKET_PACKET_TYPE_BROADCAST 2 -#define BADDR_PACKET_PACKET_TYPE_MULTICAST 3 -#define BADDR_PACKET_PACKET_TYPE_OTHERHOST 4 -#define BADDR_PACKET_PACKET_TYPE_OUTGOING 5 - -typedef struct { - int type; - union { - uint32_t ipv4; - uint8_t ipv6[16]; - }; -} BIPAddr; - -static void BIPAddr_InitInvalid (BIPAddr *addr); - -static void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip); - -static void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip); - -static void BIPAddr_Assert (BIPAddr *addr); - -static int BIPAddr_IsInvalid (BIPAddr *addr); - -static int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve) WARN_UNUSED; - -static int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2); - -/** - * Converts an IP address to human readable form. - * - * @param addr IP address to convert - * @param out destination buffer. Must be at least BIPADDR_MAX_PRINT_LEN characters long. - */ -static void BIPAddr_Print (BIPAddr *addr, char *out); - -/** - * Socket address - IP address and transport protocol port number - */ -typedef struct { - int type; - union { - struct { - uint32_t ip; - uint16_t port; - } ipv4; - struct { - uint8_t ip[16]; - uint16_t port; - } ipv6; - struct { - uint16_t phys_proto; - int interface_index; - int header_type; - int packet_type; - uint8_t phys_addr[8]; - } packet; - }; -} BAddr; - -/** - * Makes an invalid address. - */ -static BAddr BAddr_MakeNone (void); - -/** - * Makes an IPv4 address. - * - * @param ip IP address in network byte order - * @param port port number in network byte order - */ -static BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port); - -/** - * Makes an IPv6 address. - * - * @param ip IP address (16 bytes) - * @param port port number in network byte order - */ -static BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port); - -/** - * Makes an address from a BIPAddr and port number. - * - * @param ipaddr the BIPAddr - * @param port port number in network byte order - */ -static BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port); - -/** - * Deprecated, use BAddr_MakeNone. - */ -static void BAddr_InitNone (BAddr *addr); - -/** - * Deprecated, use BAddr_MakeIPv4. - */ -static void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port); - -/** - * Deprecated, use BAddr_MakeIPv6. - */ -static void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port); - -/** - * Deprecated, use BAddr_MakeFromIpaddrAndPort. - */ -static void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port); - -/** - * Initializes a packet socket (data link layer) address. - * Only Ethernet addresses are supported. - * - * @param addr the object - * @param phys_proto identifier for the upper protocol, network byte order (EtherType) - * @param interface_index network interface index - * @param header_type data link layer header type. Must be BADDR_PACKET_HEADER_TYPE_ETHERNET. - * @param packet_type the manner in which packets are sent/received. Must be one of - * BADDR_PACKET_PACKET_TYPE_HOST, BADDR_PACKET_PACKET_TYPE_BROADCAST, - * BADDR_PACKET_PACKET_TYPE_MULTICAST, BADDR_PACKET_PACKET_TYPE_OTHERHOST, - * BADDR_PACKET_PACKET_TYPE_OUTGOING. - * @param phys_addr data link layer address (MAC address) - */ -static void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr); - -/** - * Does nothing. - * - * @param addr the object - */ -static void BAddr_Assert (BAddr *addr); - -/** - * Determines whether the address is an invalid address. - * - * @param addr the object - * @return 1 if invalid, 0 if invalid - **/ -static int BAddr_IsInvalid (BAddr *addr); - -/** - * Returns the port number in the address. - * - * @param addr the object - * Must be an IPv4 or IPv6 address. - * @return port number, in network byte order - */ -static uint16_t BAddr_GetPort (BAddr *addr); - -/** - * Returns the IP address in the address. - * - * @param addr the object - * @param ipaddr IP address will be returned here. If \a addr is not - * an IPv4 or IPv6 address, an invalid address will be - * returned. - */ -static void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr); - -/** - * Sets the port number in the address. - * - * @param addr the object - * Must be an IPv4 or IPv6 address. - * @param port port number, in network byte order - */ -static void BAddr_SetPort (BAddr *addr, uint16_t port); - -/** - * Converts an IP address to human readable form. - * - * @param addr address to convert - * @param out destination buffer. Must be at least BADDR_MAX_PRINT_LEN characters long. - */ -static void BAddr_Print (BAddr *addr, char *out); - -/** - * Resolves an address string. - * Format is "addr:port" for IPv4, "[addr]:port" for IPv6. - * addr is be a numeric address or a name. - * port is a numeric port number. - * - * @param addr output address - * @param name if not NULL, the name portion of the address will be - * stored here - * @param name_len if name is not NULL, the size of the name buffer - * @param noresolve only accept numeric addresses. Avoids blocking the caller. - * @return 1 on success, 0 on parse error - */ -static int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve) WARN_UNUSED; - -/** - * Resolves an address string. - * IPv4 input format is "a.b.c.d:p", where a.b.c.d is the IP address - * and d is the port number. - * IPv6 input format is "[addr]:p", where addr is an IPv6 addres in - * standard notation and p is the port number. - * - * @param addr output address - * @param name if not NULL, the name portion of the address will be - * stored here - * @param name_len if name is not NULL, the size of the name buffer - * @return 1 on success, 0 on parse error - */ -static int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len) WARN_UNUSED; - -static int BAddr_Compare (BAddr *addr1, BAddr *addr2); - -static int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2); - -void BIPAddr_InitInvalid (BIPAddr *addr) -{ - addr->type = BADDR_TYPE_NONE; -} - -void BIPAddr_InitIPv4 (BIPAddr *addr, uint32_t ip) -{ - addr->type = BADDR_TYPE_IPV4; - addr->ipv4 = ip; -} - -void BIPAddr_InitIPv6 (BIPAddr *addr, uint8_t *ip) -{ - addr->type = BADDR_TYPE_IPV6; - memcpy(addr->ipv6, ip, 16); -} - -void BIPAddr_Assert (BIPAddr *addr) -{ - switch (addr->type) { - case BADDR_TYPE_NONE: - case BADDR_TYPE_IPV4: - case BADDR_TYPE_IPV6: - return; - default: - ASSERT(0); - } -} - -int BIPAddr_IsInvalid (BIPAddr *addr) -{ - BIPAddr_Assert(addr); - - return (addr->type == BADDR_TYPE_NONE); -} - -int BIPAddr_Resolve (BIPAddr *addr, char *str, int noresolve) -{ - int len = strlen(str); - - char *addr_start; - int addr_len; - - // determine address type - if (len >= 1 && str[0] == '[' && str[len - 1] == ']') { - addr->type = BADDR_TYPE_IPV6; - addr_start = str + 1; - addr_len = len - 2; - } else { - addr->type = BADDR_TYPE_IPV4; - addr_start = str; - addr_len = len; - } - - // copy - char addr_str[BADDR_MAX_ADDR_LEN + 1]; - if (addr_len > BADDR_MAX_ADDR_LEN) { - return 0; - } - memcpy(addr_str, addr_start, addr_len); - addr_str[addr_len] = '\0'; - - // initialize hints - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - switch (addr->type) { - case BADDR_TYPE_IPV6: - hints.ai_family = AF_INET6; - break; - case BADDR_TYPE_IPV4: - hints.ai_family = AF_INET; - break; - } - if (noresolve) { - hints.ai_flags |= AI_NUMERICHOST; - } - - // call getaddrinfo - struct addrinfo *addrs; - int res; - if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) { - return 0; - } - - // set address - switch (addr->type) { - case BADDR_TYPE_IPV6: - memcpy(addr->ipv6, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6)); - break; - case BADDR_TYPE_IPV4: - addr->ipv4 = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr; - break; - } - - freeaddrinfo(addrs); - - return 1; -} - -int BIPAddr_Compare (BIPAddr *addr1, BIPAddr *addr2) -{ - BIPAddr_Assert(addr1); - BIPAddr_Assert(addr2); - - if (addr1->type != addr2->type) { - return 0; - } - - switch (addr1->type) { - case BADDR_TYPE_NONE: - return 0; - case BADDR_TYPE_IPV4: - return (addr1->ipv4 == addr2->ipv4); - case BADDR_TYPE_IPV6: - return (!memcmp(addr1->ipv6, addr2->ipv6, sizeof(addr1->ipv6))); - default: - ASSERT(0) - return 0; - } -} - -uint16_t BAddr_GetPort (BAddr *addr) -{ - BAddr_Assert(addr); - ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6) - - switch (addr->type) { - case BADDR_TYPE_IPV4: - return addr->ipv4.port; - case BADDR_TYPE_IPV6: - return addr->ipv6.port; - default: - ASSERT(0) - return 0; - } -} - -void BAddr_GetIPAddr (BAddr *addr, BIPAddr *ipaddr) -{ - BAddr_Assert(addr); - - switch (addr->type) { - case BADDR_TYPE_IPV4: - BIPAddr_InitIPv4(ipaddr, addr->ipv4.ip); - return; - case BADDR_TYPE_IPV6: - BIPAddr_InitIPv6(ipaddr, addr->ipv6.ip); - return; - default: - BIPAddr_InitInvalid(ipaddr); - } -} - -void BAddr_SetPort (BAddr *addr, uint16_t port) -{ - BAddr_Assert(addr); - ASSERT(addr->type == BADDR_TYPE_IPV4 || addr->type == BADDR_TYPE_IPV6) - - switch (addr->type) { - case BADDR_TYPE_IPV4: - addr->ipv4.port = port; - break; - case BADDR_TYPE_IPV6: - addr->ipv6.port = port; - break; - default: - ASSERT(0); - } -} - -void BIPAddr_Print (BIPAddr *addr, char *out) -{ - switch (addr->type) { - case BADDR_TYPE_NONE: - sprintf(out, "(none)"); - break; - case BADDR_TYPE_IPV4: - sprintf(out, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, - *((uint8_t *)&addr->ipv4 + 0), - *((uint8_t *)&addr->ipv4 + 1), - *((uint8_t *)&addr->ipv4 + 2), - *((uint8_t *)&addr->ipv4 + 3) - ); - break; - case BADDR_TYPE_IPV6: { - const char *ptr = (const char *)addr->ipv6; - sprintf(out, - "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16":" - "%"PRIx16":%"PRIx16":%"PRIx16":%"PRIx16, - badvpn_read_be16(ptr + 0), - badvpn_read_be16(ptr + 2), - badvpn_read_be16(ptr + 4), - badvpn_read_be16(ptr + 6), - badvpn_read_be16(ptr + 8), - badvpn_read_be16(ptr + 10), - badvpn_read_be16(ptr + 12), - badvpn_read_be16(ptr + 14) - ); - } break; - default: - ASSERT(0); - } -} - -BAddr BAddr_MakeNone (void) -{ - BAddr addr; - addr.type = BADDR_TYPE_NONE; - return addr; -} - -BAddr BAddr_MakeIPv4 (uint32_t ip, uint16_t port) -{ - BAddr addr; - addr.type = BADDR_TYPE_IPV4; - addr.ipv4.ip = ip; - addr.ipv4.port = port; - return addr; -} - -BAddr BAddr_MakeIPv6 (const uint8_t *ip, uint16_t port) -{ - BAddr addr; - addr.type = BADDR_TYPE_IPV6; - memcpy(addr.ipv6.ip, ip, 16); - addr.ipv6.port = port; - return addr; -} - -BAddr BAddr_MakeFromIpaddrAndPort (BIPAddr ipaddr, uint16_t port) -{ - BIPAddr_Assert(&ipaddr); - - switch (ipaddr.type) { - case BADDR_TYPE_NONE: - return BAddr_MakeNone(); - case BADDR_TYPE_IPV4: - return BAddr_MakeIPv4(ipaddr.ipv4, port); - case BADDR_TYPE_IPV6: - return BAddr_MakeIPv6(ipaddr.ipv6, port); - default: - ASSERT(0); - return BAddr_MakeNone(); - } -} - -void BAddr_InitNone (BAddr *addr) -{ - *addr = BAddr_MakeNone(); -} - -void BAddr_InitIPv4 (BAddr *addr, uint32_t ip, uint16_t port) -{ - *addr = BAddr_MakeIPv4(ip, port); -} - -void BAddr_InitIPv6 (BAddr *addr, uint8_t *ip, uint16_t port) -{ - *addr = BAddr_MakeIPv6(ip, port); -} - -void BAddr_InitFromIpaddrAndPort (BAddr *addr, BIPAddr ipaddr, uint16_t port) -{ - BIPAddr_Assert(&ipaddr); - - *addr = BAddr_MakeFromIpaddrAndPort(ipaddr, port); -} - -#ifdef BADVPN_LINUX - -void BAddr_InitPacket (BAddr *addr, uint16_t phys_proto, int interface_index, int header_type, int packet_type, uint8_t *phys_addr) -{ - ASSERT(header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET) - ASSERT(packet_type == BADDR_PACKET_PACKET_TYPE_HOST || packet_type == BADDR_PACKET_PACKET_TYPE_BROADCAST || - packet_type == BADDR_PACKET_PACKET_TYPE_MULTICAST || packet_type == BADDR_PACKET_PACKET_TYPE_OTHERHOST || - packet_type == BADDR_PACKET_PACKET_TYPE_OUTGOING) - - addr->type = BADDR_TYPE_PACKET; - addr->packet.phys_proto = phys_proto; - addr->packet.interface_index = interface_index; - addr->packet.header_type = header_type; - addr->packet.packet_type = packet_type; - memcpy(addr->packet.phys_addr, phys_addr, 6); -} - -#endif - -void BAddr_Assert (BAddr *addr) -{ - switch (addr->type) { - case BADDR_TYPE_NONE: - case BADDR_TYPE_IPV4: - case BADDR_TYPE_IPV6: - #ifdef BADVPN_LINUX - case BADDR_TYPE_PACKET: - #endif - return; - default: - ASSERT(0); - } -} - -int BAddr_IsInvalid (BAddr *addr) -{ - BAddr_Assert(addr); - - return (addr->type == BADDR_TYPE_NONE); -} - -void BAddr_Print (BAddr *addr, char *out) -{ - BAddr_Assert(addr); - - BIPAddr ipaddr; - - switch (addr->type) { - case BADDR_TYPE_NONE: - sprintf(out, "(none)"); - break; - case BADDR_TYPE_IPV4: - BIPAddr_InitIPv4(&ipaddr, addr->ipv4.ip); - BIPAddr_Print(&ipaddr, out); - sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv4.port)); - break; - case BADDR_TYPE_IPV6: - BIPAddr_InitIPv6(&ipaddr, addr->ipv6.ip); - BIPAddr_Print(&ipaddr, out); - sprintf(out + strlen(out), ":%"PRIu16, ntoh16(addr->ipv6.port)); - break; - #ifdef BADVPN_LINUX - case BADDR_TYPE_PACKET: - ASSERT(addr->packet.header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET) - sprintf(out, "proto=%"PRIu16",ifindex=%d,htype=eth,ptype=%d,addr=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8, - addr->packet.phys_proto, (int)addr->packet.interface_index, (int)addr->packet.packet_type, - addr->packet.phys_addr[0], addr->packet.phys_addr[1], addr->packet.phys_addr[2], - addr->packet.phys_addr[3], addr->packet.phys_addr[4], addr->packet.phys_addr[5]); - break; - #endif - default: - ASSERT(0); - } -} - -int BAddr_Parse2 (BAddr *addr, char *str, char *name, int name_len, int noresolve) -{ - int len = strlen(str); - if (len < 1 || len > 1000) { - return 0; - } - - int addr_start; - int addr_len; - int port_start; - int port_len; - - // leading '[' indicates an IPv6 address - if (str[0] == '[') { - addr->type = BADDR_TYPE_IPV6; - // find ']' - int i=1; - while (i < len && str[i] != ']') i++; - if (i >= len) { - return 0; - } - addr_start = 1; - addr_len = i - addr_start; - // follows ':' and port number - if (i + 1 >= len || str[i + 1] != ':') { - return 0; - } - port_start = i + 2; - port_len = len - port_start; - } - // otherwise it's an IPv4 address - else { - addr->type = BADDR_TYPE_IPV4; - // find ':' - int i=0; - while (i < len && str[i] != ':') i++; - if (i >= len) { - return 0; - } - addr_start = 0; - addr_len = i - addr_start; - port_start = i + 1; - port_len = len - port_start; - } - - // copy address and port to zero-terminated buffers - - char addr_str[128]; - if (addr_len >= sizeof(addr_str)) { - return 0; - } - memcpy(addr_str, str + addr_start, addr_len); - addr_str[addr_len] = '\0'; - - char port_str[6]; - if (port_len >= sizeof(port_str)) { - return 0; - } - memcpy(port_str, str + port_start, port_len); - port_str[port_len] = '\0'; - - // parse port - char *err; - long int conv_res = strtol(port_str, &err, 10); - if (port_str[0] == '\0' || *err != '\0') { - return 0; - } - if (conv_res < 0 || conv_res > UINT16_MAX) { - return 0; - } - uint16_t port = conv_res; - port = hton16(port); - - // initialize hints - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - switch (addr->type) { - case BADDR_TYPE_IPV6: - hints.ai_family = AF_INET6; - break; - case BADDR_TYPE_IPV4: - hints.ai_family = AF_INET; - break; - } - if (noresolve) { - hints.ai_flags |= AI_NUMERICHOST; - } - - // call getaddrinfo - struct addrinfo *addrs; - int res; - if ((res = getaddrinfo(addr_str, NULL, &hints, &addrs)) != 0) { - return 0; - } - - // set address - switch (addr->type) { - case BADDR_TYPE_IPV6: - memcpy(addr->ipv6.ip, ((struct sockaddr_in6 *)addrs->ai_addr)->sin6_addr.s6_addr, sizeof(addr->ipv6.ip)); - addr->ipv6.port = port; - break; - case BADDR_TYPE_IPV4: - addr->ipv4.ip = ((struct sockaddr_in *)addrs->ai_addr)->sin_addr.s_addr; - addr->ipv4.port = port; - break; - } - - freeaddrinfo(addrs); - - if (name) { - if (strlen(addr_str) >= name_len) { - return 0; - } - strcpy(name, addr_str); - } - - return 1; -} - -int BAddr_Parse (BAddr *addr, char *str, char *name, int name_len) -{ - return BAddr_Parse2(addr, str, name, name_len, 0); -} - -int BAddr_Compare (BAddr *addr1, BAddr *addr2) -{ - BAddr_Assert(addr1); - BAddr_Assert(addr2); - - if (addr1->type != addr2->type) { - return 0; - } - - switch (addr1->type) { - case BADDR_TYPE_IPV4: - return (addr1->ipv4.ip == addr2->ipv4.ip && addr1->ipv4.port == addr2->ipv4.port); - case BADDR_TYPE_IPV6: - return (!memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip)) && addr1->ipv6.port == addr2->ipv6.port); - default: - return 0; - } -} - -int BAddr_CompareOrder (BAddr *addr1, BAddr *addr2) -{ - BAddr_Assert(addr1); - BAddr_Assert(addr2); - - int cmp = B_COMPARE(addr1->type, addr2->type); - if (cmp) { - return cmp; - } - - switch (addr1->type) { - case BADDR_TYPE_NONE: { - return 0; - } break; - case BADDR_TYPE_IPV4: { - uint32_t ip1 = ntoh32(addr1->ipv4.ip); - uint32_t ip2 = ntoh32(addr2->ipv4.ip); - cmp = B_COMPARE(ip1, ip2); - if (cmp) { - return cmp; - } - uint16_t port1 = ntoh16(addr1->ipv4.port); - uint16_t port2 = ntoh16(addr2->ipv4.port); - return B_COMPARE(port1, port2); - } break; - case BADDR_TYPE_IPV6: { - cmp = memcmp(addr1->ipv6.ip, addr2->ipv6.ip, sizeof(addr1->ipv6.ip)); - if (cmp) { - return B_COMPARE(cmp, 0); - } - uint16_t port1 = ntoh16(addr1->ipv6.port); - uint16_t port2 = ntoh16(addr2->ipv6.port); - return B_COMPARE(port1, port2); - } break; - default: { - return 0; - } break; - } -} - -#endif diff --git a/external/badvpn_dns/system/BConnection.h b/external/badvpn_dns/system/BConnection.h deleted file mode 100644 index eac25ec..0000000 --- a/external/badvpn_dns/system/BConnection.h +++ /dev/null @@ -1,369 +0,0 @@ -/** - * @file BConnection.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SYSTEM_BCONNECTION -#define BADVPN_SYSTEM_BCONNECTION - -#include <misc/debug.h> -#include <flow/StreamPassInterface.h> -#include <flow/StreamRecvInterface.h> -#include <system/BAddr.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> - - - -/** - * Checks if the given address is supported by {@link BConnection} and related objects. - * - * @param addr address to check. Must be a proper {@link BAddr} object according to - * {@link BIPAddr_Assert}. - * @return 1 if supported, 0 if not - */ -int BConnection_AddressSupported (BAddr addr); - - - -struct BListener_s; - -/** - * Object which listens for connections on an address. - * When a connection is ready, the {@link BListener_handler} handler is called, from which - * the connection can be accepted into a new {@link BConnection} object. - */ -typedef struct BListener_s BListener; - -/** - * Handler called when a new connection is ready. - * The connection can be accepted by calling {@link BConnection_Init} with the a - * BCONNECTION_SOURCE_LISTENER 'source' argument. - * If no attempt is made to accept the connection from the job closure of this handler, - * the connection will be discarded. - * - * @param user as in {@link BListener_Init} - */ -typedef void (*BListener_handler) (void *user); - -/** - * Initializes the object. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param addr address to listen on - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when a connection can be accepted - * @return 1 on success, 0 on failure - */ -int BListener_Init (BListener *o, BAddr addr, BReactor *reactor, void *user, - BListener_handler handler) WARN_UNUSED; - -#ifndef BADVPN_USE_WINAPI -/** - * Initializes the object for listening on a Unix socket. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param socket_path socket path for listening - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when a connection can be accepted - * @return 1 on success, 0 on failure - */ -int BListener_InitUnix (BListener *o, const char *socket_path, BReactor *reactor, void *user, - BListener_handler handler) WARN_UNUSED; -#endif - -/** - * Frees the object. - * - * @param o the object - */ -void BListener_Free (BListener *o); - - - -struct BConnector_s; - -/** - * Object which connects to an address. - * When the connection attempt finishes, the {@link BConnector_handler} handler is called, from which, - * if successful, the resulting connection can be moved to a new {@link BConnection} object. - */ -typedef struct BConnector_s BConnector; - -/** - * Handler called when the connection attempt finishes. - * If the connection attempt succeeded (is_error==0), the new connection can be used by calling - * {@link BConnection_Init} with a BCONNECTION_SOURCE_TYPE_CONNECTOR 'source' argument. - * This handler will be called at most once. The connector object need not be freed after it - * is called. - * - * @param user as in {@link BConnector_Init} - * @param is_error whether the connection attempt succeeded (0) or failed (1) - */ -typedef void (*BConnector_handler) (void *user, int is_error); - -/** - * Initializes the object. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param addr address to connect to - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when the connection attempt finishes - * @return 1 on success, 0 on failure - */ -int BConnector_Init (BConnector *o, BAddr addr, BReactor *reactor, void *user, - BConnector_handler handler) WARN_UNUSED; - -#ifndef BADVPN_USE_WINAPI -/** - * Initializes the object for connecting to a Unix socket. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param socket_path socket path for connecting - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when the connection attempt finishes - * @return 1 on success, 0 on failure - */ -int BConnector_InitUnix (BConnector *o, const char *socket_path, BReactor *reactor, void *user, - BConnector_handler handler) WARN_UNUSED; -#endif - -/** - * Frees the object. - * - * @param o the object - */ -void BConnector_Free (BConnector *o); - - - -#define BCONNECTION_SOURCE_TYPE_LISTENER 1 -#define BCONNECTION_SOURCE_TYPE_CONNECTOR 2 -#define BCONNECTION_SOURCE_TYPE_PIPE 3 - -struct BConnection_source { - int type; - union { - struct { - BListener *listener; - BAddr *out_addr; - } listener; - struct { - BConnector *connector; - } connector; -#ifndef BADVPN_USE_WINAPI - struct { - int pipefd; - } pipe; -#endif - } u; -}; - -static struct BConnection_source BConnection_source_listener (BListener *listener, BAddr *out_addr) -{ - struct BConnection_source s; - s.type = BCONNECTION_SOURCE_TYPE_LISTENER; - s.u.listener.listener = listener; - s.u.listener.out_addr = out_addr; - return s; -} - -static struct BConnection_source BConnection_source_connector (BConnector *connector) -{ - struct BConnection_source s; - s.type = BCONNECTION_SOURCE_TYPE_CONNECTOR; - s.u.connector.connector = connector; - return s; -} - -#ifndef BADVPN_USE_WINAPI -static struct BConnection_source BConnection_source_pipe (int pipefd) -{ - struct BConnection_source s; - s.type = BCONNECTION_SOURCE_TYPE_PIPE; - s.u.pipe.pipefd = pipefd; - return s; -} -#endif - -struct BConnection_s; - -/** - * Object which represents a stream connection. This is usually a TCP connection, either client - * or server, but may also be used with any file descriptor (e.g. pipe) on Unix-like systems. - * Sending and receiving is performed via {@link StreamPassInterface} and {@link StreamRecvInterface}, - * respectively. - */ -typedef struct BConnection_s BConnection; - -#define BCONNECTION_EVENT_ERROR 1 -#define BCONNECTION_EVENT_RECVCLOSED 2 - -/** - * Handler called when an error occurs or the receive end of the connection was closed - * by the remote peer. - * - If event is BCONNECTION_EVENT_ERROR, the connection is no longer usable and must be freed - * from withing the job closure of this handler. No further I/O or interface initialization - * must occur. - * - If event is BCONNECTION_EVENT_RECVCLOSED, no further receive I/O or receive interface - * initialization must occur. It is guarantted that the receive interface was initialized. - * - * @param user as in {@link BConnection_Init} or {@link BConnection_SetHandlers} - * @param event what happened - BCONNECTION_EVENT_ERROR or BCONNECTION_EVENT_RECVCLOSED - */ -typedef void (*BConnection_handler) (void *user, int event); - -/** - * Initializes the object. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param source specifies what the connection comes from. This argument must be created with one of the - * following macros: - * - BCONNECTION_SOURCE_LISTENER(BListener *, BAddr *) - * Accepts a connection ready on a {@link BListener} object. Must be called from the job - * closure of the listener's {@link BListener_handler}, and must be the first attempt - * for this handler invocation. The address of the client is written if the address - * argument is not NULL (theoretically an invalid address may be returned). - * - BCONNECTION_SOURCE_CONNECTOR(Bconnector *) - * Uses a connection establised with {@link BConnector}. Must be called from the job - * closure of the connector's {@link BConnector_handler}, the handler must be reporting - * successful connection, and must be the first attempt for this handler invocation. - * - BCONNECTION_SOURCE_PIPE(int) - * On Unix-like systems, uses the provided file descriptor. The file descriptor number must - * be >=0. - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when an error occurs or the receive end of the connection was closed - * by the remote peer. - * @return 1 on success, 0 on failure - */ -int BConnection_Init (BConnection *o, struct BConnection_source source, BReactor *reactor, void *user, - BConnection_handler handler) WARN_UNUSED; - -/** - * Frees the object. - * The send and receive interfaces must not be initialized. - * If the connection was created with a BCONNECTION_SOURCE_PIPE 'source' argument, the file descriptor - * will not be closed. - * - * @param o the object - */ -void BConnection_Free (BConnection *o); - -/** - * Updates the handler function. - * - * @param o the object - * @param user argument to handler - * @param handler new handler function, as in {@link BConnection_Init}. Additionally, may be NULL to - * remove the current handler. In this case, a proper handler must be set before anything - * can happen with the connection. This is used when moving the connection ownership from - * one module to another. - */ -void BConnection_SetHandlers (BConnection *o, void *user, BConnection_handler handler); - -/** - * Sets the SO_SNDBUF socket option. - * - * @param o the object - * @param buf_size value for SO_SNDBUF option - * @return 1 on success, 0 on failure - */ -int BConnection_SetSendBuffer (BConnection *o, int buf_size); - -/** - * Initializes the send interface for the connection. - * The send interface must not be initialized. - * - * @param o the object - */ -void BConnection_SendAsync_Init (BConnection *o); - -/** - * Frees the send interface for the connection. - * The send interface must be initialized. - * If the send interface was busy when this is called, the connection is no longer usable and must be - * freed before any further I/O or interface initialization. - * - * @param o the object - */ -void BConnection_SendAsync_Free (BConnection *o); - -/** - * Returns the send interface. - * The send interface must be initialized. - * - * @param o the object - * @return send interface - */ -StreamPassInterface * BConnection_SendAsync_GetIf (BConnection *o); - -/** - * Initializes the receive interface for the connection. - * The receive interface must not be initialized. - * - * @param o the object - */ -void BConnection_RecvAsync_Init (BConnection *o); - -/** - * Frees the receive interface for the connection. - * The receive interface must be initialized. - * If the receive interface was busy when this is called, the connection is no longer usable and must be - * freed before any further I/O or interface initialization. - * - * @param o the object - */ -void BConnection_RecvAsync_Free (BConnection *o); - -/** - * Returns the receive interface. - * The receive interface must be initialized. - * - * @param o the object - * @return receive interface - */ -StreamRecvInterface * BConnection_RecvAsync_GetIf (BConnection *o); - - - -#ifdef BADVPN_USE_WINAPI -#include "BConnection_win.h" -#else -#include "BConnection_unix.h" -#endif - -#endif diff --git a/external/badvpn_dns/system/BConnectionGeneric.h b/external/badvpn_dns/system/BConnectionGeneric.h deleted file mode 100644 index 9417555..0000000 --- a/external/badvpn_dns/system/BConnectionGeneric.h +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file BConnectionGeneric.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BCONNECTION_GENERIC_H -#define BADVPN_BCONNECTION_GENERIC_H - -#include <string.h> - -#include <misc/debug.h> -#include <misc/strdup.h> -#include <base/BLog.h> -#include <system/BConnection.h> - -#define BCONNECTION_ADDR_TYPE_BADDR 1 -#define BCONNECTION_ADDR_TYPE_UNIX 2 - -struct BConnection_addr { - int type; - union { - BAddr baddr; - struct { - const char *str; - size_t len; - } unix_socket_path; - } u; -}; - -static struct BConnection_addr BConnection_addr_baddr (BAddr baddr) -{ - struct BConnection_addr addr; - addr.type = BCONNECTION_ADDR_TYPE_BADDR; - addr.u.baddr = baddr; - return addr; -} - -static struct BConnection_addr BConnection_addr_unix (const char *unix_socket_path, size_t len) -{ - struct BConnection_addr addr; - addr.type = BCONNECTION_ADDR_TYPE_UNIX; - addr.u.unix_socket_path.str = unix_socket_path; - addr.u.unix_socket_path.len = len; - return addr; -} - -static int BListener_InitGeneric (BListener *o, struct BConnection_addr addr, BReactor *reactor, void *user, - BListener_handler handler) WARN_UNUSED; -static int BConnector_InitGeneric (BConnector *o, struct BConnection_addr addr, BReactor *reactor, void *user, - BConnector_handler handler) WARN_UNUSED; - -static int BListener_InitGeneric (BListener *o, struct BConnection_addr addr, BReactor *reactor, void *user, - BListener_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - ASSERT(addr.type != BCONNECTION_ADDR_TYPE_UNIX || !memchr(addr.u.unix_socket_path.str, '\0', addr.u.unix_socket_path.len)) - - switch (addr.type) { - case BCONNECTION_ADDR_TYPE_BADDR: { - return BListener_Init(o, addr.u.baddr, reactor, user, handler); - } break; - - case BCONNECTION_ADDR_TYPE_UNIX: { -#ifdef BADVPN_USE_WINAPI - BLog_LogToChannel(BLOG_CHANNEL_BConnection, BLOG_ERROR, "unix sockets not supported"); - return 0; -#else - char *str = b_strdup_bin(addr.u.unix_socket_path.str, addr.u.unix_socket_path.len); - if (!str) { - BLog_LogToChannel(BLOG_CHANNEL_BConnection, BLOG_ERROR, "b_strdup_bin failed"); - return 0; - } - int res = BListener_InitUnix(o, str, reactor, user, handler); - free(str); - return res; -#endif - } break; - - default: - ASSERT(0); - return 0; - } -} - -static int BConnector_InitGeneric (BConnector *o, struct BConnection_addr addr, BReactor *reactor, void *user, - BConnector_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - ASSERT(addr.type != BCONNECTION_ADDR_TYPE_UNIX || !memchr(addr.u.unix_socket_path.str, '\0', addr.u.unix_socket_path.len)) - - switch (addr.type) { - case BCONNECTION_ADDR_TYPE_BADDR: { - return BConnector_Init(o, addr.u.baddr, reactor, user, handler); - } break; - - case BCONNECTION_ADDR_TYPE_UNIX: { -#ifdef BADVPN_USE_WINAPI - BLog_LogToChannel(BLOG_CHANNEL_BConnection, BLOG_ERROR, "unix sockets not supported"); - return 0; -#else - char *str = b_strdup_bin(addr.u.unix_socket_path.str, addr.u.unix_socket_path.len); - if (!str) { - BLog_LogToChannel(BLOG_CHANNEL_BConnection, BLOG_ERROR, "b_strdup_bin failed"); - return 0; - } - int res = BConnector_InitUnix(o, str, reactor, user, handler); - free(str); - return res; -#endif - } break; - - default: - ASSERT(0); - return 0; - } -} - -#endif diff --git a/external/badvpn_dns/system/BConnection_unix.c b/external/badvpn_dns/system/BConnection_unix.c deleted file mode 100644 index f6fa356..0000000 --- a/external/badvpn_dns/system/BConnection_unix.c +++ /dev/null @@ -1,1057 +0,0 @@ -/** - * @file BConnection_unix.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <misc/nonblocking.h> -#include <misc/strdup.h> -#include <base/BLog.h> - -#include "BConnection.h" - -#include <generated/blog_channel_BConnection.h> - -#define MAX_UNIX_SOCKET_PATH 200 - -#define SEND_STATE_NOT_INITED 0 -#define SEND_STATE_READY 1 -#define SEND_STATE_BUSY 2 - -#define RECV_STATE_NOT_INITED 0 -#define RECV_STATE_READY 1 -#define RECV_STATE_BUSY 2 -#define RECV_STATE_INITED_CLOSED 3 -#define RECV_STATE_NOT_INITED_CLOSED 4 - -struct sys_addr { - socklen_t len; - union { - struct sockaddr generic; - struct sockaddr_in ipv4; - struct sockaddr_in6 ipv6; - } addr; -}; - -struct unix_addr { - socklen_t len; - union { - struct sockaddr_un addr; - uint8_t bytes[offsetof(struct sockaddr_un, sun_path) + MAX_UNIX_SOCKET_PATH + 1]; - } u; -}; - -static int build_unix_address (struct unix_addr *out, const char *socket_path); -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr); -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr); -static void listener_fd_handler (BListener *o, int events); -static void listener_default_job_handler (BListener *o); -static void connector_fd_handler (BConnector *o, int events); -static void connector_job_handler (BConnector *o); -static void connection_report_error (BConnection *o); -static void connection_send (BConnection *o); -static void connection_recv (BConnection *o); -static void connection_fd_handler (BConnection *o, int events); -static void connection_send_job_handler (BConnection *o); -static void connection_recv_job_handler (BConnection *o); -static void connection_send_if_handler_send (BConnection *o, uint8_t *data, int data_len); -static void connection_recv_if_handler_recv (BConnection *o, uint8_t *data, int data_len); - -static int build_unix_address (struct unix_addr *out, const char *socket_path) -{ - ASSERT(socket_path); - - if (strlen(socket_path) > MAX_UNIX_SOCKET_PATH) { - return 0; - } - - out->len = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path) + 1; - out->u.addr.sun_family = AF_UNIX; - strcpy(out->u.addr.sun_path, socket_path); - - return 1; -} - -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr) -{ - switch (addr.type) { - case BADDR_TYPE_IPV4: { - out->len = sizeof(out->addr.ipv4); - memset(&out->addr.ipv4, 0, sizeof(out->addr.ipv4)); - out->addr.ipv4.sin_family = AF_INET; - out->addr.ipv4.sin_port = addr.ipv4.port; - out->addr.ipv4.sin_addr.s_addr = addr.ipv4.ip; - } break; - - case BADDR_TYPE_IPV6: { - out->len = sizeof(out->addr.ipv6); - memset(&out->addr.ipv6, 0, sizeof(out->addr.ipv6)); - out->addr.ipv6.sin6_family = AF_INET6; - out->addr.ipv6.sin6_port = addr.ipv6.port; - out->addr.ipv6.sin6_flowinfo = 0; - memcpy(out->addr.ipv6.sin6_addr.s6_addr, addr.ipv6.ip, 16); - out->addr.ipv6.sin6_scope_id = 0; - } break; - - default: ASSERT(0); - } -} - -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr) -{ - switch (addr.addr.generic.sa_family) { - case AF_INET: { - ASSERT(addr.len == sizeof(struct sockaddr_in)) - BAddr_InitIPv4(out, addr.addr.ipv4.sin_addr.s_addr, addr.addr.ipv4.sin_port); - } break; - - case AF_INET6: { - ASSERT(addr.len == sizeof(struct sockaddr_in6)) - BAddr_InitIPv6(out, addr.addr.ipv6.sin6_addr.s6_addr, addr.addr.ipv6.sin6_port); - } break; - - default: { - BAddr_InitNone(out); - } break; - } -} - -static void listener_fd_handler (BListener *o, int events) -{ - DebugObject_Access(&o->d_obj); - - // set default job - BPending_Set(&o->default_job); - - // call handler - o->handler(o->user); - return; -} - -static void listener_default_job_handler (BListener *o) -{ - DebugObject_Access(&o->d_obj); - - BLog(BLOG_ERROR, "discarding connection"); - - // accept - int newfd = accept(o->fd, NULL, NULL); - if (newfd < 0) { - BLog(BLOG_ERROR, "accept failed"); - return; - } - - // close new fd - if (close(newfd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -} - -static void connector_fd_handler (BConnector *o, int events) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->fd >= 0) - ASSERT(!o->connected) - ASSERT(o->have_bfd) - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - // set have no BFileDescriptor - o->have_bfd = 0; - - // read connection result - int result; - socklen_t result_len = sizeof(result); - if (getsockopt(o->fd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) { - BLog(BLOG_ERROR, "getsockopt failed"); - goto fail0; - } - ASSERT_FORCE(result_len == sizeof(result)) - - if (result != 0) { - BLog(BLOG_ERROR, "connection failed"); - goto fail0; - } - - // set connected - o->connected = 1; - -fail0: - // call handler - o->handler(o->user, !o->connected); - return; -} - -static void connector_job_handler (BConnector *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->fd >= 0) - ASSERT(o->connected) - ASSERT(!o->have_bfd) - - // call handler - o->handler(o->user, 0); - return; -} - -static void connection_report_error (BConnection *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->handler) - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BCONNECTION_EVENT_ERROR)); - return; -} - -static void connection_send (BConnection *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.state == SEND_STATE_BUSY) - - // limit - if (!o->is_hupd) { - if (!BReactorLimit_Increment(&o->send.limit)) { - // wait for fd - o->wait_events |= BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - } - - // send - int bytes = write(o->fd, o->send.busy_data, o->send.busy_data_len); - if (bytes < 0) { - if (!o->is_hupd && (errno == EAGAIN || errno == EWOULDBLOCK)) { - // wait for fd - o->wait_events |= BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - BLog(BLOG_ERROR, "send failed"); - connection_report_error(o); - return; - } - - ASSERT(bytes > 0) - ASSERT(bytes <= o->send.busy_data_len) - - // set ready - o->send.state = SEND_STATE_READY; - - // done - StreamPassInterface_Done(&o->send.iface, bytes); -} - -static void connection_recv (BConnection *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.state == RECV_STATE_BUSY) - - // limit - if (!o->is_hupd) { - if (!BReactorLimit_Increment(&o->recv.limit)) { - // wait for fd - o->wait_events |= BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - } - - // recv - int bytes = read(o->fd, o->recv.busy_data, o->recv.busy_data_avail); - if (bytes < 0) { - if (!o->is_hupd && (errno == EAGAIN || errno == EWOULDBLOCK)) { - // wait for fd - o->wait_events |= BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - BLog(BLOG_ERROR, "recv failed"); - connection_report_error(o); - return; - } - - if (bytes == 0) { - // set recv inited closed - o->recv.state = RECV_STATE_INITED_CLOSED; - - // report recv closed - o->handler(o->user, BCONNECTION_EVENT_RECVCLOSED); - return; - } - - ASSERT(bytes > 0) - ASSERT(bytes <= o->recv.busy_data_avail) - - // set not busy - o->recv.state = RECV_STATE_READY; - - // done - StreamRecvInterface_Done(&o->recv.iface, bytes); -} - -static void connection_fd_handler (BConnection *o, int events) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->is_hupd) - - // clear handled events - o->wait_events &= ~events; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - - int have_send = 0; - int have_recv = 0; - - // if we got a HUP event, stop monitoring the file descriptor - if ((events & BREACTOR_HUP)) { - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - o->is_hupd = 1; - } - - if ((events & BREACTOR_WRITE) || ((events & (BREACTOR_ERROR|BREACTOR_HUP)) && o->send.state == SEND_STATE_BUSY)) { - ASSERT(o->send.state == SEND_STATE_BUSY) - have_send = 1; - } - - if ((events & BREACTOR_READ) || ((events & (BREACTOR_ERROR|BREACTOR_HUP)) && o->recv.state == RECV_STATE_BUSY)) { - ASSERT(o->recv.state == RECV_STATE_BUSY) - have_recv = 1; - } - - if (have_send) { - if (have_recv) { - BPending_Set(&o->recv.job); - } - - connection_send(o); - return; - } - - if (have_recv) { - connection_recv(o); - return; - } - - if (!o->is_hupd) { - BLog(BLOG_ERROR, "fd error event"); - connection_report_error(o); - return; - } -} - -static void connection_send_job_handler (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.state == SEND_STATE_BUSY) - - connection_send(o); - return; -} - -static void connection_recv_job_handler (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.state == RECV_STATE_BUSY) - - connection_recv(o); - return; -} - -static void connection_send_if_handler_send (BConnection *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.state == SEND_STATE_READY) - ASSERT(data_len > 0) - - // remember data - o->send.busy_data = data; - o->send.busy_data_len = data_len; - - // set busy - o->send.state = SEND_STATE_BUSY; - - connection_send(o); - return; -} - -static void connection_recv_if_handler_recv (BConnection *o, uint8_t *data, int data_avail) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.state == RECV_STATE_READY) - ASSERT(data_avail > 0) - - // remember data - o->recv.busy_data = data; - o->recv.busy_data_avail = data_avail; - - // set busy - o->recv.state = RECV_STATE_BUSY; - - connection_recv(o); - return; -} - -int BConnection_AddressSupported (BAddr addr) -{ - BAddr_Assert(&addr); - - return (addr.type == BADDR_TYPE_IPV4 || addr.type == BADDR_TYPE_IPV6); -} - -int BListener_Init (BListener *o, BAddr addr, BReactor *reactor, void *user, - BListener_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // set no unix socket path - o->unix_socket_path = NULL; - - // check address - if (!BConnection_AddressSupported(addr)) { - BLog(BLOG_ERROR, "address not supported"); - goto fail0; - } - - // convert address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // init fd - if ((o->fd = socket(sysaddr.addr.generic.sa_family, SOCK_STREAM, 0)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail0; - } - - // set non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // set SO_REUSEADDR - int optval = 1; - if (setsockopt(o->fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { - BLog(BLOG_ERROR, "setsockopt(SO_REUSEADDR) failed"); - } - - // bind - if (bind(o->fd, &sysaddr.addr.generic, sysaddr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - goto fail1; - } - - // listen - if (listen(o->fd, BCONNECTION_LISTEN_BACKLOG) < 0) { - BLog(BLOG_ERROR, "listen failed"); - goto fail1; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)listener_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - - // init default job - BPending_Init(&o->default_job, BReactor_PendingGroup(o->reactor), (BPending_handler)listener_default_job_handler, o); - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail0: - return 0; -} - -int BListener_InitUnix (BListener *o, const char *socket_path, BReactor *reactor, void *user, - BListener_handler handler) -{ - ASSERT(socket_path) - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // copy socket path - o->unix_socket_path = b_strdup(socket_path); - if (!o->unix_socket_path) { - BLog(BLOG_ERROR, "b_strdup failed"); - goto fail0; - } - - // build address - struct unix_addr addr; - if (!build_unix_address(&addr, socket_path)) { - BLog(BLOG_ERROR, "build_unix_address failed"); - goto fail1; - } - - // init fd - if ((o->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail1; - } - - // set non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail2; - } - - // unlink existing socket - if (unlink(o->unix_socket_path) < 0 && errno != ENOENT) { - BLog(BLOG_ERROR, "unlink existing socket failed"); - goto fail2; - } - - // bind - if (bind(o->fd, (struct sockaddr *)&addr.u.addr, addr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - goto fail2; - } - - // listen - if (listen(o->fd, BCONNECTION_LISTEN_BACKLOG) < 0) { - BLog(BLOG_ERROR, "listen failed"); - goto fail3; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)listener_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail3; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - - // init default job - BPending_Init(&o->default_job, BReactor_PendingGroup(o->reactor), (BPending_handler)listener_default_job_handler, o); - - DebugObject_Init(&o->d_obj); - return 1; - -fail3: - if (unlink(o->unix_socket_path) < 0) { - BLog(BLOG_ERROR, "unlink socket failed"); - } -fail2: - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail1: - free(o->unix_socket_path); -fail0: - return 0; -} - -void BListener_Free (BListener *o) -{ - DebugObject_Free(&o->d_obj); - - // free default job - BPending_Free(&o->default_job); - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - // free fd - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - - // unlink unix socket - if (o->unix_socket_path) { - if (unlink(o->unix_socket_path) < 0) { - BLog(BLOG_ERROR, "unlink socket failed"); - } - } - - // free unix socket path - if (o->unix_socket_path) { - free(o->unix_socket_path); - } -} - -int BConnector_Init (BConnector *o, BAddr addr, BReactor *reactor, void *user, - BConnector_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // check address - if (!BConnection_AddressSupported(addr)) { - BLog(BLOG_ERROR, "address not supported"); - goto fail0; - } - - // convert address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // init job - BPending_Init(&o->job, BReactor_PendingGroup(o->reactor), (BPending_handler)connector_job_handler, o); - - // init fd - if ((o->fd = socket(sysaddr.addr.generic.sa_family, SOCK_STREAM, 0)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail1; - } - - // set fd non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail2; - } - - // connect fd - int res = connect(o->fd, &sysaddr.addr.generic, sysaddr.len); - if (res < 0 && errno != EINPROGRESS) { - BLog(BLOG_ERROR, "connect failed"); - goto fail2; - } - - // set not connected - o->connected = 0; - - // set have no BFileDescriptor - o->have_bfd = 0; - - if (res < 0) { - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)connector_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail2; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_WRITE); - - // set have BFileDescriptor - o->have_bfd = 1; - } else { - // set connected - o->connected = 1; - - // set job - BPending_Set(&o->job); - } - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail1: - BPending_Free(&o->job); -fail0: - return 0; -} - -int BConnector_InitUnix (BConnector *o, const char *socket_path, BReactor *reactor, void *user, - BConnector_handler handler) -{ - ASSERT(socket_path) - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // build address - struct unix_addr addr; - if (!build_unix_address(&addr, socket_path)) { - BLog(BLOG_ERROR, "build_unix_address failed"); - goto fail0; - } - - // init job - BPending_Init(&o->job, BReactor_PendingGroup(o->reactor), (BPending_handler)connector_job_handler, o); - - // init fd - if ((o->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail1; - } - - // set fd non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail2; - } - - // connect fd - int res = connect(o->fd, (struct sockaddr *)&addr.u.addr, addr.len); - if (res < 0 && errno != EINPROGRESS) { - BLog(BLOG_ERROR, "connect failed"); - goto fail2; - } - - // set not connected - o->connected = 0; - - // set have no BFileDescriptor - o->have_bfd = 0; - - if (res < 0) { - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)connector_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail2; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_WRITE); - - // set have BFileDescriptor - o->have_bfd = 1; - } else { - // set connected - o->connected = 1; - - // set job - BPending_Set(&o->job); - } - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail1: - BPending_Free(&o->job); -fail0: - return 0; -} - -void BConnector_Free (BConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free BFileDescriptor - if (o->have_bfd) { - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - } - - // close fd - if (o->fd != -1) { - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - } - - // free job - BPending_Free(&o->job); -} - -int BConnection_Init (BConnection *o, struct BConnection_source source, BReactor *reactor, void *user, - BConnection_handler handler) -{ - switch (source.type) { - case BCONNECTION_SOURCE_TYPE_LISTENER: { - BListener *listener = source.u.listener.listener; - DebugObject_Access(&listener->d_obj); - ASSERT(BPending_IsSet(&listener->default_job)) - } break; - case BCONNECTION_SOURCE_TYPE_CONNECTOR: { - BConnector *connector = source.u.connector.connector; - DebugObject_Access(&connector->d_obj); - ASSERT(connector->fd >= 0) - ASSERT(connector->connected) - ASSERT(!connector->have_bfd) - ASSERT(!BPending_IsSet(&connector->job)) - } break; - case BCONNECTION_SOURCE_TYPE_PIPE: { - ASSERT(source.u.pipe.pipefd >= 0) - } break; - default: ASSERT(0); - } - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - switch (source.type) { - case BCONNECTION_SOURCE_TYPE_LISTENER: { - BListener *listener = source.u.listener.listener; - - // unset listener's default job - BPending_Unset(&listener->default_job); - - // accept - struct sys_addr sysaddr; - sysaddr.len = sizeof(sysaddr.addr); - if ((o->fd = accept(listener->fd, &sysaddr.addr.generic, &sysaddr.len)) < 0) { - BLog(BLOG_ERROR, "accept failed"); - goto fail0; - } - o->close_fd = 1; - - // set non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // return address - if (source.u.listener.out_addr) { - addr_sys_to_socket(source.u.listener.out_addr, sysaddr); - } - } break; - - case BCONNECTION_SOURCE_TYPE_CONNECTOR: { - BConnector *connector = source.u.connector.connector; - - // grab fd from connector - o->fd = connector->fd; - connector->fd = -1; - o->close_fd = 1; - } break; - - case BCONNECTION_SOURCE_TYPE_PIPE: { - // use user-provided fd - o->fd = source.u.pipe.pipefd; - o->close_fd = 0; - - // set non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - } break; - } - - // set not HUPd - o->is_hupd = 0; - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)connection_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - - // set no wait events - o->wait_events = 0; - - // init limits - BReactorLimit_Init(&o->send.limit, o->reactor, BCONNECTION_SEND_LIMIT); - BReactorLimit_Init(&o->recv.limit, o->reactor, BCONNECTION_RECV_LIMIT); - - // set send and recv not inited - o->send.state = SEND_STATE_NOT_INITED; - o->recv.state = RECV_STATE_NOT_INITED; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (o->close_fd) { - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - } -fail0: - return 0; -} - -void BConnection_Free (BConnection *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - ASSERT(o->send.state == SEND_STATE_NOT_INITED) - ASSERT(o->recv.state == RECV_STATE_NOT_INITED || o->recv.state == RECV_STATE_NOT_INITED_CLOSED) - - // free limits - BReactorLimit_Free(&o->recv.limit); - BReactorLimit_Free(&o->send.limit); - - // free BFileDescriptor - if (!o->is_hupd) { - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - } - - // close fd - if (o->close_fd) { - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - } -} - -void BConnection_SetHandlers (BConnection *o, void *user, BConnection_handler handler) -{ - DebugObject_Access(&o->d_obj); - - // set handlers - o->user = user; - o->handler = handler; -} - -int BConnection_SetSendBuffer (BConnection *o, int buf_size) -{ - DebugObject_Access(&o->d_obj); - - if (setsockopt(o->fd, SOL_SOCKET, SO_SNDBUF, (void *)&buf_size, sizeof(buf_size)) < 0) { - BLog(BLOG_ERROR, "setsockopt failed"); - return 0; - } - - return 1; -} - -void BConnection_SendAsync_Init (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.state == SEND_STATE_NOT_INITED) - - // init interface - StreamPassInterface_Init(&o->send.iface, (StreamPassInterface_handler_send)connection_send_if_handler_send, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->send.job, BReactor_PendingGroup(o->reactor), (BPending_handler)connection_send_job_handler, o); - - // set ready - o->send.state = SEND_STATE_READY; -} - -void BConnection_SendAsync_Free (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.state == SEND_STATE_READY || o->send.state == SEND_STATE_BUSY) - - // update events - if (!o->is_hupd) { - o->wait_events &= ~BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - } - - // free job - BPending_Free(&o->send.job); - - // free interface - StreamPassInterface_Free(&o->send.iface); - - // set not inited - o->send.state = SEND_STATE_NOT_INITED; -} - -StreamPassInterface * BConnection_SendAsync_GetIf (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.state == SEND_STATE_READY || o->send.state == SEND_STATE_BUSY) - - return &o->send.iface; -} - -void BConnection_RecvAsync_Init (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.state == RECV_STATE_NOT_INITED) - - // init interface - StreamRecvInterface_Init(&o->recv.iface, (StreamRecvInterface_handler_recv)connection_recv_if_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->recv.job, BReactor_PendingGroup(o->reactor), (BPending_handler)connection_recv_job_handler, o); - - // set ready - o->recv.state = RECV_STATE_READY; -} - -void BConnection_RecvAsync_Free (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.state == RECV_STATE_READY || o->recv.state == RECV_STATE_BUSY || o->recv.state == RECV_STATE_INITED_CLOSED) - - // update events - if (!o->is_hupd) { - o->wait_events &= ~BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - } - - // free job - BPending_Free(&o->recv.job); - - // free interface - StreamRecvInterface_Free(&o->recv.iface); - - // set not inited - o->recv.state = RECV_STATE_NOT_INITED; -} - -StreamRecvInterface * BConnection_RecvAsync_GetIf (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.state == RECV_STATE_READY || o->recv.state == RECV_STATE_BUSY || o->recv.state == RECV_STATE_INITED_CLOSED) - - return &o->recv.iface; -} diff --git a/external/badvpn_dns/system/BConnection_unix.h b/external/badvpn_dns/system/BConnection_unix.h deleted file mode 100644 index e134f6c..0000000 --- a/external/badvpn_dns/system/BConnection_unix.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file BConnection_unix.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debugerror.h> -#include <base/DebugObject.h> - -#define BCONNECTION_SEND_LIMIT 2 -#define BCONNECTION_RECV_LIMIT 2 -#define BCONNECTION_LISTEN_BACKLOG 128 - -struct BListener_s { - BReactor *reactor; - void *user; - BListener_handler handler; - char *unix_socket_path; - int fd; - BFileDescriptor bfd; - BPending default_job; - DebugObject d_obj; -}; - -struct BConnector_s { - BReactor *reactor; - void *user; - BConnector_handler handler; - BPending job; - int fd; - int connected; - int have_bfd; - BFileDescriptor bfd; - DebugObject d_obj; -}; - -struct BConnection_s { - BReactor *reactor; - void *user; - BConnection_handler handler; - int fd; - int close_fd; - int is_hupd; - BFileDescriptor bfd; - int wait_events; - struct { - BReactorLimit limit; - StreamPassInterface iface; - BPending job; - const uint8_t *busy_data; - int busy_data_len; - int state; - } send; - struct { - BReactorLimit limit; - StreamRecvInterface iface; - BPending job; - uint8_t *busy_data; - int busy_data_avail; - int state; - } recv; - DebugError d_err; - DebugObject d_obj; -}; diff --git a/external/badvpn_dns/system/BConnection_win.c b/external/badvpn_dns/system/BConnection_win.c deleted file mode 100644 index 17ae727..0000000 --- a/external/badvpn_dns/system/BConnection_win.c +++ /dev/null @@ -1,875 +0,0 @@ -/** - * @file BConnection_win.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <limits.h> - -#include <base/BLog.h> - -#include "BConnection.h" - -#include <generated/blog_channel_BConnection.h> - -#define LISTEN_BACKLOG 128 - -struct sys_addr { - int len; - union { - struct sockaddr generic; - struct sockaddr_in ipv4; - struct sockaddr_in6 ipv6; - } addr; -}; - -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr); -static void addr_any_to_sys (struct sys_addr *out, int family); -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr); -static void listener_next_job_handler (BListener *o); -static void listener_olap_handler (BListener *o, int event, DWORD bytes); -static void connector_olap_handler (BConnector *o, int event, DWORD bytes); -static void connector_abort (BConnector *o); -static void connection_report_error (BConnection *o); -static void connection_abort (BConnection *o); -static void connection_send_iface_handler_send (BConnection *o, uint8_t *data, int data_len); -static void connection_recv_iface_handler_recv (BConnection *o, uint8_t *data, int data_len); -static void connection_send_olap_handler (BConnection *o, int event, DWORD bytes); -static void connection_recv_olap_handler (BConnection *o, int event, DWORD bytes); - -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr) -{ - switch (addr.type) { - case BADDR_TYPE_IPV4: { - out->len = sizeof(out->addr.ipv4); - memset(&out->addr.ipv4, 0, sizeof(out->addr.ipv4)); - out->addr.ipv4.sin_family = AF_INET; - out->addr.ipv4.sin_port = addr.ipv4.port; - out->addr.ipv4.sin_addr.s_addr = addr.ipv4.ip; - } break; - - case BADDR_TYPE_IPV6: { - out->len = sizeof(out->addr.ipv6); - memset(&out->addr.ipv6, 0, sizeof(out->addr.ipv6)); - out->addr.ipv6.sin6_family = AF_INET6; - out->addr.ipv6.sin6_port = addr.ipv6.port; - out->addr.ipv6.sin6_flowinfo = 0; - memcpy(out->addr.ipv6.sin6_addr.s6_addr, addr.ipv6.ip, 16); - out->addr.ipv6.sin6_scope_id = 0; - } break; - - default: ASSERT(0); - } -} - -static void addr_any_to_sys (struct sys_addr *out, int family) -{ - switch (family) { - case BADDR_TYPE_IPV4: { - out->len = sizeof(out->addr.ipv4); - memset(&out->addr.ipv4, 0, sizeof(out->addr.ipv4)); - out->addr.ipv4.sin_family = AF_INET; - out->addr.ipv4.sin_port = 0; - out->addr.ipv4.sin_addr.s_addr = INADDR_ANY; - } break; - - case BADDR_TYPE_IPV6: { - out->len = sizeof(out->addr.ipv6); - memset(&out->addr.ipv6, 0, sizeof(out->addr.ipv6)); - out->addr.ipv6.sin6_family = AF_INET6; - out->addr.ipv6.sin6_port = 0; - out->addr.ipv6.sin6_flowinfo = 0; - struct in6_addr any = IN6ADDR_ANY_INIT; - out->addr.ipv6.sin6_addr = any; - out->addr.ipv6.sin6_scope_id = 0; - } break; - - default: ASSERT(0); - } -} - -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr) -{ - switch (addr.addr.generic.sa_family) { - case AF_INET: { - ASSERT(addr.len == sizeof(struct sockaddr_in)) - BAddr_InitIPv4(out, addr.addr.ipv4.sin_addr.s_addr, addr.addr.ipv4.sin_port); - } break; - - case AF_INET6: { - ASSERT(addr.len == sizeof(struct sockaddr_in6)) - BAddr_InitIPv6(out, addr.addr.ipv6.sin6_addr.s6_addr, addr.addr.ipv6.sin6_port); - } break; - - default: { - BAddr_InitNone(out); - } break; - } -} - -static void listener_next_job_handler (BListener *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->busy) - - // free ready socket - if (o->ready) { - BLog(BLOG_ERROR, "discarding connection"); - - // close new socket - if (closesocket(o->newsock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - - // set not ready - o->ready = 0; - } - - // create new socket - if ((o->newsock = WSASocket(o->sys_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { - BLog(BLOG_ERROR, "WSASocket failed"); - goto fail0; - } - - // start accept operation - while (1) { - memset(&o->olap.olap, 0, sizeof(o->olap.olap)); - DWORD bytes; - BOOL res = o->fnAcceptEx(o->sock, o->newsock, o->addrbuf, 0, sizeof(struct BListener_addrbuf_stub), sizeof(struct BListener_addrbuf_stub), &bytes, &o->olap.olap); - if (res == FALSE && WSAGetLastError() != ERROR_IO_PENDING) { - BLog(BLOG_ERROR, "AcceptEx failed"); - continue; - } - break; - } - - // set busy - o->busy = 1; - - return; - -fail0: - return; -} - -static void listener_olap_handler (BListener *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->busy) - ASSERT(!o->ready) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->busy = 0; - - // schedule next accept - BPending_Set(&o->next_job); - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "accepting failed"); - - // close new socket - if (closesocket(o->newsock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - - return; - } - - BLog(BLOG_INFO, "connection accepted"); - - // set ready - o->ready = 1; - - // call handler - o->handler(o->user); - return; -} - -static void connector_olap_handler (BConnector *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->sock != INVALID_SOCKET) - ASSERT(o->busy) - ASSERT(!o->ready) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->busy = 0; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "connection failed"); - } else { - // set ready - o->ready = 1; - } - - // call handler - o->handler(o->user, !o->ready); - return; -} - -static void connector_abort (BConnector *o) -{ - if (o->sock != INVALID_SOCKET) { - // cancel I/O - if (o->busy) { - if (!CancelIo((HANDLE)o->sock)) { - BLog(BLOG_ERROR, "CancelIo failed"); - } - } - - // close socket - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - } - - // wait for connect operation to finish - if (o->busy) { - BReactorIOCPOverlapped_Wait(&o->olap, NULL, NULL); - } - - // free olap - BReactorIOCPOverlapped_Free(&o->olap); -} - -static void connection_report_error (BConnection *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->handler) - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BCONNECTION_EVENT_ERROR)); - return; -} - -static void connection_abort (BConnection *o) -{ - ASSERT(!o->aborted) - - // cancel I/O - if ((o->recv.inited && o->recv.busy) || (o->send.inited && o->send.busy)) { - if (!CancelIo((HANDLE)o->sock)) { - BLog(BLOG_ERROR, "CancelIo failed"); - } - } - - // close socket - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - - // wait for receiving to complete - if (o->recv.inited && o->recv.busy) { - BReactorIOCPOverlapped_Wait(&o->recv.olap, NULL, NULL); - } - - // wait for sending to complete - if (o->send.inited && o->send.busy) { - BReactorIOCPOverlapped_Wait(&o->send.olap, NULL, NULL); - } - - // free recv olap - BReactorIOCPOverlapped_Free(&o->recv.olap); - - // free send olap - BReactorIOCPOverlapped_Free(&o->send.olap); - - // set aborted - o->aborted = 1; -} - -static void connection_send_iface_handler_send (BConnection *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(!o->send.busy) - ASSERT(data_len > 0) - - if (data_len > ULONG_MAX) { - data_len = ULONG_MAX; - } - - WSABUF buf; - buf.buf = (char *)data; - buf.len = data_len; - - memset(&o->send.olap.olap, 0, sizeof(o->send.olap.olap)); - - // send - int res = WSASend(o->sock, &buf, 1, NULL, 0, &o->send.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSASend failed (%d)", WSAGetLastError()); - connection_report_error(o); - return; - } - - // set busy - o->send.busy = 1; - o->send.busy_data_len = data_len; -} - -static void connection_recv_iface_handler_recv (BConnection *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->recv.closed) - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(!o->recv.busy) - ASSERT(data_len > 0) - - if (data_len > ULONG_MAX) { - data_len = ULONG_MAX; - } - - WSABUF buf; - buf.buf = (char *)data; - buf.len = data_len; - - memset(&o->recv.olap.olap, 0, sizeof(o->recv.olap.olap)); - - // recv - DWORD flags = 0; - int res = WSARecv(o->sock, &buf, 1, NULL, &flags, &o->recv.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSARecv failed (%d)", WSAGetLastError()); - connection_report_error(o); - return; - } - - // set busy - o->recv.busy = 1; - o->recv.busy_data_len = data_len; -} - -static void connection_send_olap_handler (BConnection *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(o->send.busy) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->send.busy = 0; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "sending failed"); - connection_report_error(o); - return; - } - - ASSERT(bytes > 0) - ASSERT(bytes <= o->send.busy_data_len) - - // done - StreamPassInterface_Done(&o->send.iface, bytes); -} - -static void connection_recv_olap_handler (BConnection *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->recv.closed) - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(o->recv.busy) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->recv.busy = 0; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "receiving failed"); - connection_report_error(o); - return; - } - - if (bytes == 0) { - // set closed - o->recv.closed = 1; - - // report recv closed - o->handler(o->user, BCONNECTION_EVENT_RECVCLOSED); - return; - } - - ASSERT(bytes > 0) - ASSERT(bytes <= o->recv.busy_data_len) - - // done - StreamRecvInterface_Done(&o->recv.iface, bytes); -} - -int BConnection_AddressSupported (BAddr addr) -{ - BAddr_Assert(&addr); - - return (addr.type == BADDR_TYPE_IPV4 || addr.type == BADDR_TYPE_IPV6); -} - -int BListener_Init (BListener *o, BAddr addr, BReactor *reactor, void *user, - BListener_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // check address - if (!BConnection_AddressSupported(addr)) { - BLog(BLOG_ERROR, "address not supported"); - goto fail0; - } - - // convert address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // remember family - o->sys_family = sysaddr.addr.generic.sa_family; - - // init socket - if ((o->sock = WSASocket(sysaddr.addr.generic.sa_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { - BLog(BLOG_ERROR, "WSASocket failed"); - goto fail0; - } - - // associate with IOCP - if (!CreateIoCompletionPort((HANDLE)o->sock, BReactor_GetIOCPHandle(o->reactor), 0, 0)) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail1; - } - - // bind - if (bind(o->sock, &sysaddr.addr.generic, sysaddr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - goto fail1; - } - - // listen - if (listen(o->sock, LISTEN_BACKLOG) < 0) { - BLog(BLOG_ERROR, "listen failed"); - goto fail1; - } - - DWORD out_bytes; - - // obtain AcceptEx - GUID guid1 = WSAID_ACCEPTEX; - if (WSAIoctl(o->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid1, sizeof(guid1), &o->fnAcceptEx, sizeof(o->fnAcceptEx), &out_bytes, NULL, NULL) != 0) { - BLog(BLOG_ERROR, "faild to obtain AcceptEx"); - goto fail1; - } - - // obtain GetAcceptExSockaddrs - GUID guid2 = WSAID_GETACCEPTEXSOCKADDRS; - if (WSAIoctl(o->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid2, sizeof(guid2), &o->fnGetAcceptExSockaddrs, sizeof(o->fnGetAcceptExSockaddrs), &out_bytes, NULL, NULL) != 0) { - BLog(BLOG_ERROR, "faild to obtain GetAcceptExSockaddrs"); - goto fail1; - } - - // init olap - BReactorIOCPOverlapped_Init(&o->olap, o->reactor, o, (BReactorIOCPOverlapped_handler)listener_olap_handler); - - // init next job - BPending_Init(&o->next_job, BReactor_PendingGroup(o->reactor), (BPending_handler)listener_next_job_handler, o); - - // set not busy - o->busy = 0; - - // set not ready - o->ready = 0; - - // set next job - BPending_Set(&o->next_job); - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } -fail0: - return 0; -} - -void BListener_Free (BListener *o) -{ - DebugObject_Free(&o->d_obj); - - // cancel I/O - if (o->busy) { - if (!CancelIo((HANDLE)o->sock)) { - BLog(BLOG_ERROR, "CancelIo failed"); - } - } - - // close socket - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - - // wait for accept operation to finish - if (o->busy) { - BReactorIOCPOverlapped_Wait(&o->olap, NULL, NULL); - } - - // close new socket - if (o->busy || o->ready) { - if (closesocket(o->newsock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - } - - // free next job - BPending_Free(&o->next_job); - - // free olap - BReactorIOCPOverlapped_Free(&o->olap); -} - -int BConnector_Init (BConnector *o, BAddr addr, BReactor *reactor, void *user, - BConnector_handler handler) -{ - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // check address - if (!BConnection_AddressSupported(addr)) { - BLog(BLOG_ERROR, "address not supported"); - goto fail0; - } - - // convert address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // create local any address - struct sys_addr local_sysaddr; - addr_any_to_sys(&local_sysaddr, addr.type); - - // init socket - if ((o->sock = WSASocket(sysaddr.addr.generic.sa_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { - BLog(BLOG_ERROR, "WSASocket failed"); - goto fail0; - } - - // associate with IOCP - if (!CreateIoCompletionPort((HANDLE)o->sock, BReactor_GetIOCPHandle(o->reactor), 0, 0)) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail1; - } - - // bind socket - if (bind(o->sock, &local_sysaddr.addr.generic, local_sysaddr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - goto fail1; - } - - // obtain ConnectEx - GUID guid = WSAID_CONNECTEX; - DWORD out_bytes; - if (WSAIoctl(o->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &o->fnConnectEx, sizeof(o->fnConnectEx), &out_bytes, NULL, NULL) != 0) { - BLog(BLOG_ERROR, "faild to get ConnectEx"); - goto fail1; - } - - // init olap - BReactorIOCPOverlapped_Init(&o->olap, o->reactor, o, (BReactorIOCPOverlapped_handler)connector_olap_handler); - - // start connect operation - BOOL res = o->fnConnectEx(o->sock, &sysaddr.addr.generic, sysaddr.len, NULL, 0, NULL, &o->olap.olap); - if (res == FALSE && WSAGetLastError() != ERROR_IO_PENDING) { - BLog(BLOG_ERROR, "ConnectEx failed (%d)", WSAGetLastError()); - goto fail2; - } - - // set busy - o->busy = 1; - - // set not ready - o->ready = 0; - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - BReactorIOCPOverlapped_Free(&o->olap); -fail1: - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } -fail0: - return 0; -} - -void BConnector_Free (BConnector *o) -{ - DebugObject_Free(&o->d_obj); - - if (o->sock != INVALID_SOCKET) { - connector_abort(o); - } -} - -int BConnection_Init (BConnection *o, struct BConnection_source source, BReactor *reactor, void *user, - BConnection_handler handler) -{ - switch (source.type) { - case BCONNECTION_SOURCE_TYPE_LISTENER: { - BListener *listener = source.u.listener.listener; - DebugObject_Access(&listener->d_obj); - ASSERT(BPending_IsSet(&listener->next_job)) - ASSERT(!listener->busy) - ASSERT(listener->ready) - } break; - case BCONNECTION_SOURCE_TYPE_CONNECTOR: { - BConnector *connector = source.u.connector.connector; - DebugObject_Access(&connector->d_obj); - ASSERT(connector->reactor == reactor) - ASSERT(connector->sock != INVALID_SOCKET) - ASSERT(!connector->busy) - ASSERT(connector->ready) - } break; - default: ASSERT(0); - } - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - switch (source.type) { - case BCONNECTION_SOURCE_TYPE_LISTENER: { - BListener *listener = source.u.listener.listener; - - // grab new socket from listener - o->sock = listener->newsock; - listener->ready = 0; - - // associate with IOCP - if (!CreateIoCompletionPort((HANDLE)o->sock, BReactor_GetIOCPHandle(o->reactor), 0, 0)) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail1; - } - - // return address - if (source.u.listener.out_addr) { - struct sockaddr *addr_local; - struct sockaddr *addr_remote; - int len_local; - int len_remote; - listener->fnGetAcceptExSockaddrs(listener->addrbuf, 0, sizeof(struct BListener_addrbuf_stub), sizeof(struct BListener_addrbuf_stub), - &addr_local, &len_local, &addr_remote, &len_remote); - - struct sys_addr sysaddr; - - ASSERT_FORCE(len_remote >= 0) - ASSERT_FORCE(len_remote <= sizeof(sysaddr.addr)) - - memcpy((uint8_t *)&sysaddr.addr, (uint8_t *)addr_remote, len_remote); - sysaddr.len = len_remote; - - addr_sys_to_socket(source.u.listener.out_addr, sysaddr); - } - } break; - - case BCONNECTION_SOURCE_TYPE_CONNECTOR: { - BConnector *connector = source.u.connector.connector; - - // grab fd from connector - o->sock = connector->sock; - connector->sock = INVALID_SOCKET; - - // release connector resources - connector_abort(connector); - } break; - } - - // set not aborted - o->aborted = 0; - - // init send olap - BReactorIOCPOverlapped_Init(&o->send.olap, o->reactor, o, (BReactorIOCPOverlapped_handler)connection_send_olap_handler); - - // set send not inited - o->send.inited = 0; - - // init recv olap - BReactorIOCPOverlapped_Init(&o->recv.olap, o->reactor, o, (BReactorIOCPOverlapped_handler)connection_recv_olap_handler); - - // set recv not closed - o->recv.closed = 0; - - // set recv not inited - o->recv.inited = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - return 0; -} - -void BConnection_Free (BConnection *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - ASSERT(!o->recv.inited) - ASSERT(!o->send.inited) - - if (!o->aborted) { - connection_abort(o); - } -} - -void BConnection_SetHandlers (BConnection *o, void *user, BConnection_handler handler) -{ - DebugObject_Access(&o->d_obj); - - // set handlers - o->user = user; - o->handler = handler; -} - -int BConnection_SetSendBuffer (BConnection *o, int buf_size) -{ - DebugObject_Access(&o->d_obj); - - if (setsockopt(o->sock, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)) < 0) { - BLog(BLOG_ERROR, "setsockopt failed"); - return 0; - } - - return 1; -} - -void BConnection_SendAsync_Init (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(!o->send.inited) - - // init interface - StreamPassInterface_Init(&o->send.iface, (StreamPassInterface_handler_send)connection_send_iface_handler_send, o, BReactor_PendingGroup(o->reactor)); - - // set not busy - o->send.busy = 0; - - // set inited - o->send.inited = 1; -} - -void BConnection_SendAsync_Free (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - // abort if busy - if (o->send.busy && !o->aborted) { - connection_abort(o); - } - - // free interface - StreamPassInterface_Free(&o->send.iface); - - // set not inited - o->send.inited = 0; -} - -StreamPassInterface * BConnection_SendAsync_GetIf (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - return &o->send.iface; -} - -void BConnection_RecvAsync_Init (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->recv.closed) - ASSERT(!o->aborted) - ASSERT(!o->recv.inited) - - // init interface - StreamRecvInterface_Init(&o->recv.iface, (StreamRecvInterface_handler_recv)connection_recv_iface_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // set not busy - o->recv.busy = 0; - - // set inited - o->recv.inited = 1; -} - -void BConnection_RecvAsync_Free (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - // abort if busy - if (o->recv.busy && !o->aborted) { - connection_abort(o); - } - - // free interface - StreamRecvInterface_Free(&o->recv.iface); - - // set not inited - o->recv.inited = 0; -} - -StreamRecvInterface * BConnection_RecvAsync_GetIf (BConnection *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - return &o->recv.iface; -} diff --git a/external/badvpn_dns/system/BConnection_win.h b/external/badvpn_dns/system/BConnection_win.h deleted file mode 100644 index da9a8ed..0000000 --- a/external/badvpn_dns/system/BConnection_win.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file BConnection_win.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <windows.h> -#include <winsock2.h> -#ifdef BADVPN_USE_SHIPPED_MSWSOCK -# include <misc/mswsock.h> -#else -# include <mswsock.h> -#endif - -#include <misc/debugerror.h> -#include <base/DebugObject.h> - -struct BListener_addrbuf_stub { - union { - struct sockaddr_in ipv4; - struct sockaddr_in6 ipv6; - } addr; - uint8_t extra[16]; -}; - -struct BListener_s { - BReactor *reactor; - void *user; - BListener_handler handler; - int sys_family; - SOCKET sock; - LPFN_ACCEPTEX fnAcceptEx; - LPFN_GETACCEPTEXSOCKADDRS fnGetAcceptExSockaddrs; - BReactorIOCPOverlapped olap; - SOCKET newsock; - uint8_t addrbuf[2 * sizeof(struct BListener_addrbuf_stub)]; - BPending next_job; - int busy; - int ready; - DebugObject d_obj; -}; - -struct BConnector_s { - BReactor *reactor; - void *user; - BConnector_handler handler; - SOCKET sock; - LPFN_CONNECTEX fnConnectEx; - BReactorIOCPOverlapped olap; - int busy; - int ready; - DebugObject d_obj; -}; - -struct BConnection_s { - BReactor *reactor; - void *user; - BConnection_handler handler; - SOCKET sock; - int aborted; - struct { - BReactorIOCPOverlapped olap; - int inited; - StreamPassInterface iface; - int busy; - int busy_data_len; - } send; - struct { - BReactorIOCPOverlapped olap; - int closed; - int inited; - StreamRecvInterface iface; - int busy; - int busy_data_len; - } recv; - DebugError d_err; - DebugObject d_obj; -}; diff --git a/external/badvpn_dns/system/BDatagram.h b/external/badvpn_dns/system/BDatagram.h deleted file mode 100644 index 33efb45..0000000 --- a/external/badvpn_dns/system/BDatagram.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file BDatagram.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SYSTEM_BDATAGRAM -#define BADVPN_SYSTEM_BDATAGRAM - -#include <misc/debug.h> -#include <flow/PacketPassInterface.h> -#include <flow/PacketRecvInterface.h> -#include <system/BAddr.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> - -struct BDatagram_s; - -/** - * Represents datagram communication. This is usually UDP, but may also be Linux packet sockets. - * Sending and receiving is performed via {@link PacketPassInterface} and {@link PacketRecvInterface}, - * respectively. - */ -typedef struct BDatagram_s BDatagram; - -#define BDATAGRAM_EVENT_ERROR 1 - -/** - * Handler called when an error occurs with the datagram object. - * The datagram object is no longer usable and must be freed from withing the job closure of - * this handler. No further I/O, interface initialization, binding and send address setting - * must occur. - * - * @param user as in {@link BDatagram_Init} - * @param event always BDATAGRAM_EVENT_ERROR - */ -typedef void (*BDatagram_handler) (void *user, int event); - -/** - * Checks if the given address family (from {@link BAddr.h}) is supported by {@link BDatagram} - * and related objects. - * - * @param family family to check - * @return 1 if supported, 0 if not - */ -int BDatagram_AddressFamilySupported (int family); - -/** - * Initializes the object. - * {@link BNetwork_GlobalInit} must have been done. - * - * @param o the object - * @param family address family. Must be supported according to {@link BDatagram_AddressFamilySupported}. - * @param reactor reactor we live in - * @param user argument to handler - * @param handler handler called when an error occurs - * @return 1 on success, 0 on failure - */ -int BDatagram_Init (BDatagram *o, int family, BReactor *reactor, void *user, - BDatagram_handler handler) WARN_UNUSED; - -/** - * Frees the object. - * The send and receive interfaces must not be initialized. - * - * @param o the object - */ -void BDatagram_Free (BDatagram *o); - -/** - * Binds to the given local address. - * May initiate I/O. - * - * @param o the object - * @param addr address to bind to. Its family must be supported according to {@link BDatagram_AddressFamilySupported}. - * @return 1 on success, 0 on failure - */ -int BDatagram_Bind (BDatagram *o, BAddr addr) WARN_UNUSED; - -/** - * Sets addresses for sending. - * May initiate I/O. - * - * @param o the object - * @param remote_addr destination address for sending datagrams. Its family must be supported according - * to {@link BDatagram_AddressFamilySupported}. - * @param local_addr local source IP address. May be an invalid address, otherwise its family must be - * supported according to {@link BDatagram_AddressFamilySupported}. - */ -void BDatagram_SetSendAddrs (BDatagram *o, BAddr remote_addr, BIPAddr local_addr); - -/** - * Returns the remote and local address of the last datagram received. - * Fails if and only if no datagrams have been received yet. - * - * @param o the object - * @param remote_addr returns the remote source address of the datagram. May be an invalid address, theoretically. - * @param local_addr returns the local destination IP address. May be an invalid address. - * @return 1 on success, 0 on failure - */ -int BDatagram_GetLastReceiveAddrs (BDatagram *o, BAddr *remote_addr, BIPAddr *local_addr); - -#ifndef BADVPN_USE_WINAPI -/** - * Returns the underlying socket file descriptor of the datagram object. - * Available on Unix-like systems only. - * - * @param o the object - * @return file descriptor - */ -int BDatagram_GetFd (BDatagram *o); -#endif - -/** - * Sets the SO_REUSEADDR option for the underlying socket. - * - * @param o the object - * @param reuse value of the option. Must be 0 or 1. - */ -int BDatagram_SetReuseAddr (BDatagram *o, int reuse); - -/** - * Initializes the send interface. - * The send interface must not be initialized. - * - * @param o the object - * @param mtu maximum transmission unit. Must be >=0. - */ -void BDatagram_SendAsync_Init (BDatagram *o, int mtu); - -/** - * Frees the send interface. - * The send interface must be initialized. - * If the send interface was busy when this is called, the datagram object is no longer usable and must be - * freed before any further I/O or interface initialization. - * - * @param o the object - */ -void BDatagram_SendAsync_Free (BDatagram *o); - -/** - * Returns the send interface. - * The send interface must be initialized. - * The MTU of the interface will be as in {@link BDatagram_SendAsync_Init}. - * - * @param o the object - * @return send interface - */ -PacketPassInterface * BDatagram_SendAsync_GetIf (BDatagram *o); - -/** - * Initializes the receive interface. - * The receive interface must not be initialized. - * - * @param o the object - * @param mtu maximum transmission unit. Must be >=0. - */ -void BDatagram_RecvAsync_Init (BDatagram *o, int mtu); - -/** - * Frees the receive interface. - * The receive interface must be initialized. - * If the receive interface was busy when this is called, the datagram object is no longer usable and must be - * freed before any further I/O or interface initialization. - * - * @param o the object - */ -void BDatagram_RecvAsync_Free (BDatagram *o); - -/** - * Returns the receive interface. - * The receive interface must be initialized. - * The MTU of the interface will be as in {@link BDatagram_RecvAsync_Init}. - * - * @param o the object - * @return receive interface - */ -PacketRecvInterface * BDatagram_RecvAsync_GetIf (BDatagram *o); - -#ifdef BADVPN_USE_WINAPI -#include "BDatagram_win.h" -#else -#include "BDatagram_unix.h" -#endif - -#endif diff --git a/external/badvpn_dns/system/BDatagram_unix.c b/external/badvpn_dns/system/BDatagram_unix.c deleted file mode 100644 index 67853db..0000000 --- a/external/badvpn_dns/system/BDatagram_unix.c +++ /dev/null @@ -1,855 +0,0 @@ -/** - * @file BDatagram_unix.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#ifdef BADVPN_LINUX -# include <netpacket/packet.h> -# include <net/ethernet.h> -#endif - -#include <misc/nonblocking.h> -#include <base/BLog.h> - -#include "BDatagram.h" - -#include <generated/blog_channel_BDatagram.h> - -struct sys_addr { - socklen_t len; - union { - struct sockaddr generic; - struct sockaddr_in ipv4; - struct sockaddr_in6 ipv6; -#ifdef BADVPN_LINUX - struct sockaddr_ll packet; -#endif - } addr; -}; - -static int family_socket_to_sys (int family); -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr); -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr); -static void set_pktinfo (int fd, int family); -static void report_error (BDatagram *o); -static void do_send (BDatagram *o); -static void do_recv (BDatagram *o); -static void fd_handler (BDatagram *o, int events); -static void send_job_handler (BDatagram *o); -static void recv_job_handler (BDatagram *o); -static void send_if_handler_send (BDatagram *o, uint8_t *data, int data_len); -static void recv_if_handler_recv (BDatagram *o, uint8_t *data); - -static int family_socket_to_sys (int family) -{ - switch (family) { - case BADDR_TYPE_IPV4: - return AF_INET; - case BADDR_TYPE_IPV6: - return AF_INET6; -#ifdef BADVPN_LINUX - case BADDR_TYPE_PACKET: - return AF_PACKET; -#endif - } - - ASSERT(0); - return 0; -} - -static void addr_socket_to_sys (struct sys_addr *out, BAddr addr) -{ - switch (addr.type) { - case BADDR_TYPE_IPV4: { - out->len = sizeof(out->addr.ipv4); - memset(&out->addr.ipv4, 0, sizeof(out->addr.ipv4)); - out->addr.ipv4.sin_family = AF_INET; - out->addr.ipv4.sin_port = addr.ipv4.port; - out->addr.ipv4.sin_addr.s_addr = addr.ipv4.ip; - } break; - - case BADDR_TYPE_IPV6: { - out->len = sizeof(out->addr.ipv6); - memset(&out->addr.ipv6, 0, sizeof(out->addr.ipv6)); - out->addr.ipv6.sin6_family = AF_INET6; - out->addr.ipv6.sin6_port = addr.ipv6.port; - out->addr.ipv6.sin6_flowinfo = 0; - memcpy(out->addr.ipv6.sin6_addr.s6_addr, addr.ipv6.ip, 16); - out->addr.ipv6.sin6_scope_id = 0; - } break; - -#ifdef BADVPN_LINUX - case BADDR_TYPE_PACKET: { - ASSERT(addr.packet.header_type == BADDR_PACKET_HEADER_TYPE_ETHERNET) - memset(&out->addr.packet, 0, sizeof(out->addr.packet)); - out->len = sizeof(out->addr.packet); - out->addr.packet.sll_family = AF_PACKET; - out->addr.packet.sll_protocol = addr.packet.phys_proto; - out->addr.packet.sll_ifindex = addr.packet.interface_index; - out->addr.packet.sll_hatype = 1; // linux/if_arp.h: #define ARPHRD_ETHER 1 - switch (addr.packet.packet_type) { - case BADDR_PACKET_PACKET_TYPE_HOST: - out->addr.packet.sll_pkttype = PACKET_HOST; - break; - case BADDR_PACKET_PACKET_TYPE_BROADCAST: - out->addr.packet.sll_pkttype = PACKET_BROADCAST; - break; - case BADDR_PACKET_PACKET_TYPE_MULTICAST: - out->addr.packet.sll_pkttype = PACKET_MULTICAST; - break; - case BADDR_PACKET_PACKET_TYPE_OTHERHOST: - out->addr.packet.sll_pkttype = PACKET_OTHERHOST; - break; - case BADDR_PACKET_PACKET_TYPE_OUTGOING: - out->addr.packet.sll_pkttype = PACKET_OUTGOING; - break; - default: - ASSERT(0); - } - out->addr.packet.sll_halen = 6; - memcpy(out->addr.packet.sll_addr, addr.packet.phys_addr, 6); - } break; -#endif - - default: ASSERT(0); - } -} - -static void addr_sys_to_socket (BAddr *out, struct sys_addr addr) -{ - switch (addr.addr.generic.sa_family) { - case AF_INET: { - ASSERT(addr.len == sizeof(struct sockaddr_in)) - BAddr_InitIPv4(out, addr.addr.ipv4.sin_addr.s_addr, addr.addr.ipv4.sin_port); - } break; - - case AF_INET6: { - ASSERT(addr.len == sizeof(struct sockaddr_in6)) - BAddr_InitIPv6(out, addr.addr.ipv6.sin6_addr.s6_addr, addr.addr.ipv6.sin6_port); - } break; - -#ifdef BADVPN_LINUX - case AF_PACKET: { - if (addr.len < offsetof(struct sockaddr_ll, sll_addr) + 6) { - goto fail; - } - if (addr.addr.packet.sll_hatype != 1) { // linux/if_arp.h: #define ARPHRD_ETHER 1 - goto fail; - } - int packet_type; - switch (addr.addr.packet.sll_pkttype) { - case PACKET_HOST: - packet_type = BADDR_PACKET_PACKET_TYPE_HOST; - break; - case PACKET_BROADCAST: - packet_type = BADDR_PACKET_PACKET_TYPE_BROADCAST; - break; - case PACKET_MULTICAST: - packet_type = BADDR_PACKET_PACKET_TYPE_MULTICAST; - break; - case PACKET_OTHERHOST: - packet_type = BADDR_PACKET_PACKET_TYPE_OTHERHOST; - break; - case PACKET_OUTGOING: - packet_type = BADDR_PACKET_PACKET_TYPE_OUTGOING; - break; - default: - goto fail; - } - if (addr.addr.packet.sll_halen != 6) { - goto fail; - } - BAddr_InitPacket(out, addr.addr.packet.sll_protocol, addr.addr.packet.sll_ifindex, BADDR_PACKET_HEADER_TYPE_ETHERNET, packet_type, addr.addr.packet.sll_addr); - } break; -#endif - - fail: - default: { - BAddr_InitNone(out); - } break; - } -} - -static void set_pktinfo (int fd, int family) -{ - int opt = 1; - - switch (family) { - case BADDR_TYPE_IPV4: { -#ifdef BADVPN_FREEBSD - if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) < 0) { - BLog(BLOG_ERROR, "setsockopt(IP_RECVDSTADDR) failed"); - } -#else - if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) < 0) { - BLog(BLOG_ERROR, "setsockopt(IP_PKTINFO) failed"); - } -#endif - } break; - -#ifdef IPV6_RECVPKTINFO - case BADDR_TYPE_IPV6: { - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) < 0) { - BLog(BLOG_ERROR, "setsockopt(IPV6_RECVPKTINFO) failed"); - } - } break; -#endif - } -} - -static void report_error (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BDATAGRAM_EVENT_ERROR)); - return; -} - -static void do_send (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.inited) - ASSERT(o->send.busy) - ASSERT(o->send.have_addrs) - - // limit - if (!BReactorLimit_Increment(&o->send.limit)) { - // wait for fd - o->wait_events |= BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - // convert destination address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, o->send.remote_addr); - - struct iovec iov; - iov.iov_base = (uint8_t *)o->send.busy_data; - iov.iov_len = o->send.busy_data_len; - - union { -#ifdef BADVPN_FREEBSD - char in[CMSG_SPACE(sizeof(struct in_addr))]; -#else - char in[CMSG_SPACE(sizeof(struct in_pktinfo))]; -#endif - char in6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; - } cdata; - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_name = &sysaddr.addr.generic; - msg.msg_namelen = sysaddr.len; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cdata; - msg.msg_controllen = sizeof(cdata); - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - - size_t controllen = 0; - - switch (o->send.local_addr.type) { - case BADDR_TYPE_IPV4: { -#ifdef BADVPN_FREEBSD - memset(cmsg, 0, CMSG_SPACE(sizeof(struct in_addr))); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_SENDSRCADDR; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); - struct in_addr *addrinfo = (struct in_addr *)CMSG_DATA(cmsg); - addrinfo->s_addr = o->send.local_addr.ipv4; - controllen += CMSG_SPACE(sizeof(struct in_addr)); -#else - memset(cmsg, 0, CMSG_SPACE(sizeof(struct in_pktinfo))); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); - struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); - pktinfo->ipi_spec_dst.s_addr = o->send.local_addr.ipv4; - controllen += CMSG_SPACE(sizeof(struct in_pktinfo)); -#endif - } break; - - case BADDR_TYPE_IPV6: { - memset(cmsg, 0, CMSG_SPACE(sizeof(struct in6_pktinfo))); - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); - struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); - memcpy(pktinfo->ipi6_addr.s6_addr, o->send.local_addr.ipv6, 16); - controllen += CMSG_SPACE(sizeof(struct in6_pktinfo)); - } break; - } - - msg.msg_controllen = controllen; - - if (msg.msg_controllen == 0) { - msg.msg_control = NULL; - } - - // send - int bytes = sendmsg(o->fd, &msg, 0); - if (bytes < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // wait for fd - o->wait_events |= BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - BLog(BLOG_ERROR, "send failed"); - report_error(o); - return; - } - - ASSERT(bytes >= 0) - ASSERT(bytes <= o->send.busy_data_len) - - if (bytes < o->send.busy_data_len) { - BLog(BLOG_ERROR, "send sent too little"); - } - - // if recv wasn't started yet, start it - if (!o->recv.started) { - // set recv started - o->recv.started = 1; - - // continue receiving - if (o->recv.inited && o->recv.busy) { - BPending_Set(&o->recv.job); - } - } - - // set not busy - o->send.busy = 0; - - // done - PacketPassInterface_Done(&o->send.iface); -} - -static void do_recv (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.inited) - ASSERT(o->recv.busy) - ASSERT(o->recv.started) - - // limit - if (!BReactorLimit_Increment(&o->recv.limit)) { - // wait for fd - o->wait_events |= BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - struct sys_addr sysaddr; - - struct iovec iov; - iov.iov_base = o->recv.busy_data; - iov.iov_len = o->recv.mtu; - - union { -#ifdef BADVPN_FREEBSD - char in[CMSG_SPACE(sizeof(struct in_addr))]; -#else - char in[CMSG_SPACE(sizeof(struct in_pktinfo))]; -#endif - char in6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; - } cdata; - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_name = &sysaddr.addr.generic; - msg.msg_namelen = sizeof(sysaddr.addr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cdata; - msg.msg_controllen = sizeof(cdata); - - // recv - int bytes = recvmsg(o->fd, &msg, 0); - if (bytes < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // wait for fd - o->wait_events |= BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - return; - } - - BLog(BLOG_ERROR, "recv failed"); - report_error(o); - return; - } - - ASSERT(bytes >= 0) - ASSERT(bytes <= o->recv.mtu) - - // read returned address - sysaddr.len = msg.msg_namelen; - addr_sys_to_socket(&o->recv.remote_addr, sysaddr); - - // read returned local address - BIPAddr_InitInvalid(&o->recv.local_addr); - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { -#ifdef BADVPN_FREEBSD - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { - struct in_addr *addrinfo = (struct in_addr *)CMSG_DATA(cmsg); - BIPAddr_InitIPv4(&o->recv.local_addr, addrinfo->s_addr); - } -#else - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); - BIPAddr_InitIPv4(&o->recv.local_addr, pktinfo->ipi_addr.s_addr); - } -#endif - else if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); - BIPAddr_InitIPv6(&o->recv.local_addr, pktinfo->ipi6_addr.s6_addr); - } - } - - // set have addresses - o->recv.have_addrs = 1; - - // set not busy - o->recv.busy = 0; - - // done - PacketRecvInterface_Done(&o->recv.iface, bytes); -} - -static void fd_handler (BDatagram *o, int events) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - // clear handled events - o->wait_events &= ~events; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - - int have_send = 0; - int have_recv = 0; - - if ((events & BREACTOR_WRITE) || ((events & (BREACTOR_ERROR|BREACTOR_HUP)) && o->send.inited && o->send.busy && o->send.have_addrs)) { - ASSERT(o->send.inited) - ASSERT(o->send.busy) - ASSERT(o->send.have_addrs) - - have_send = 1; - } - - if ((events & BREACTOR_READ) || ((events & (BREACTOR_ERROR|BREACTOR_HUP)) && o->recv.inited && o->recv.busy && o->recv.started)) { - ASSERT(o->recv.inited) - ASSERT(o->recv.busy) - ASSERT(o->recv.started) - - have_recv = 1; - } - - if (have_send) { - if (have_recv) { - BPending_Set(&o->recv.job); - } - - do_send(o); - return; - } - - if (have_recv) { - do_recv(o); - return; - } - - BLog(BLOG_ERROR, "fd error event"); - report_error(o); - return; -} - -static void send_job_handler (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.inited) - ASSERT(o->send.busy) - ASSERT(o->send.have_addrs) - - do_send(o); - return; -} - -static void recv_job_handler (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.inited) - ASSERT(o->recv.busy) - ASSERT(o->recv.started) - - do_recv(o); - return; -} - -static void send_if_handler_send (BDatagram *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->send.inited) - ASSERT(!o->send.busy) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->send.mtu) - - // remember data - o->send.busy_data = data; - o->send.busy_data_len = data_len; - - // set busy - o->send.busy = 1; - - // if have no addresses, wait - if (!o->send.have_addrs) { - return; - } - - // set job - BPending_Set(&o->send.job); -} - -static void recv_if_handler_recv (BDatagram *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv.inited) - ASSERT(!o->recv.busy) - - // remember data - o->recv.busy_data = data; - - // set busy - o->recv.busy = 1; - - // if recv not started yet, wait - if (!o->recv.started) { - return; - } - - // set job - BPending_Set(&o->recv.job); -} - -int BDatagram_AddressFamilySupported (int family) -{ - switch (family) { - case BADDR_TYPE_IPV4: - case BADDR_TYPE_IPV6: -#ifdef BADVPN_LINUX - case BADDR_TYPE_PACKET: -#endif - return 1; - } - - return 0; -} - -int BDatagram_Init (BDatagram *o, int family, BReactor *reactor, void *user, - BDatagram_handler handler) -{ - ASSERT(BDatagram_AddressFamilySupported(family)) - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // init fd - if ((o->fd = socket(family_socket_to_sys(family), SOCK_DGRAM, 0)) < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail0; - } - - // set fd non-blocking - if (!badvpn_set_nonblocking(o->fd)) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - // enable receiving pktinfo - set_pktinfo(o->fd, family); - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - - // set no wait events - o->wait_events = 0; - - // init limits - BReactorLimit_Init(&o->send.limit, o->reactor, BDATAGRAM_SEND_LIMIT); - BReactorLimit_Init(&o->recv.limit, o->reactor, BDATAGRAM_RECV_LIMIT); - - // set have no send and recv addresses - o->send.have_addrs = 0; - o->recv.have_addrs = 0; - - // set recv not started - o->recv.started = 0; - - // set send and recv not inited - o->send.inited = 0; - o->recv.inited = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail0: - return 0; -} - -void BDatagram_Free (BDatagram *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - ASSERT(!o->recv.inited) - ASSERT(!o->send.inited) - - // free limits - BReactorLimit_Free(&o->recv.limit); - BReactorLimit_Free(&o->send.limit); - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - // free fd - if (close(o->fd) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -} - -int BDatagram_Bind (BDatagram *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(BDatagram_AddressFamilySupported(addr.type)) - - // translate address - struct sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // bind - if (bind(o->fd, &sysaddr.addr.generic, sysaddr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - return 0; - } - - // if recv wasn't started yet, start it - if (!o->recv.started) { - // set recv started - o->recv.started = 1; - - // continue receiving - if (o->recv.inited && o->recv.busy) { - BPending_Set(&o->recv.job); - } - } - - return 1; -} - -void BDatagram_SetSendAddrs (BDatagram *o, BAddr remote_addr, BIPAddr local_addr) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(BDatagram_AddressFamilySupported(remote_addr.type)) - ASSERT(local_addr.type == BADDR_TYPE_NONE || BDatagram_AddressFamilySupported(local_addr.type)) - - // set addresses - o->send.remote_addr = remote_addr; - o->send.local_addr = local_addr; - - if (!o->send.have_addrs) { - // set have addresses - o->send.have_addrs = 1; - - // start sending - if (o->send.inited && o->send.busy) { - BPending_Set(&o->send.job); - } - } -} - -int BDatagram_GetLastReceiveAddrs (BDatagram *o, BAddr *remote_addr, BIPAddr *local_addr) -{ - DebugObject_Access(&o->d_obj); - - if (!o->recv.have_addrs) { - return 0; - } - - *remote_addr = o->recv.remote_addr; - *local_addr = o->recv.local_addr; - return 1; -} - -int BDatagram_GetFd (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - - return o->fd; -} - -int BDatagram_SetReuseAddr (BDatagram *o, int reuse) -{ - DebugObject_Access(&o->d_obj); - ASSERT(reuse == 0 || reuse == 1) - - if (setsockopt(o->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { - return 0; - } - - return 1; -} - -void BDatagram_SendAsync_Init (BDatagram *o, int mtu) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->send.inited) - ASSERT(mtu >= 0) - - // init arguments - o->send.mtu = mtu; - - // init interface - PacketPassInterface_Init(&o->send.iface, o->send.mtu, (PacketPassInterface_handler_send)send_if_handler_send, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->send.job, BReactor_PendingGroup(o->reactor), (BPending_handler)send_job_handler, o); - - // set not busy - o->send.busy = 0; - - // set inited - o->send.inited = 1; -} - -void BDatagram_SendAsync_Free (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - // update events - o->wait_events &= ~BREACTOR_WRITE; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - - // free job - BPending_Free(&o->send.job); - - // free interface - PacketPassInterface_Free(&o->send.iface); - - // set not inited - o->send.inited = 0; -} - -PacketPassInterface * BDatagram_SendAsync_GetIf (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - return &o->send.iface; -} - -void BDatagram_RecvAsync_Init (BDatagram *o, int mtu) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->recv.inited) - ASSERT(mtu >= 0) - - // init arguments - o->recv.mtu = mtu; - - // init interface - PacketRecvInterface_Init(&o->recv.iface, o->recv.mtu, (PacketRecvInterface_handler_recv)recv_if_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->recv.job, BReactor_PendingGroup(o->reactor), (BPending_handler)recv_job_handler, o); - - // set not busy - o->recv.busy = 0; - - // set inited - o->recv.inited = 1; -} - -void BDatagram_RecvAsync_Free (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - // update events - o->wait_events &= ~BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->wait_events); - - // free job - BPending_Free(&o->recv.job); - - // free interface - PacketRecvInterface_Free(&o->recv.iface); - - // set not inited - o->recv.inited = 0; -} - -PacketRecvInterface * BDatagram_RecvAsync_GetIf (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - return &o->recv.iface; -} diff --git a/external/badvpn_dns/system/BDatagram_unix.h b/external/badvpn_dns/system/BDatagram_unix.h deleted file mode 100644 index 3ef0262..0000000 --- a/external/badvpn_dns/system/BDatagram_unix.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file BDatagram_unix.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debugerror.h> -#include <base/DebugObject.h> - -#define BDATAGRAM_SEND_LIMIT 2 -#define BDATAGRAM_RECV_LIMIT 2 - -struct BDatagram_s { - BReactor *reactor; - void *user; - BDatagram_handler handler; - int fd; - BFileDescriptor bfd; - int wait_events; - struct { - BReactorLimit limit; - int have_addrs; - BAddr remote_addr; - BIPAddr local_addr; - int inited; - int mtu; - PacketPassInterface iface; - BPending job; - int busy; - const uint8_t *busy_data; - int busy_data_len; - } send; - struct { - BReactorLimit limit; - int started; - int have_addrs; - BAddr remote_addr; - BIPAddr local_addr; - int inited; - int mtu; - PacketRecvInterface iface; - BPending job; - int busy; - uint8_t *busy_data; - } recv; - DebugError d_err; - DebugObject d_obj; -}; diff --git a/external/badvpn_dns/system/BDatagram_win.c b/external/badvpn_dns/system/BDatagram_win.c deleted file mode 100644 index 0528866..0000000 --- a/external/badvpn_dns/system/BDatagram_win.c +++ /dev/null @@ -1,755 +0,0 @@ -/** - * @file BDatagram_win.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> - -#include <base/BLog.h> - -#include "BDatagram.h" - -#include <generated/blog_channel_BDatagram.h> - -static int family_socket_to_sys (int family); -static void addr_socket_to_sys (struct BDatagram_sys_addr *out, BAddr addr); -static void addr_sys_to_socket (BAddr *out, struct BDatagram_sys_addr addr); -static void set_pktinfo (SOCKET sock, int family); -static void report_error (BDatagram *o); -static void datagram_abort (BDatagram *o); -static void start_send (BDatagram *o); -static void start_recv (BDatagram *o); -static void send_job_handler (BDatagram *o); -static void recv_job_handler (BDatagram *o); -static void send_if_handler_send (BDatagram *o, uint8_t *data, int data_len); -static void recv_if_handler_recv (BDatagram *o, uint8_t *data); -static void send_olap_handler (BDatagram *o, int event, DWORD bytes); -static void recv_olap_handler (BDatagram *o, int event, DWORD bytes); - -static int family_socket_to_sys (int family) -{ - switch (family) { - case BADDR_TYPE_IPV4: - return AF_INET; - case BADDR_TYPE_IPV6: - return AF_INET6; - } - - ASSERT(0); - return 0; -} - -static void addr_socket_to_sys (struct BDatagram_sys_addr *out, BAddr addr) -{ - switch (addr.type) { - case BADDR_TYPE_IPV4: { - out->len = sizeof(out->addr.ipv4); - memset(&out->addr.ipv4, 0, sizeof(out->addr.ipv4)); - out->addr.ipv4.sin_family = AF_INET; - out->addr.ipv4.sin_port = addr.ipv4.port; - out->addr.ipv4.sin_addr.s_addr = addr.ipv4.ip; - } break; - - case BADDR_TYPE_IPV6: { - out->len = sizeof(out->addr.ipv6); - memset(&out->addr.ipv6, 0, sizeof(out->addr.ipv6)); - out->addr.ipv6.sin6_family = AF_INET6; - out->addr.ipv6.sin6_port = addr.ipv6.port; - out->addr.ipv6.sin6_flowinfo = 0; - memcpy(out->addr.ipv6.sin6_addr.s6_addr, addr.ipv6.ip, 16); - out->addr.ipv6.sin6_scope_id = 0; - } break; - - default: ASSERT(0); - } -} - -static void addr_sys_to_socket (BAddr *out, struct BDatagram_sys_addr addr) -{ - switch (addr.addr.generic.sa_family) { - case AF_INET: { - ASSERT(addr.len == sizeof(struct sockaddr_in)) - BAddr_InitIPv4(out, addr.addr.ipv4.sin_addr.s_addr, addr.addr.ipv4.sin_port); - } break; - - case AF_INET6: { - ASSERT(addr.len == sizeof(struct sockaddr_in6)) - BAddr_InitIPv6(out, addr.addr.ipv6.sin6_addr.s6_addr, addr.addr.ipv6.sin6_port); - } break; - - default: { - BAddr_InitNone(out); - } break; - } -} - -static void set_pktinfo (SOCKET sock, int family) -{ - DWORD opt = 1; - - switch (family) { - case BADDR_TYPE_IPV4: { - if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char *)&opt, sizeof(opt)) < 0) { - BLog(BLOG_ERROR, "setsockopt(IP_PKTINFO) failed"); - } - } break; - - case BADDR_TYPE_IPV6: { - if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&opt, sizeof(opt)) < 0) { - BLog(BLOG_ERROR, "setsockopt(IPV6_PKTINFO) failed"); - } - } break; - } -} - -static void report_error (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BDATAGRAM_EVENT_ERROR)); - return; -} - -static void datagram_abort (BDatagram *o) -{ - ASSERT(!o->aborted) - - // cancel I/O - if ((o->recv.inited && o->recv.data_have && o->recv.data_busy) || (o->send.inited && o->send.data_len >= 0 && o->send.data_busy)) { - if (!CancelIo((HANDLE)o->sock)) { - BLog(BLOG_ERROR, "CancelIo failed"); - } - } - - // close socket - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } - - // wait for receiving to complete - if (o->recv.inited && o->recv.data_have && o->recv.data_busy) { - BReactorIOCPOverlapped_Wait(&o->recv.olap, NULL, NULL); - } - - // wait for sending to complete - if (o->send.inited && o->send.data_len >= 0 && o->send.data_busy) { - BReactorIOCPOverlapped_Wait(&o->send.olap, NULL, NULL); - } - - // free recv olap - BReactorIOCPOverlapped_Free(&o->recv.olap); - - // free send olap - BReactorIOCPOverlapped_Free(&o->send.olap); - - // set aborted - o->aborted = 1; -} - -static void start_send (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(o->send.data_len >= 0) - ASSERT(!o->send.data_busy) - ASSERT(o->send.have_addrs) - - // convert destination address - addr_socket_to_sys(&o->send.sysaddr, o->send.remote_addr); - - WSABUF buf; - buf.buf = (char *)o->send.data; - buf.len = (o->send.data_len > ULONG_MAX ? ULONG_MAX : o->send.data_len); - - memset(&o->send.olap.olap, 0, sizeof(o->send.olap.olap)); - - if (o->fnWSASendMsg) { - o->send.msg.name = &o->send.sysaddr.addr.generic; - o->send.msg.namelen = o->send.sysaddr.len; - o->send.msg.lpBuffers = &buf; - o->send.msg.dwBufferCount = 1; - o->send.msg.Control.buf = (char *)&o->send.cdata; - o->send.msg.Control.len = sizeof(o->send.cdata); - o->send.msg.dwFlags = 0; - - int sum = 0; - - WSACMSGHDR *cmsg = WSA_CMSG_FIRSTHDR(&o->send.msg); - - switch (o->send.local_addr.type) { - case BADDR_TYPE_IPV4: { - memset(cmsg, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo))); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo)); - struct in_pktinfo *pktinfo = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg); - pktinfo->ipi_addr.s_addr = o->send.local_addr.ipv4; - sum += WSA_CMSG_SPACE(sizeof(struct in_pktinfo)); - } break; - case BADDR_TYPE_IPV6: { - memset(cmsg, 0, WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))); - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(struct in6_pktinfo)); - struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)WSA_CMSG_DATA(cmsg); - memcpy(pktinfo->ipi6_addr.s6_addr, o->send.local_addr.ipv6, 16); - sum += WSA_CMSG_SPACE(sizeof(struct in6_pktinfo)); - } break; - } - - o->send.msg.Control.len = sum; - - if (o->send.msg.Control.len == 0) { - o->send.msg.Control.buf = NULL; - } - - // send - int res = o->fnWSASendMsg(o->sock, &o->send.msg, 0, NULL, &o->send.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSASendMsg failed (%d)", WSAGetLastError()); - report_error(o); - return; - } - } else { - // send - int res = WSASendTo(o->sock, &buf, 1, NULL, 0, &o->send.sysaddr.addr.generic, o->send.sysaddr.len, &o->send.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSASendTo failed (%d)", WSAGetLastError()); - report_error(o); - return; - } - } - - // set busy - o->send.data_busy = 1; -} - -static void start_recv (BDatagram *o) -{ - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(o->recv.data_have) - ASSERT(!o->recv.data_busy) - ASSERT(o->recv.started) - - WSABUF buf; - buf.buf = (char *)o->recv.data; - buf.len = (o->recv.mtu > ULONG_MAX ? ULONG_MAX : o->recv.mtu); - - memset(&o->recv.olap.olap, 0, sizeof(o->recv.olap.olap)); - - if (o->fnWSARecvMsg) { - o->recv.msg.name = &o->recv.sysaddr.addr.generic; - o->recv.msg.namelen = sizeof(o->recv.sysaddr.addr); - o->recv.msg.lpBuffers = &buf; - o->recv.msg.dwBufferCount = 1; - o->recv.msg.Control.buf = (char *)&o->recv.cdata; - o->recv.msg.Control.len = sizeof(o->recv.cdata); - o->recv.msg.dwFlags = 0; - - // recv - int res = o->fnWSARecvMsg(o->sock, &o->recv.msg, NULL, &o->recv.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSARecvMsg failed (%d)", WSAGetLastError()); - report_error(o); - return; - } - } else { - o->recv.sysaddr.len = sizeof(o->recv.sysaddr.addr); - - // recv - DWORD flags = 0; - int res = WSARecvFrom(o->sock, &buf, 1, NULL, &flags, &o->recv.sysaddr.addr.generic, &o->recv.sysaddr.len, &o->recv.olap.olap, NULL); - if (res == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { - BLog(BLOG_ERROR, "WSARecvFrom failed (%d)", WSAGetLastError()); - report_error(o); - return; - } - } - - // set busy - o->recv.data_busy = 1; -} - -static void send_job_handler (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(o->send.data_len >= 0) - ASSERT(!o->send.data_busy) - ASSERT(o->send.have_addrs) - - // send - start_send(o); - return; -} - -static void recv_job_handler (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(o->recv.data_have) - ASSERT(!o->recv.data_busy) - ASSERT(o->recv.started) - - // recv - start_recv(o); - return; -} - -static void send_if_handler_send (BDatagram *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(o->send.data_len == -1) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->send.mtu) - - // remember data - o->send.data = data; - o->send.data_len = data_len; - o->send.data_busy = 0; - - // if have no addresses, wait - if (!o->send.have_addrs) { - return; - } - - // send - start_send(o); - return; -} - -static void recv_if_handler_recv (BDatagram *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(!o->recv.data_have) - - // remember data - o->recv.data = data; - o->recv.data_have = 1; - o->recv.data_busy = 0; - - // if recv not started yet, wait - if (!o->recv.started) { - return; - } - - // recv - start_recv(o); - return; -} - -static void send_olap_handler (BDatagram *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->send.inited) - ASSERT(o->send.data_len >= 0) - ASSERT(o->send.data_busy) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->send.data_busy = 0; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "sending failed"); - report_error(o); - return; - } - - ASSERT(bytes >= 0) - ASSERT(bytes <= o->send.data_len) - - if (bytes < o->send.data_len) { - BLog(BLOG_ERROR, "sent too little"); - } - - // if recv wasn't started yet, start it - if (!o->recv.started) { - // set recv started - o->recv.started = 1; - - // continue receiving - if (o->recv.inited && o->recv.data_have) { - ASSERT(!o->recv.data_busy) - - BPending_Set(&o->recv.job); - } - } - - // set no data - o->send.data_len = -1; - - // done - PacketPassInterface_Done(&o->send.iface); -} - -static void recv_olap_handler (BDatagram *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(o->recv.inited) - ASSERT(o->recv.data_have) - ASSERT(o->recv.data_busy) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set not busy - o->recv.data_busy = 0; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "receiving failed"); - report_error(o); - return; - } - - ASSERT(bytes >= 0) - ASSERT(bytes <= o->recv.mtu) - - if (o->fnWSARecvMsg) { - o->recv.sysaddr.len = o->recv.msg.namelen; - } - - // read remote address - addr_sys_to_socket(&o->recv.remote_addr, o->recv.sysaddr); - - // read local address - BIPAddr_InitInvalid(&o->recv.local_addr); - if (o->fnWSARecvMsg) { - for (WSACMSGHDR *cmsg = WSA_CMSG_FIRSTHDR(&o->recv.msg); cmsg; cmsg = WSA_CMSG_NXTHDR(&o->recv.msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - struct in_pktinfo *pktinfo = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg); - BIPAddr_InitIPv4(&o->recv.local_addr, pktinfo->ipi_addr.s_addr); - } - else if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)WSA_CMSG_DATA(cmsg); - BIPAddr_InitIPv6(&o->recv.local_addr, pktinfo->ipi6_addr.s6_addr); - } - } - } - - // set have addresses - o->recv.have_addrs = 1; - - // set no data - o->recv.data_have = 0; - - // done - PacketRecvInterface_Done(&o->recv.iface, bytes); -} - -int BDatagram_AddressFamilySupported (int family) -{ - return (family == BADDR_TYPE_IPV4 || family == BADDR_TYPE_IPV6); -} - -int BDatagram_Init (BDatagram *o, int family, BReactor *reactor, void *user, - BDatagram_handler handler) -{ - ASSERT(BDatagram_AddressFamilySupported(family)) - ASSERT(handler) - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // init socket - if ((o->sock = WSASocket(family_socket_to_sys(family), SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { - BLog(BLOG_ERROR, "WSASocket failed"); - goto fail0; - } - - DWORD out_bytes; - - // obtain WSASendMsg - GUID guid1 = WSAID_WSASENDMSG; - if (WSAIoctl(o->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid1, sizeof(guid1), &o->fnWSASendMsg, sizeof(o->fnWSASendMsg), &out_bytes, NULL, NULL) != 0) { - o->fnWSASendMsg = NULL; - } - - // obtain WSARecvMsg - GUID guid2 = WSAID_WSARECVMSG; - if (WSAIoctl(o->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid2, sizeof(guid2), &o->fnWSARecvMsg, sizeof(o->fnWSARecvMsg), &out_bytes, NULL, NULL) != 0) { - BLog(BLOG_ERROR, "failed to obtain WSARecvMsg"); - o->fnWSARecvMsg = NULL; - } - - // associate with IOCP - if (!CreateIoCompletionPort((HANDLE)o->sock, BReactor_GetIOCPHandle(o->reactor), 0, 0)) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail1; - } - - // enable receiving pktinfo - set_pktinfo(o->sock, family); - - // set not aborted - o->aborted = 0; - - // init send olap - BReactorIOCPOverlapped_Init(&o->send.olap, o->reactor, o, (BReactorIOCPOverlapped_handler)send_olap_handler); - - // set have no send addrs - o->send.have_addrs = 0; - - // set send not inited - o->send.inited = 0; - - // init recv olap - BReactorIOCPOverlapped_Init(&o->recv.olap, o->reactor, o, (BReactorIOCPOverlapped_handler)recv_olap_handler); - - // set recv not started - o->recv.started = 0; - - // set have no recv addrs - o->recv.have_addrs = 0; - - // set recv not inited - o->recv.inited = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (closesocket(o->sock) == SOCKET_ERROR) { - BLog(BLOG_ERROR, "closesocket failed"); - } -fail0: - return 0; -} - -void BDatagram_Free (BDatagram *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - ASSERT(!o->recv.inited) - ASSERT(!o->send.inited) - - if (!o->aborted) { - datagram_abort(o); - } -} - -int BDatagram_Bind (BDatagram *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(BDatagram_AddressFamilySupported(addr.type)) - - // translate address - struct BDatagram_sys_addr sysaddr; - addr_socket_to_sys(&sysaddr, addr); - - // bind - if (bind(o->sock, &sysaddr.addr.generic, sysaddr.len) < 0) { - BLog(BLOG_ERROR, "bind failed"); - return 0; - } - - // if recv wasn't started yet, start it - if (!o->recv.started) { - // set recv started - o->recv.started = 1; - - // continue receiving - if (o->recv.inited && o->recv.data_have) { - ASSERT(!o->recv.data_busy) - - BPending_Set(&o->recv.job); - } - } - - return 1; -} - -void BDatagram_SetSendAddrs (BDatagram *o, BAddr remote_addr, BIPAddr local_addr) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(BDatagram_AddressFamilySupported(remote_addr.type)) - ASSERT(local_addr.type == BADDR_TYPE_NONE || BDatagram_AddressFamilySupported(local_addr.type)) - - // set addresses - o->send.remote_addr = remote_addr; - o->send.local_addr = local_addr; - - // set have addresses - o->send.have_addrs = 1; - - // start sending - if (o->send.inited && o->send.data_len >= 0 && !o->send.data_busy) { - BPending_Set(&o->send.job); - } -} - -int BDatagram_GetLastReceiveAddrs (BDatagram *o, BAddr *remote_addr, BIPAddr *local_addr) -{ - DebugObject_Access(&o->d_obj); - - if (!o->recv.have_addrs) { - return 0; - } - - *remote_addr = o->recv.remote_addr; - *local_addr = o->recv.local_addr; - return 1; -} - -int BDatagram_SetReuseAddr (BDatagram *o, int reuse) -{ - DebugObject_Access(&o->d_obj); - ASSERT(reuse == 0 || reuse == 1) - - if (setsockopt(o->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) { - return 0; - } - - return 1; -} - -void BDatagram_SendAsync_Init (BDatagram *o, int mtu) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(!o->send.inited) - ASSERT(mtu >= 0) - - // init arguments - o->send.mtu = mtu; - - // init interface - PacketPassInterface_Init(&o->send.iface, o->send.mtu, (PacketPassInterface_handler_send)send_if_handler_send, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->send.job, BReactor_PendingGroup(o->reactor), (BPending_handler)send_job_handler, o); - - // set have no data - o->send.data_len = -1; - - // set inited - o->send.inited = 1; -} - -void BDatagram_SendAsync_Free (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - // abort if busy - if (o->send.data_len >= 0 && o->send.data_busy && !o->aborted) { - datagram_abort(o); - } - - // free job - BPending_Free(&o->send.job); - - // free interface - PacketPassInterface_Free(&o->send.iface); - - // set not inited - o->send.inited = 0; -} - -PacketPassInterface * BDatagram_SendAsync_GetIf (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send.inited) - - return &o->send.iface; -} - -void BDatagram_RecvAsync_Init (BDatagram *o, int mtu) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(!o->aborted) - ASSERT(!o->recv.inited) - ASSERT(mtu >= 0) - - // init arguments - o->recv.mtu = mtu; - - // init interface - PacketRecvInterface_Init(&o->recv.iface, o->recv.mtu, (PacketRecvInterface_handler_recv)recv_if_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // init job - BPending_Init(&o->recv.job, BReactor_PendingGroup(o->reactor), (BPending_handler)recv_job_handler, o); - - // set have no data - o->recv.data_have = 0; - - // set inited - o->recv.inited = 1; -} - -void BDatagram_RecvAsync_Free (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - // abort if busy - if (o->recv.data_have && o->recv.data_busy && !o->aborted) { - datagram_abort(o); - } - - // free job - BPending_Free(&o->recv.job); - - // free interface - PacketRecvInterface_Free(&o->recv.iface); - - // set not inited - o->recv.inited = 0; -} - -PacketRecvInterface * BDatagram_RecvAsync_GetIf (BDatagram *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->recv.inited) - - return &o->recv.iface; -} diff --git a/external/badvpn_dns/system/BDatagram_win.h b/external/badvpn_dns/system/BDatagram_win.h deleted file mode 100644 index 9831946..0000000 --- a/external/badvpn_dns/system/BDatagram_win.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file BDatagram_win.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <windows.h> -#include <winsock2.h> -#ifdef BADVPN_USE_SHIPPED_MSWSOCK -# include <misc/mswsock.h> -#else -# include <mswsock.h> -#endif - -#include <misc/debugerror.h> -#include <base/DebugObject.h> - -struct BDatagram_sys_addr { - int len; - union { - struct sockaddr generic; - struct sockaddr_in ipv4; - struct sockaddr_in6 ipv6; - } addr; -}; - -struct BDatagram_s { - BReactor *reactor; - void *user; - BDatagram_handler handler; - SOCKET sock; - LPFN_WSASENDMSG fnWSASendMsg; - LPFN_WSARECVMSG fnWSARecvMsg; - int aborted; - struct { - BReactorIOCPOverlapped olap; - int have_addrs; - BAddr remote_addr; - BIPAddr local_addr; - int inited; - int mtu; - PacketPassInterface iface; - BPending job; - int data_len; - uint8_t *data; - int data_busy; - struct BDatagram_sys_addr sysaddr; - union { - char in[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))]; - char in6[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))]; - } cdata; - WSAMSG msg; - } send; - struct { - BReactorIOCPOverlapped olap; - int started; - int have_addrs; - BAddr remote_addr; - BIPAddr local_addr; - int inited; - int mtu; - PacketRecvInterface iface; - BPending job; - int data_have; - uint8_t *data; - int data_busy; - struct BDatagram_sys_addr sysaddr; - union { - char in[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))]; - char in6[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))]; - } cdata; - WSAMSG msg; - } recv; - DebugError d_err; - DebugObject d_obj; -}; diff --git a/external/badvpn_dns/system/BInputProcess.c b/external/badvpn_dns/system/BInputProcess.c deleted file mode 100644 index b3d096a..0000000 --- a/external/badvpn_dns/system/BInputProcess.c +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @file BInputProcess.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <unistd.h> - -#include <base/BLog.h> -#include <system/BNetwork.h> - -#include "BInputProcess.h" - -#include <generated/blog_channel_BInputProcess.h> - -static void connection_handler (BInputProcess *o, int event); -static void process_handler (BInputProcess *o, int normally, uint8_t normally_exit_status); - -void connection_handler (BInputProcess *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pipe_fd >= 0) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - BLog(BLOG_INFO, "pipe closed"); - } else { - BLog(BLOG_ERROR, "pipe error"); - } - - // free pipe connection read interface - BConnection_RecvAsync_Free(&o->pipe_con); - - // free pipe connection - BConnection_Free(&o->pipe_con); - - // close pipe read end - ASSERT_FORCE(close(o->pipe_fd) == 0) - - // forget pipe - o->pipe_fd = -1; - - // call closed handler - o->handler_closed(o->user, (event != BCONNECTION_EVENT_RECVCLOSED)); - return; -} - -void process_handler (BInputProcess *o, int normally, uint8_t normally_exit_status) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->started) - ASSERT(o->have_process) - - // free process - BProcess_Free(&o->process); - - // set not have process - o->have_process = 0; - - // call terminated handler - o->handler_terminated(o->user, normally, normally_exit_status); - return; -} - -int BInputProcess_Init (BInputProcess *o, BReactor *reactor, BProcessManager *manager, void *user, - BInputProcess_handler_terminated handler_terminated, - BInputProcess_handler_closed handler_closed) -{ - BNetwork_Assert(); - - // init arguments - o->reactor = reactor; - o->manager = manager; - o->user = user; - o->handler_terminated = handler_terminated; - o->handler_closed = handler_closed; - - // create pipe - int pipefds[2]; - if (pipe(pipefds) < 0) { - BLog(BLOG_ERROR, "pipe failed"); - goto fail0; - } - - // init pipe connection - if (!BConnection_Init(&o->pipe_con, BConnection_source_pipe(pipefds[0]), o->reactor, o, (BConnection_handler)connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // init pipe connection read interface - BConnection_RecvAsync_Init(&o->pipe_con); - - // remember pipe fds - o->pipe_fd = pipefds[0]; - o->pipe_write_fd = pipefds[1]; - - // set not started - o->started = 0; - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - ASSERT_FORCE(close(pipefds[0]) == 0) - ASSERT_FORCE(close(pipefds[1]) == 0) -fail0: - return 0; -} - -void BInputProcess_Free (BInputProcess *o) -{ - DebugObject_Free(&o->d_obj); - - if (!o->started) { - // close pipe write end - ASSERT_FORCE(close(o->pipe_write_fd) == 0) - } else { - // free process - if (o->have_process) { - BProcess_Free(&o->process); - } - } - - if (o->pipe_fd >= 0) { - // free pipe connection read interface - BConnection_RecvAsync_Free(&o->pipe_con); - - // free pipe connection - BConnection_Free(&o->pipe_con); - - // close pipe read end - ASSERT_FORCE(close(o->pipe_fd) == 0) - } -} - -int BInputProcess_Start (BInputProcess *o, const char *file, char *const argv[], const char *username) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->started) - - // start process - int fds[] = { o->pipe_write_fd, -1 }; - int fds_map[] = { 1 }; - if (!BProcess_InitWithFds(&o->process, o->manager, (BProcess_handler)process_handler, o, file, argv, username, fds, fds_map)) { - BLog(BLOG_ERROR, "BProcess_Init failed"); - goto fail0; - } - - // close pipe write end - ASSERT_FORCE(close(o->pipe_write_fd) == 0) - - // set started - o->started = 1; - - // set have process - o->have_process = 1; - - return 1; - -fail0: - return 0; -} - -int BInputProcess_Terminate (BInputProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->started) - ASSERT(o->have_process) - - return BProcess_Terminate(&o->process); -} - -int BInputProcess_Kill (BInputProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->started) - ASSERT(o->have_process) - - return BProcess_Kill(&o->process); -} - -StreamRecvInterface * BInputProcess_GetInput (BInputProcess *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pipe_fd >= 0) - - return BConnection_RecvAsync_GetIf(&o->pipe_con); -} diff --git a/external/badvpn_dns/system/BInputProcess.h b/external/badvpn_dns/system/BInputProcess.h deleted file mode 100644 index 7317a5d..0000000 --- a/external/badvpn_dns/system/BInputProcess.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file BInputProcess.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BINPUTPROCESS_H -#define BADVPN_BINPUTPROCESS_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BConnection.h> -#include <system/BProcess.h> - -typedef void (*BInputProcess_handler_terminated) (void *user, int normally, uint8_t normally_exit_status); -typedef void (*BInputProcess_handler_closed) (void *user, int is_error); - -typedef struct { - BReactor *reactor; - BProcessManager *manager; - void *user; - BInputProcess_handler_terminated handler_terminated; - BInputProcess_handler_closed handler_closed; - int pipe_write_fd; - int started; - int have_process; - BProcess process; - int pipe_fd; - BConnection pipe_con; - DebugObject d_obj; -} BInputProcess; - -int BInputProcess_Init (BInputProcess *o, BReactor *reactor, BProcessManager *manager, void *user, - BInputProcess_handler_terminated handler_terminated, - BInputProcess_handler_closed handler_closed) WARN_UNUSED; -void BInputProcess_Free (BInputProcess *o); -int BInputProcess_Start (BInputProcess *o, const char *file, char *const argv[], const char *username); -int BInputProcess_Terminate (BInputProcess *o); -int BInputProcess_Kill (BInputProcess *o); -StreamRecvInterface * BInputProcess_GetInput (BInputProcess *o); - -#endif diff --git a/external/badvpn_dns/system/BLockReactor.c b/external/badvpn_dns/system/BLockReactor.c deleted file mode 100644 index e9a2724..0000000 --- a/external/badvpn_dns/system/BLockReactor.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file BLockReactor.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> -#include <misc/offset.h> -#include <base/BLog.h> - -#include "BLockReactor.h" - -#include <generated/blog_channel_BLockReactor.h> - -static void thread_signal_handler (BThreadSignal *thread_signal) -{ - BLockReactor *o = UPPER_OBJECT(thread_signal, BLockReactor, thread_signal); - DebugObject_Access(&o->d_obj); - - ASSERT_FORCE(sem_post(&o->sem1) == 0) - ASSERT_FORCE(sem_wait(&o->sem2) == 0) -} - -int BLockReactor_Init (BLockReactor *o, BReactor *reactor) -{ - o->reactor = reactor; - - if (!BThreadSignal_Init(&o->thread_signal, reactor, thread_signal_handler)) { - BLog(BLOG_ERROR, "BThreadSignal_Init failed"); - goto fail0; - } - - if (sem_init(&o->sem1, 0, 0) < 0) { - BLog(BLOG_ERROR, "sem_init failed"); - goto fail1; - } - - if (sem_init(&o->sem2, 0, 0) < 0) { - BLog(BLOG_ERROR, "sem_init failed"); - goto fail2; - } - -#ifndef NDEBUG - o->locked = 0; -#endif - - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - if (sem_close(&o->sem1) < 0) { - BLog(BLOG_ERROR, "sem_close failed"); - } -fail1: - BThreadSignal_Free(&o->thread_signal); -fail0: - return 0; -} - -void BLockReactor_Free (BLockReactor *o) -{ - DebugObject_Free(&o->d_obj); -#ifndef NDEBUG - ASSERT(!o->locked) -#endif - - if (sem_destroy(&o->sem2) < 0) { - BLog(BLOG_ERROR, "sem_close failed"); - } - if (sem_destroy(&o->sem1) < 0) { - BLog(BLOG_ERROR, "sem_close failed"); - } - BThreadSignal_Free(&o->thread_signal); -} - -int BLockReactor_Thread_Lock (BLockReactor *o) -{ - DebugObject_Access(&o->d_obj); -#ifndef NDEBUG - ASSERT(!o->locked) -#endif - - if (!BThreadSignal_Thread_Signal(&o->thread_signal)) { - return 0; - } - - ASSERT_FORCE(sem_wait(&o->sem1) == 0) - -#ifndef NDEBUG - o->locked = 1; -#endif - - return 1; -} - -void BLockReactor_Thread_Unlock (BLockReactor *o) -{ - DebugObject_Access(&o->d_obj); -#ifndef NDEBUG - ASSERT(o->locked) -#endif - -#ifndef NDEBUG - o->locked = 0; -#endif - - ASSERT_FORCE(sem_post(&o->sem2) == 0) -} diff --git a/external/badvpn_dns/system/BLockReactor.h b/external/badvpn_dns/system/BLockReactor.h deleted file mode 100644 index 84acab8..0000000 --- a/external/badvpn_dns/system/BLockReactor.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file BLockReactor.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_B_LOCK_REACTOR_H -#define BADVPN_B_LOCK_REACTOR_H - -#include <semaphore.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <system/BThreadSignal.h> - -typedef struct BLockReactor_s BLockReactor; - -struct BLockReactor_s { - BReactor *reactor; - BThreadSignal thread_signal; - sem_t sem1; - sem_t sem2; -#ifndef NDEBUG - int locked; -#endif - DebugObject d_obj; -}; - -int BLockReactor_Init (BLockReactor *o, BReactor *reactor) WARN_UNUSED; -void BLockReactor_Free (BLockReactor *o); -int BLockReactor_Thread_Lock (BLockReactor *o); -void BLockReactor_Thread_Unlock (BLockReactor *o); - -#endif diff --git a/external/badvpn_dns/system/BNetwork.c b/external/badvpn_dns/system/BNetwork.c deleted file mode 100644 index b48ae61..0000000 --- a/external/badvpn_dns/system/BNetwork.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file BNetwork.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef BADVPN_USE_WINAPI -#include <windows.h> -#include <winsock2.h> -#include <mswsock.h> -#else -#include <string.h> -#include <signal.h> -#endif - -#include <misc/debug.h> -#include <base/BLog.h> - -#include <system/BNetwork.h> - -#include <generated/blog_channel_BNetwork.h> - -extern int bnetwork_initialized; - -#ifndef BADVPN_PLUGIN -int bnetwork_initialized = 0; -#endif - -int BNetwork_GlobalInit (void) -{ - ASSERT(!bnetwork_initialized) - -#ifdef BADVPN_USE_WINAPI - - WORD requested = MAKEWORD(2, 2); - WSADATA wsadata; - if (WSAStartup(requested, &wsadata) != 0) { - BLog(BLOG_ERROR, "WSAStartup failed"); - goto fail0; - } - if (wsadata.wVersion != requested) { - BLog(BLOG_ERROR, "WSAStartup returned wrong version"); - goto fail1; - } - -#else - - struct sigaction act; - memset(&act, 0, sizeof(act)); - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - if (sigaction(SIGPIPE, &act, NULL) < 0) { - BLog(BLOG_ERROR, "sigaction failed"); - goto fail0; - } - -#endif - - bnetwork_initialized = 1; - - return 1; - -#ifdef BADVPN_USE_WINAPI -fail1: - WSACleanup(); -#endif - -fail0: - return 0; -} - -void BNetwork_Assert (void) -{ - ASSERT(bnetwork_initialized) -} diff --git a/external/badvpn_dns/system/BNetwork.h b/external/badvpn_dns/system/BNetwork.h deleted file mode 100644 index 0db1744..0000000 --- a/external/badvpn_dns/system/BNetwork.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file BNetwork.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SYSTEM_BNETWORK_H -#define BADVPN_SYSTEM_BNETWORK_H - -int BNetwork_GlobalInit (void); -void BNetwork_Assert (void); - -#endif diff --git a/external/badvpn_dns/system/BProcess.c b/external/badvpn_dns/system/BProcess.c deleted file mode 100644 index 7efea25..0000000 --- a/external/badvpn_dns/system/BProcess.c +++ /dev/null @@ -1,400 +0,0 @@ -/** - * @file BProcess.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <string.h> -#include <inttypes.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <signal.h> -#include <grp.h> -#include <pwd.h> -#include <errno.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <misc/offset.h> -#include <misc/open_standard_streams.h> -#include <base/BLog.h> - -#include "BProcess.h" - -#include <generated/blog_channel_BProcess.h> - -static void call_handler (BProcess *o, int normally, uint8_t normally_exit_status) -{ - DEBUGERROR(&o->d_err, o->handler(o->user, normally, normally_exit_status)) -} - -static BProcess * find_process (BProcessManager *o, pid_t pid) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->processes); node; node = LinkedList1Node_Next(node)) { - BProcess *p = UPPER_OBJECT(node, BProcess, list_node); - if (p->pid == pid) { - return p; - } - } - - return NULL; -} - -static void work_signals (BProcessManager *o) -{ - // read exit status with waitpid() - int status; - pid_t pid = waitpid(-1, &status, WNOHANG); - if (pid <= 0) { - return; - } - - // schedule next waitpid - BPending_Set(&o->wait_job); - - // find process - BProcess *p = find_process(o, pid); - if (!p) { - BLog(BLOG_DEBUG, "unknown child %p"); - } - - if (WIFEXITED(status)) { - uint8_t exit_status = WEXITSTATUS(status); - - BLog(BLOG_INFO, "child %"PRIiMAX" exited with status %"PRIu8, (intmax_t)pid, exit_status); - - if (p) { - call_handler(p, 1, exit_status); - return; - } - } - else if (WIFSIGNALED(status)) { - int signo = WTERMSIG(status); - - BLog(BLOG_INFO, "child %"PRIiMAX" exited with signal %d", (intmax_t)pid, signo); - - if (p) { - call_handler(p, 0, 0); - return; - } - } - else { - BLog(BLOG_ERROR, "unknown wait status type for pid %"PRIiMAX" (%d)", (intmax_t)pid, status); - } -} - -static void wait_job_handler (BProcessManager *o) -{ - DebugObject_Access(&o->d_obj); - - work_signals(o); - return; -} - -static void signal_handler (BProcessManager *o, int signo) -{ - ASSERT(signo == SIGCHLD) - DebugObject_Access(&o->d_obj); - - work_signals(o); - return; -} - -int BProcessManager_Init (BProcessManager *o, BReactor *reactor) -{ - // init arguments - o->reactor = reactor; - - // init signal handling - sigset_t sset; - ASSERT_FORCE(sigemptyset(&sset) == 0) - ASSERT_FORCE(sigaddset(&sset, SIGCHLD) == 0) - if (!BUnixSignal_Init(&o->signal, o->reactor, sset, (BUnixSignal_handler)signal_handler, o)) { - BLog(BLOG_ERROR, "BUnixSignal_Init failed"); - goto fail0; - } - - // init processes list - LinkedList1_Init(&o->processes); - - // init wait job - BPending_Init(&o->wait_job, BReactor_PendingGroup(o->reactor), (BPending_handler)wait_job_handler, o); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - return 0; -} - -void BProcessManager_Free (BProcessManager *o) -{ - ASSERT(LinkedList1_IsEmpty(&o->processes)) - DebugObject_Free(&o->d_obj); - - // free wait job - BPending_Free(&o->wait_job); - - // free signal handling - BUnixSignal_Free(&o->signal, 1); -} - -static int fds_contains (const int *fds, int fd, size_t *pos) -{ - for (size_t i = 0; fds[i] >= 0; i++) { - if (fds[i] == fd) { - if (pos) { - *pos = i; - } - - return 1; - } - } - - return 0; -} - -int BProcess_Init2 (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], struct BProcess_params params) -{ - // init arguments - o->m = m; - o->handler = handler; - o->user = user; - - // count fds - size_t num_fds; - for (num_fds = 0; params.fds[num_fds] >= 0; num_fds++); - - // block signals - // needed to prevent parent's signal handlers from being called - // in the child - sigset_t sset_all; - sigfillset(&sset_all); - sigset_t sset_old; - if (sigprocmask(SIG_SETMASK, &sset_all, &sset_old) < 0) { - BLog(BLOG_ERROR, "sigprocmask failed"); - goto fail0; - } - - // fork - pid_t pid = fork(); - - if (pid == 0) { - // this is child - - // restore signal dispositions - for (int i = 1; i < NSIG; i++) { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sa.sa_flags = 0; - sigaction(i, &sa, NULL); - } - - // unblock signals - sigset_t sset_none; - sigemptyset(&sset_none); - if (sigprocmask(SIG_SETMASK, &sset_none, NULL) < 0) { - abort(); - } - - // copy fds array - int *fds2 = malloc((num_fds + 1) * sizeof(fds2[0])); - if (!fds2) { - abort(); - } - memcpy(fds2, params.fds, (num_fds + 1) * sizeof(fds2[0])); - - // find maximum file descriptors - int max_fd = sysconf(_SC_OPEN_MAX); - if (max_fd < 0) { - abort(); - } - - // close file descriptors - for (int i = 0; i < max_fd; i++) { - // if it's one of the given fds, don't close it - if (fds_contains(fds2, i, NULL)) { - continue; - } - - close(i); - } - - // map fds to requested fd numbers - while (*fds2 >= 0) { - // resolve possible conflict - size_t cpos; - if (fds_contains(fds2 + 1, *params.fds_map, &cpos)) { - // dup() the fd to a new number; the old one will be closed - // in the following dup2() - if ((fds2[1 + cpos] = dup(fds2[1 + cpos])) < 0) { - abort(); - } - } - - if (*fds2 != *params.fds_map) { - // dup fd - if (dup2(*fds2, *params.fds_map) < 0) { - abort(); - } - - // close original fd - close(*fds2); - } - - fds2++; - params.fds_map++; - } - - // make sure standard streams are open - open_standard_streams(); - - // make session leader if requested - if (params.do_setsid) { - setsid(); - } - - // assume identity of username, if requested - if (params.username) { - long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize < 0) { - bufsize = 16384; - } - - char *buf = malloc(bufsize); - if (!buf) { - abort(); - } - - struct passwd pwd; - struct passwd *res; - getpwnam_r(params.username, &pwd, buf, bufsize, &res); - if (!res) { - abort(); - } - - if (initgroups(params.username, pwd.pw_gid) < 0) { - abort(); - } - - if (setgid(pwd.pw_gid) < 0) { - abort(); - } - - if (setuid(pwd.pw_uid) < 0) { - abort(); - } - } - - execv(file, argv); - - abort(); - } - - // restore original signal mask - ASSERT_FORCE(sigprocmask(SIG_SETMASK, &sset_old, NULL) == 0) - - if (pid < 0) { - BLog(BLOG_ERROR, "fork failed"); - goto fail0; - } - - // remember pid - o->pid = pid; - - // add to processes list - LinkedList1_Append(&o->m->processes, &o->list_node); - - DebugObject_Init(&o->d_obj); - DebugError_Init(&o->d_err, BReactor_PendingGroup(m->reactor)); - - return 1; - -fail0: - return 0; -} - -int BProcess_InitWithFds (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], const char *username, const int *fds, const int *fds_map) -{ - struct BProcess_params params; - params.username = username; - params.fds = fds; - params.fds_map = fds_map; - params.do_setsid = 0; - - return BProcess_Init2(o, m, handler, user, file, argv, params); -} - -int BProcess_Init (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], const char *username) -{ - int fds[] = {-1}; - - return BProcess_InitWithFds(o, m, handler, user, file, argv, username, fds, NULL); -} - -void BProcess_Free (BProcess *o) -{ - DebugError_Free(&o->d_err); - DebugObject_Free(&o->d_obj); - - // remove from processes list - LinkedList1_Remove(&o->m->processes, &o->list_node); -} - -int BProcess_Terminate (BProcess *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - ASSERT(o->pid > 0) - - if (kill(o->pid, SIGTERM) < 0) { - BLog(BLOG_ERROR, "kill(%"PRIiMAX", SIGTERM) failed", (intmax_t)o->pid); - return 0; - } - - return 1; -} - -int BProcess_Kill (BProcess *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - ASSERT(o->pid > 0) - - if (kill(o->pid, SIGKILL) < 0) { - BLog(BLOG_ERROR, "kill(%"PRIiMAX", SIGKILL) failed", (intmax_t)o->pid); - return 0; - } - - return 1; -} diff --git a/external/badvpn_dns/system/BProcess.h b/external/badvpn_dns/system/BProcess.h deleted file mode 100644 index 35993fe..0000000 --- a/external/badvpn_dns/system/BProcess.h +++ /dev/null @@ -1,200 +0,0 @@ -/** - * @file BProcess.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BPROCESS_H -#define BADVPN_BPROCESS_H - -#include <stdint.h> -#include <unistd.h> - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <system/BUnixSignal.h> -#include <base/BPending.h> - -/** - * Manages child processes. - * There may be at most one process manager at any given time. This restriction is not - * enforced, however. - */ -typedef struct { - BReactor *reactor; - BUnixSignal signal; - LinkedList1 processes; - BPending wait_job; - DebugObject d_obj; -} BProcessManager; - -/** - * Handler called when the process terminates. - * The process object must be freed from the job context of this handler. - * {@link BProcess_Terminate} or {@link BProcess_Kill} must not be called - * after this handler is called. - * - * @param user as in {@link BProcess_InitWithFds} or {@link BProcess_Init} - * @param normally whether the child process terminated normally (0 or 1) - * @param normally_exit_status if the child process terminated normally, its exit - * status; otherwise undefined - */ -typedef void (*BProcess_handler) (void *user, int normally, uint8_t normally_exit_status); - -/** - * Represents a child process. - */ -typedef struct { - BProcessManager *m; - BProcess_handler handler; - void *user; - pid_t pid; - LinkedList1Node list_node; // node in BProcessManager.processes - DebugObject d_obj; - DebugError d_err; -} BProcess; - -/** - * Initializes the process manager. - * There may be at most one process manager at any given time. This restriction is not - * enforced, however. - * - * @param o the object - * @param reactor reactor we live in - * @return 1 on success, 0 on failure - */ -int BProcessManager_Init (BProcessManager *o, BReactor *reactor) WARN_UNUSED; - -/** - * Frees the process manager. - * There must be no {@link BProcess} objects using this process manager. - * - * @param o the object - */ -void BProcessManager_Free (BProcessManager *o); - -struct BProcess_params { - const char *username; - const int *fds; - const int *fds_map; - int do_setsid; -}; - -/** - * Initializes the process. - * 'file', 'argv', 'username', 'fds' and 'fds_map' arguments are only used during this - * function call. - * If no file descriptor is mapped to a standard stream (file descriptors 0, 1, 2), - * then /dev/null will be opened in the child for that standard stream. - * - * @param o the object - * @param m process manager - * @param handler handler called when the process terminates - * @param user argument to handler - * @param file path to executable file - * @param argv arguments array, including the zeroth argument, terminated with a NULL pointer - * @param params.username user account to run the program as, or NULL to not switch user - * @param params.fds array of file descriptors in the parent to map to file descriptors in the child, - * terminated with -1 - * @param params.fds_map array of file descriptors in the child that file descriptors in 'fds' will - * be mapped to, in the same order. Must contain the same number of file descriptors - * as the 'fds' argument, and does not have to be terminated with -1. - * @param params.do_setsid if set to non-zero, will make the child call setsid() before exec'ing. - * Failure of setsid() will be ignored. - * @return 1 on success, 0 on failure - */ -int BProcess_Init2 (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], struct BProcess_params params) WARN_UNUSED; - -/** - * Initializes the process. - * 'file', 'argv', 'username', 'fds' and 'fds_map' arguments are only used during this - * function call. - * If no file descriptor is mapped to a standard stream (file descriptors 0, 1, 2), - * then /dev/null will be opened in the child for that standard stream. - * - * @param o the object - * @param m process manager - * @param handler handler called when the process terminates - * @param user argument to handler - * @param file path to executable file - * @param argv arguments array, including the zeroth argument, terminated with a NULL pointer - * @param username user account to run the program as, or NULL to not switch user - * @param fds array of file descriptors in the parent to map to file descriptors in the child, - * terminated with -1 - * @param fds_map array of file descriptors in the child that file descriptors in 'fds' will - * be mapped to, in the same order. Must contain the same number of file descriptors - * as the 'fds' argument, and does not have to be terminated with -1. - * @return 1 on success, 0 on failure - */ -int BProcess_InitWithFds (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], const char *username, const int *fds, const int *fds_map) WARN_UNUSED; - -/** - * Initializes the process. - * Like {@link BProcess_InitWithFds}, but without file descriptor mapping. - * 'file', 'argv' and 'username' arguments are only used during this function call. - * - * @param o the object - * @param m process manager - * @param handler handler called when the process terminates - * @param user argument to handler - * @param file path to executable file - * @param argv arguments array, including the zeroth argument, terminated with a NULL pointer - * @param username user account to run the program as, or NULL to not switch user - * @return 1 on success, 0 on failure - */ -int BProcess_Init (BProcess *o, BProcessManager *m, BProcess_handler handler, void *user, const char *file, char *const argv[], const char *username) WARN_UNUSED; - -/** - * Frees the process. - * This does not do anything with the actual child process; it only prevents the user to wait - * for its termination. If the process terminates while a process manager is running, it will still - * be waited for (and will not become a zombie). - * - * @param o the object - */ -void BProcess_Free (BProcess *o); - -/** - * Sends the process the SIGTERM signal. - * Success of this action does NOT mean that the child has terminated. - * - * @param o the object - * @return 1 on success, 0 on failure - */ -int BProcess_Terminate (BProcess *o); - -/** - * Sends the process the SIGKILL signal. - * Success of this action does NOT mean that the child has terminated. - * - * @param o the object - * @return 1 on success, 0 on failure - */ -int BProcess_Kill (BProcess *o); - -#endif diff --git a/external/badvpn_dns/system/BReactor.h b/external/badvpn_dns/system/BReactor.h deleted file mode 100644 index 4c0fa5b..0000000 --- a/external/badvpn_dns/system/BReactor.h +++ /dev/null @@ -1,11 +0,0 @@ -#if defined(BADVPN_BREACTOR_BADVPN) + defined(BADVPN_BREACTOR_GLIB) + defined(BADVPN_BREACTOR_EMSCRIPTEN) != 1 -#error No reactor backend or too many reactor backens -#endif - -#if defined(BADVPN_BREACTOR_BADVPN) -#include "BReactor_badvpn.h" -#elif defined(BADVPN_BREACTOR_GLIB) -#include "BReactor_glib.h" -#elif defined(BADVPN_BREACTOR_EMSCRIPTEN) -#include "BReactor_emscripten.h" -#endif diff --git a/external/badvpn_dns/system/BReactor_badvpn.c b/external/badvpn_dns/system/BReactor_badvpn.c deleted file mode 100644 index 1b03d58..0000000 --- a/external/badvpn_dns/system/BReactor_badvpn.c +++ /dev/null @@ -1,1430 +0,0 @@ -/** - * @file BReactor_badvpn.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stddef.h> - -#ifdef BADVPN_USE_WINAPI -#include <windows.h> -#else -#include <limits.h> -#include <sys/types.h> -#include <errno.h> -#include <unistd.h> -#endif - -#include <misc/debug.h> -#include <misc/offset.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <base/BLog.h> - -#include <system/BReactor.h> - -#include <generated/blog_channel_BReactor.h> - -#define KEVENT_TAG_FD 1 -#define KEVENT_TAG_KEVENT 2 - -#define TIMER_STATE_INACTIVE 1 -#define TIMER_STATE_RUNNING 2 -#define TIMER_STATE_EXPIRED 3 - -static int compare_timers (BSmallTimer *t1, BSmallTimer *t2) -{ - int cmp = B_COMPARE(t1->absTime, t2->absTime); - if (cmp) { - return cmp; - } - - return B_COMPARE((uintptr_t)t1, (uintptr_t)t2); -} - -#include "BReactor_badvpn_timerstree.h" -#include <structure/CAvl_impl.h> - -static void assert_timer (BSmallTimer *bt) -{ - ASSERT(bt->state == TIMER_STATE_INACTIVE || bt->state == TIMER_STATE_RUNNING || - bt->state == TIMER_STATE_EXPIRED) -} - -static int move_expired_timers (BReactor *bsys, btime_t now) -{ - int moved = 0; - - // move timed out timers to the expired list - BReactor__TimersTreeRef ref; - BSmallTimer *timer; - while (timer = (ref = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0)).link) { - ASSERT(timer->state == TIMER_STATE_RUNNING) - - // if it's in the future, stop - if (timer->absTime > now) { - break; - } - moved = 1; - - // remove from running timers tree - BReactor__TimersTree_Remove(&bsys->timers_tree, 0, ref); - - // add to expired timers list - LinkedList1_Append(&bsys->timers_expired_list, &timer->u.list_node); - - // set expired - timer->state = TIMER_STATE_EXPIRED; - } - - return moved; -} - -static void move_first_timers (BReactor *bsys) -{ - BReactor__TimersTreeRef ref; - - // get the time of the first timer - BSmallTimer *first_timer = (ref = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0)).link; - ASSERT(first_timer) - ASSERT(first_timer->state == TIMER_STATE_RUNNING) - btime_t first_time = first_timer->absTime; - - // remove from running timers tree - BReactor__TimersTree_Remove(&bsys->timers_tree, 0, ref); - - // add to expired timers list - LinkedList1_Append(&bsys->timers_expired_list, &first_timer->u.list_node); - - // set expired - first_timer->state = TIMER_STATE_EXPIRED; - - // also move other timers with the same timeout - BSmallTimer *timer; - while (timer = (ref = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0)).link) { - ASSERT(timer->state == TIMER_STATE_RUNNING) - ASSERT(timer->absTime >= first_time) - - // if it's in the future, stop - if (timer->absTime > first_time) { - break; - } - - // remove from running timers tree - BReactor__TimersTree_Remove(&bsys->timers_tree, 0, ref); - - // add to expired timers list - LinkedList1_Append(&bsys->timers_expired_list, &timer->u.list_node); - - // set expired - timer->state = TIMER_STATE_EXPIRED; - } -} - -#ifdef BADVPN_USE_WINAPI - -static void set_iocp_ready (BReactorIOCPOverlapped *olap, int succeeded, DWORD bytes) -{ - BReactor *reactor = olap->reactor; - ASSERT(!olap->is_ready) - - // set parameters - olap->ready_succeeded = succeeded; - olap->ready_bytes = bytes; - - // insert to IOCP ready list - LinkedList1_Append(&reactor->iocp_ready_list, &olap->ready_list_node); - - // set ready - olap->is_ready = 1; -} - -#endif - -#ifdef BADVPN_USE_EPOLL - -static void set_epoll_fd_pointers (BReactor *bsys) -{ - // Write pointers to our entry pointers into file descriptors. - // If a handler function frees some other file descriptor, the - // free routine will set our pointer to NULL so we don't dispatch it. - for (int i = 0; i < bsys->epoll_results_num; i++) { - struct epoll_event *event = &bsys->epoll_results[i]; - ASSERT(event->data.ptr) - BFileDescriptor *bfd = (BFileDescriptor *)event->data.ptr; - ASSERT(bfd->active) - ASSERT(!bfd->epoll_returned_ptr) - bfd->epoll_returned_ptr = (BFileDescriptor **)&event->data.ptr; - } -} - -#endif - -#ifdef BADVPN_USE_KEVENT - -static void set_kevent_fd_pointers (BReactor *bsys) -{ - for (int i = 0; i < bsys->kevent_results_num; i++) { - struct kevent *event = &bsys->kevent_results[i]; - ASSERT(event->udata) - int *tag = event->udata; - switch (*tag) { - case KEVENT_TAG_FD: { - BFileDescriptor *bfd = UPPER_OBJECT(tag, BFileDescriptor, kevent_tag); - ASSERT(bfd->active) - ASSERT(!bfd->kevent_returned_ptr) - bfd->kevent_returned_ptr = (int **)&event->udata; - } break; - - case KEVENT_TAG_KEVENT: { - BReactorKEvent *kev = UPPER_OBJECT(tag, BReactorKEvent, kevent_tag); - ASSERT(kev->reactor == bsys) - ASSERT(!kev->kevent_returned_ptr) - kev->kevent_returned_ptr = (int **)&event->udata; - } break; - - default: - ASSERT(0); - } - } -} - -static void update_kevent_fd_events (BReactor *bsys, BFileDescriptor *bs, int events) -{ - struct kevent event; - - if (!(bs->waitEvents & BREACTOR_READ) && (events & BREACTOR_READ)) { - memset(&event, 0, sizeof(event)); - event.ident = bs->fd; - event.filter = EVFILT_READ; - event.flags = EV_ADD; - event.udata = &bs->kevent_tag; - ASSERT_FORCE(kevent(bsys->kqueue_fd, &event, 1, NULL, 0, NULL) == 0) - } - else if ((bs->waitEvents & BREACTOR_READ) && !(events & BREACTOR_READ)) { - memset(&event, 0, sizeof(event)); - event.ident = bs->fd; - event.filter = EVFILT_READ; - event.flags = EV_DELETE; - ASSERT_FORCE(kevent(bsys->kqueue_fd, &event, 1, NULL, 0, NULL) == 0) - } - - if (!(bs->waitEvents & BREACTOR_WRITE) && (events & BREACTOR_WRITE)) { - memset(&event, 0, sizeof(event)); - event.ident = bs->fd; - event.filter = EVFILT_WRITE; - event.flags = EV_ADD; - event.udata = &bs->kevent_tag; - ASSERT_FORCE(kevent(bsys->kqueue_fd, &event, 1, NULL, 0, NULL) == 0) - } - else if ((bs->waitEvents & BREACTOR_WRITE) && !(events & BREACTOR_WRITE)) { - memset(&event, 0, sizeof(event)); - event.ident = bs->fd; - event.filter = EVFILT_WRITE; - event.flags = EV_DELETE; - ASSERT_FORCE(kevent(bsys->kqueue_fd, &event, 1, NULL, 0, NULL) == 0) - } -} - -#endif - -#ifdef BADVPN_USE_POLL - -static void set_poll_fd_pointers (BReactor *bsys) -{ - for (int i = 0; i < bsys->poll_results_num; i++) { - BFileDescriptor *bfd = bsys->poll_results_bfds[i]; - ASSERT(bfd) - ASSERT(bfd->active) - ASSERT(bfd->poll_returned_index == -1) - bfd->poll_returned_index = i; - } -} - -#endif - -static void wait_for_events (BReactor *bsys) -{ - // must have processed all pending events - ASSERT(!BPendingGroup_HasJobs(&bsys->pending_jobs)) - ASSERT(LinkedList1_IsEmpty(&bsys->timers_expired_list)) - #ifdef BADVPN_USE_WINAPI - ASSERT(LinkedList1_IsEmpty(&bsys->iocp_ready_list)) - #endif - #ifdef BADVPN_USE_EPOLL - ASSERT(bsys->epoll_results_pos == bsys->epoll_results_num) - #endif - #ifdef BADVPN_USE_KEVENT - ASSERT(bsys->kevent_results_pos == bsys->kevent_results_num) - #endif - #ifdef BADVPN_USE_POLL - ASSERT(bsys->poll_results_pos == bsys->poll_results_num) - #endif - - // clean up epoll results - #ifdef BADVPN_USE_EPOLL - bsys->epoll_results_num = 0; - bsys->epoll_results_pos = 0; - #endif - - // clean up kevent results - #ifdef BADVPN_USE_KEVENT - bsys->kevent_results_num = 0; - bsys->kevent_results_pos = 0; - #endif - - // clean up poll results - #ifdef BADVPN_USE_POLL - bsys->poll_results_num = 0; - bsys->poll_results_pos = 0; - #endif - - // timeout vars - int have_timeout = 0; - btime_t timeout_abs; - btime_t now = 0; // to remove warning - - // compute timeout - BSmallTimer *first_timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0).link; - if (first_timer) { - ASSERT(first_timer->state == TIMER_STATE_RUNNING) - - // get current time - now = btime_gettime(); - - // if some timers have already timed out, return them immediately - if (move_expired_timers(bsys, now)) { - BLog(BLOG_DEBUG, "Got already expired timers"); - return; - } - - // timeout is first timer, remember absolute time - have_timeout = 1; - timeout_abs = first_timer->absTime; - } - - // wait until the timeout is reached or the file descriptor / handle in ready - while (1) { - // compute timeout - btime_t timeout_rel = 0; // to remove warning - btime_t timeout_rel_trunc = 0; // to remove warning - if (have_timeout) { - timeout_rel = timeout_abs - now; - timeout_rel_trunc = timeout_rel; - } - - // perform wait - - #ifdef BADVPN_USE_WINAPI - - if (have_timeout) { - if (timeout_rel_trunc > INFINITE - 1) { - timeout_rel_trunc = INFINITE - 1; - } - } - - DWORD bytes = 0; - ULONG_PTR key; - BReactorIOCPOverlapped *olap = NULL; - BOOL res = GetQueuedCompletionStatus(bsys->iocp_handle, &bytes, &key, (OVERLAPPED **)&olap, (have_timeout ? timeout_rel_trunc : INFINITE)); - - ASSERT_FORCE(olap || have_timeout) - - if (olap || timeout_rel_trunc == timeout_rel) { - if (olap) { - BLog(BLOG_DEBUG, "GetQueuedCompletionStatus returned event"); - - DebugObject_Access(&olap->d_obj); - ASSERT(olap->reactor == bsys) - ASSERT(!olap->is_ready) - - set_iocp_ready(olap, (res == TRUE), bytes); - } else { - BLog(BLOG_DEBUG, "GetQueuedCompletionStatus timed out"); - move_first_timers(bsys); - } - break; - } - - #endif - - #ifdef BADVPN_USE_EPOLL - - if (have_timeout) { - if (timeout_rel_trunc > INT_MAX) { - timeout_rel_trunc = INT_MAX; - } - } - - BLog(BLOG_DEBUG, "Calling epoll_wait"); - - int waitres = epoll_wait(bsys->efd, bsys->epoll_results, BSYSTEM_MAX_RESULTS, (have_timeout ? timeout_rel_trunc : -1)); - if (waitres < 0) { - int error = errno; - if (error == EINTR) { - BLog(BLOG_DEBUG, "epoll_wait interrupted"); - goto try_again; - } - perror("epoll_wait"); - ASSERT_FORCE(0) - } - - ASSERT_FORCE(!(waitres == 0) || have_timeout) - ASSERT_FORCE(waitres <= BSYSTEM_MAX_RESULTS) - - if (waitres != 0 || timeout_rel_trunc == timeout_rel) { - if (waitres != 0) { - BLog(BLOG_DEBUG, "epoll_wait returned %d file descriptors", waitres); - bsys->epoll_results_num = waitres; - set_epoll_fd_pointers(bsys); - } else { - BLog(BLOG_DEBUG, "epoll_wait timed out"); - move_first_timers(bsys); - } - break; - } - - #endif - - #ifdef BADVPN_USE_KEVENT - - struct timespec ts; - if (have_timeout) { - if (timeout_rel_trunc > 86400000) { - timeout_rel_trunc = 86400000; - } - ts.tv_sec = timeout_rel_trunc / 1000; - ts.tv_nsec = (timeout_rel_trunc % 1000) * 1000000; - } - - BLog(BLOG_DEBUG, "Calling kevent"); - - int waitres = kevent(bsys->kqueue_fd, NULL, 0, bsys->kevent_results, BSYSTEM_MAX_RESULTS, (have_timeout ? &ts : NULL)); - if (waitres < 0) { - int error = errno; - if (error == EINTR) { - BLog(BLOG_DEBUG, "kevent interrupted"); - goto try_again; - } - perror("kevent"); - ASSERT_FORCE(0) - } - - ASSERT_FORCE(!(waitres == 0) || have_timeout) - ASSERT_FORCE(waitres <= BSYSTEM_MAX_RESULTS) - - if (waitres != 0 || timeout_rel_trunc == timeout_rel) { - if (waitres != 0) { - BLog(BLOG_DEBUG, "kevent returned %d events", waitres); - bsys->kevent_results_num = waitres; - set_kevent_fd_pointers(bsys); - } else { - BLog(BLOG_DEBUG, "kevent timed out"); - move_first_timers(bsys); - } - break; - } - - #endif - - #ifdef BADVPN_USE_POLL - - if (have_timeout) { - if (timeout_rel_trunc > INT_MAX) { - timeout_rel_trunc = INT_MAX; - } - } - - ASSERT(bsys->poll_num_enabled_fds >= 0) - ASSERT(bsys->poll_num_enabled_fds <= BSYSTEM_MAX_POLL_FDS) - int num_fds = 0; - - LinkedList1Node *list_node = LinkedList1_GetFirst(&bsys->poll_enabled_fds_list); - while (list_node) { - BFileDescriptor *bfd = UPPER_OBJECT(list_node, BFileDescriptor, poll_enabled_fds_list_node); - ASSERT(bfd->active) - ASSERT(bfd->poll_returned_index == -1) - - // calculate poll events - int pevents = 0; - if ((bfd->waitEvents & BREACTOR_READ)) { - pevents |= POLLIN; - } - if ((bfd->waitEvents & BREACTOR_WRITE)) { - pevents |= POLLOUT; - } - - // write pollfd entry - struct pollfd *pfd = &bsys->poll_results_pollfds[num_fds]; - pfd->fd = bfd->fd; - pfd->events = pevents; - pfd->revents = 0; - - // write BFileDescriptor reference entry - bsys->poll_results_bfds[num_fds] = bfd; - - // increment number of fds in array - num_fds++; - - list_node = LinkedList1Node_Next(list_node); - } - - BLog(BLOG_DEBUG, "Calling poll"); - - int waitres = poll(bsys->poll_results_pollfds, num_fds, (have_timeout ? timeout_rel_trunc : -1)); - if (waitres < 0) { - int error = errno; - if (error == EINTR) { - BLog(BLOG_DEBUG, "poll interrupted"); - goto try_again; - } - perror("poll"); - ASSERT_FORCE(0) - } - - ASSERT_FORCE(!(waitres == 0) || have_timeout) - - if (waitres != 0 || timeout_rel_trunc == timeout_rel) { - if (waitres != 0) { - BLog(BLOG_DEBUG, "poll returned %d file descriptors", waitres); - bsys->poll_results_num = num_fds; - bsys->poll_results_pos = 0; - set_poll_fd_pointers(bsys); - } else { - BLog(BLOG_DEBUG, "poll timed out"); - move_first_timers(bsys); - } - break; - } - - #endif - - try_again: - if (have_timeout) { - // get current time - now = btime_gettime(); - // check if we already reached the time we're waiting for - if (now >= timeout_abs) { - BLog(BLOG_DEBUG, "already timed out while trying again"); - move_first_timers(bsys); - break; - } - } - } - - // reset limit objects - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&bsys->active_limits_list)) { - BReactorLimit *limit = UPPER_OBJECT(list_node, BReactorLimit, active_limits_list_node); - ASSERT(limit->count > 0) - limit->count = 0; - LinkedList1_Remove(&bsys->active_limits_list, &limit->active_limits_list_node); - } -} - -#ifndef BADVPN_USE_WINAPI - -void BFileDescriptor_Init (BFileDescriptor *bs, int fd, BFileDescriptor_handler handler, void *user) -{ - bs->fd = fd; - bs->handler = handler; - bs->user = user; - bs->active = 0; -} - -#endif - -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler) -{ - bt->handler.smalll = handler; - bt->state = TIMER_STATE_INACTIVE; - bt->is_small = 1; -} - -int BSmallTimer_IsRunning (BSmallTimer *bt) -{ - assert_timer(bt); - - return (bt->state != TIMER_STATE_INACTIVE); -} - -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user) -{ - bt->base.handler.heavy = handler; - bt->base.state = TIMER_STATE_INACTIVE; - bt->base.is_small = 0; - bt->user = user; - bt->msTime = msTime; -} - -int BTimer_IsRunning (BTimer *bt) -{ - return BSmallTimer_IsRunning(&bt->base); -} - -int BReactor_Init (BReactor *bsys) -{ - BLog(BLOG_DEBUG, "Reactor initializing"); - - // set not exiting - bsys->exiting = 0; - - // init jobs - BPendingGroup_Init(&bsys->pending_jobs); - - // init timers - BReactor__TimersTree_Init(&bsys->timers_tree); - LinkedList1_Init(&bsys->timers_expired_list); - - // init limits - LinkedList1_Init(&bsys->active_limits_list); - - #ifdef BADVPN_USE_WINAPI - - // init IOCP list - LinkedList1_Init(&bsys->iocp_list); - - // init IOCP handle - if (!(bsys->iocp_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1))) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail0; - } - - // init IOCP ready list - LinkedList1_Init(&bsys->iocp_ready_list); - - #endif - - #ifdef BADVPN_USE_EPOLL - - // create epoll fd - if ((bsys->efd = epoll_create(10)) < 0) { - BLog(BLOG_ERROR, "epoll_create failed"); - goto fail0; - } - - // init results array - bsys->epoll_results_num = 0; - bsys->epoll_results_pos = 0; - - #endif - - #ifdef BADVPN_USE_KEVENT - - // create kqueue fd - if ((bsys->kqueue_fd = kqueue()) < 0) { - BLog(BLOG_ERROR, "kqueue failed"); - goto fail0; - } - - // init results array - bsys->kevent_results_num = 0; - bsys->kevent_results_pos = 0; - - #endif - - #ifdef BADVPN_USE_POLL - - // init enabled fds list - LinkedList1_Init(&bsys->poll_enabled_fds_list); - - // set zero enabled fds - bsys->poll_num_enabled_fds = 0; - - // allocate results arrays - if (!(bsys->poll_results_pollfds = BAllocArray(BSYSTEM_MAX_POLL_FDS, sizeof(bsys->poll_results_pollfds[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - if (!(bsys->poll_results_bfds = BAllocArray(BSYSTEM_MAX_POLL_FDS, sizeof(bsys->poll_results_bfds[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail1; - } - - // init results array - bsys->poll_results_num = 0; - bsys->poll_results_pos = 0; - - #endif - - DebugObject_Init(&bsys->d_obj); - #ifndef BADVPN_USE_WINAPI - DebugCounter_Init(&bsys->d_fds_counter); - #endif - #ifdef BADVPN_USE_KEVENT - DebugCounter_Init(&bsys->d_kevent_ctr); - #endif - DebugCounter_Init(&bsys->d_limits_ctr); - - return 1; - - #ifdef BADVPN_USE_POLL -fail1: - BFree(bsys->poll_results_pollfds); - #endif -fail0: - BPendingGroup_Free(&bsys->pending_jobs); - BLog(BLOG_ERROR, "Reactor failed to initialize"); - return 0; -} - -void BReactor_Free (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - #ifdef BADVPN_USE_WINAPI - while (!LinkedList1_IsEmpty(&bsys->iocp_list)) { - BReactorIOCPOverlapped *olap = UPPER_OBJECT(LinkedList1_GetLast(&bsys->iocp_list), BReactorIOCPOverlapped, iocp_list_node); - ASSERT(olap->reactor == bsys) - olap->handler(olap->user, BREACTOR_IOCP_EVENT_EXITING, 0); - } - #endif - - // {pending group has no BPending objects} - ASSERT(!BPendingGroup_HasJobs(&bsys->pending_jobs)) - ASSERT(BReactor__TimersTree_IsEmpty(&bsys->timers_tree)) - ASSERT(LinkedList1_IsEmpty(&bsys->timers_expired_list)) - ASSERT(LinkedList1_IsEmpty(&bsys->active_limits_list)) - DebugObject_Free(&bsys->d_obj); - #ifdef BADVPN_USE_WINAPI - ASSERT(LinkedList1_IsEmpty(&bsys->iocp_ready_list)) - ASSERT(LinkedList1_IsEmpty(&bsys->iocp_list)) - #endif - #ifndef BADVPN_USE_WINAPI - DebugCounter_Free(&bsys->d_fds_counter); - #endif - #ifdef BADVPN_USE_KEVENT - DebugCounter_Free(&bsys->d_kevent_ctr); - #endif - DebugCounter_Free(&bsys->d_limits_ctr); - #ifdef BADVPN_USE_POLL - ASSERT(bsys->poll_num_enabled_fds == 0) - ASSERT(LinkedList1_IsEmpty(&bsys->poll_enabled_fds_list)) - #endif - - BLog(BLOG_DEBUG, "Reactor freeing"); - - #ifdef BADVPN_USE_WINAPI - - // close IOCP handle - ASSERT_FORCE(CloseHandle(bsys->iocp_handle)) - - #endif - - #ifdef BADVPN_USE_EPOLL - - // close epoll fd - ASSERT_FORCE(close(bsys->efd) == 0) - - #endif - - #ifdef BADVPN_USE_KEVENT - - // close kqueue fd - ASSERT_FORCE(close(bsys->kqueue_fd) == 0) - - #endif - - #ifdef BADVPN_USE_POLL - - // free results arrays - BFree(bsys->poll_results_bfds); - BFree(bsys->poll_results_pollfds); - - #endif - - // free jobs - BPendingGroup_Free(&bsys->pending_jobs); -} - -int BReactor_Exec (BReactor *bsys) -{ - BLog(BLOG_DEBUG, "Entering event loop"); - - while (!bsys->exiting) { - // dispatch job - if (BPendingGroup_HasJobs(&bsys->pending_jobs)) { - BPendingGroup_ExecuteJob(&bsys->pending_jobs); - continue; - } - - // dispatch timer - LinkedList1Node *list_node = LinkedList1_GetFirst(&bsys->timers_expired_list); - if (list_node) { - BSmallTimer *timer = UPPER_OBJECT(list_node, BSmallTimer, u.list_node); - ASSERT(timer->state == TIMER_STATE_EXPIRED) - - // remove from expired list - LinkedList1_Remove(&bsys->timers_expired_list, &timer->u.list_node); - - // set inactive - timer->state = TIMER_STATE_INACTIVE; - - // call handler - BLog(BLOG_DEBUG, "Dispatching timer"); - if (timer->is_small) { - timer->handler.smalll(timer); - } else { - BTimer *btimer = UPPER_OBJECT(timer, BTimer, base); - timer->handler.heavy(btimer->user); - } - continue; - } - - #ifdef BADVPN_USE_WINAPI - - if (!LinkedList1_IsEmpty(&bsys->iocp_ready_list)) { - BReactorIOCPOverlapped *olap = UPPER_OBJECT(LinkedList1_GetFirst(&bsys->iocp_ready_list), BReactorIOCPOverlapped, ready_list_node); - ASSERT(olap->is_ready) - ASSERT(olap->handler) - - // remove from ready list - LinkedList1_Remove(&bsys->iocp_ready_list, &olap->ready_list_node); - - // set not ready - olap->is_ready = 0; - - int event = (olap->ready_succeeded ? BREACTOR_IOCP_EVENT_SUCCEEDED : BREACTOR_IOCP_EVENT_FAILED); - - // call handler - olap->handler(olap->user, event, olap->ready_bytes); - continue; - } - - #endif - - #ifdef BADVPN_USE_EPOLL - - // dispatch file descriptor - if (bsys->epoll_results_pos < bsys->epoll_results_num) { - // grab event - struct epoll_event *event = &bsys->epoll_results[bsys->epoll_results_pos]; - bsys->epoll_results_pos++; - - // check if the BFileDescriptor was removed - if (!event->data.ptr) { - continue; - } - - // get BFileDescriptor - BFileDescriptor *bfd = (BFileDescriptor *)event->data.ptr; - ASSERT(bfd->active) - ASSERT(bfd->epoll_returned_ptr == (BFileDescriptor **)&event->data.ptr) - - // zero pointer to the epoll entry - bfd->epoll_returned_ptr = NULL; - - // calculate events to report - int events = 0; - if ((bfd->waitEvents&BREACTOR_READ) && (event->events&EPOLLIN)) { - events |= BREACTOR_READ; - } - if ((bfd->waitEvents&BREACTOR_WRITE) && (event->events&EPOLLOUT)) { - events |= BREACTOR_WRITE; - } - if ((event->events&EPOLLERR)) { - events |= BREACTOR_ERROR; - } - if ((event->events&EPOLLHUP)) { - events |= BREACTOR_HUP; - } - - if (!events) { - BLog(BLOG_ERROR, "no events detected?"); - continue; - } - - // call handler - BLog(BLOG_DEBUG, "Dispatching file descriptor"); - bfd->handler(bfd->user, events); - continue; - } - - #endif - - #ifdef BADVPN_USE_KEVENT - - // dispatch kevent - if (bsys->kevent_results_pos < bsys->kevent_results_num) { - // grab event - struct kevent *event = &bsys->kevent_results[bsys->kevent_results_pos]; - bsys->kevent_results_pos++; - - // check if the event was removed - if (!event->udata) { - continue; - } - - // check tag - int *tag = event->udata; - switch (*tag) { - case KEVENT_TAG_FD: { - // get BFileDescriptor - BFileDescriptor *bfd = UPPER_OBJECT(tag, BFileDescriptor, kevent_tag); - ASSERT(bfd->active) - ASSERT(bfd->kevent_returned_ptr == (int **)&event->udata) - - // zero pointer to the kevent entry - bfd->kevent_returned_ptr = NULL; - - // calculate event to report - int events = 0; - if ((bfd->waitEvents&BREACTOR_READ) && event->filter == EVFILT_READ) { - events |= BREACTOR_READ; - } - if ((bfd->waitEvents&BREACTOR_WRITE) && event->filter == EVFILT_WRITE) { - events |= BREACTOR_WRITE; - } - - if (!events) { - BLog(BLOG_ERROR, "no events detected?"); - continue; - } - - // call handler - BLog(BLOG_DEBUG, "Dispatching file descriptor"); - bfd->handler(bfd->user, events); - continue; - } break; - - case KEVENT_TAG_KEVENT: { - // get BReactorKEvent - BReactorKEvent *kev = UPPER_OBJECT(tag, BReactorKEvent, kevent_tag); - ASSERT(kev->reactor == bsys) - ASSERT(kev->kevent_returned_ptr == (int **)&event->udata) - - // zero pointer to the kevent entry - kev->kevent_returned_ptr = NULL; - - // call handler - BLog(BLOG_DEBUG, "Dispatching kevent"); - kev->handler(kev->user, event->fflags, event->data); - continue; - } break; - - default: - ASSERT(0); - } - } - - #endif - - #ifdef BADVPN_USE_POLL - - if (bsys->poll_results_pos < bsys->poll_results_num) { - // grab event - struct pollfd *pfd = &bsys->poll_results_pollfds[bsys->poll_results_pos]; - BFileDescriptor *bfd = bsys->poll_results_bfds[bsys->poll_results_pos]; - bsys->poll_results_pos++; - - // skip removed entry - if (!bfd) { - continue; - } - - ASSERT(bfd->active) - ASSERT(bfd->poll_returned_index == bsys->poll_results_pos - 1) - - // remove result reference - bfd->poll_returned_index = -1; - - // calculate events to report - int events = 0; - if ((bfd->waitEvents & BREACTOR_READ) && (pfd->revents & POLLIN)) { - events |= BREACTOR_READ; - } - if ((bfd->waitEvents & BREACTOR_WRITE) && (pfd->revents & POLLOUT)) { - events |= BREACTOR_WRITE; - } - if ((pfd->revents & POLLERR) || (pfd->revents & POLLHUP)) { - events |= BREACTOR_ERROR; - } - - if (!events) { - continue; - } - - // call handler - BLog(BLOG_DEBUG, "Dispatching file descriptor"); - bfd->handler(bfd->user, events); - continue; - } - - #endif - - wait_for_events(bsys); - } - - BLog(BLOG_DEBUG, "Exiting event loop, exit code %d", bsys->exit_code); - - return bsys->exit_code; -} - -void BReactor_Quit (BReactor *bsys, int code) -{ - bsys->exiting = 1; - bsys->exit_code = code; -} - -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time) -{ - assert_timer(bt); - ASSERT(mode == BTIMER_SET_ABSOLUTE || mode == BTIMER_SET_RELATIVE) - - // unlink it if it's already in the list - BReactor_RemoveSmallTimer(bsys, bt); - - // if mode is relative, add current time - if (mode == BTIMER_SET_RELATIVE) { - time = btime_add(btime_gettime(), time); - } - - // set time - bt->absTime = time; - - // set running - bt->state = TIMER_STATE_RUNNING; - - // insert to running timers tree - BReactor__TimersTreeRef ref = {bt, bt}; - int res = BReactor__TimersTree_Insert(&bsys->timers_tree, 0, ref, NULL); - ASSERT_EXECUTE(res) -} - -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt) -{ - assert_timer(bt); - - if (bt->state == TIMER_STATE_INACTIVE) { - return; - } - - if (bt->state == TIMER_STATE_EXPIRED) { - // remove from expired list - LinkedList1_Remove(&bsys->timers_expired_list, &bt->u.list_node); - } else { - // remove from running tree - BReactor__TimersTreeRef ref = {bt, bt}; - BReactor__TimersTree_Remove(&bsys->timers_tree, 0, ref); - } - - // set inactive - bt->state = TIMER_STATE_INACTIVE; -} - -void BReactor_SetTimer (BReactor *bsys, BTimer *bt) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, bt->msTime); -} - -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, after); -} - -void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_ABSOLUTE, time); -} - -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt) -{ - return BReactor_RemoveSmallTimer(bsys, &bt->base); -} - -BPendingGroup * BReactor_PendingGroup (BReactor *bsys) -{ - return &bsys->pending_jobs; -} - -int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref) -{ - ASSERT(ref) - - while (!bsys->exiting) { - ASSERT(BPendingGroup_HasJobs(&bsys->pending_jobs)) - - if (BPendingGroup_PeekJob(&bsys->pending_jobs) == ref) { - return 1; - } - - BPendingGroup_ExecuteJob(&bsys->pending_jobs); - } - - return 0; -} - -#ifndef BADVPN_USE_WINAPI - -int BReactor_AddFileDescriptor (BReactor *bsys, BFileDescriptor *bs) -{ - ASSERT(!bs->active) - - #ifdef BADVPN_USE_EPOLL - - // add epoll entry - struct epoll_event event; - memset(&event, 0, sizeof(event)); - event.events = 0; - event.data.ptr = bs; - if (epoll_ctl(bsys->efd, EPOLL_CTL_ADD, bs->fd, &event) < 0) { - int error = errno; - BLog(BLOG_ERROR, "epoll_ctl failed: %d", error); - return 0; - } - - // set epoll returned pointer - bs->epoll_returned_ptr = NULL; - - #endif - - #ifdef BADVPN_USE_KEVENT - - // set kevent tag - bs->kevent_tag = KEVENT_TAG_FD; - - // set kevent returned pointer - bs->kevent_returned_ptr = NULL; - - #endif - - #ifdef BADVPN_USE_POLL - - if (bsys->poll_num_enabled_fds == BSYSTEM_MAX_POLL_FDS) { - BLog(BLOG_ERROR, "too many fds"); - return 0; - } - - // append to enabled fds list - LinkedList1_Append(&bsys->poll_enabled_fds_list, &bs->poll_enabled_fds_list_node); - bsys->poll_num_enabled_fds++; - - // set not returned - bs->poll_returned_index = -1; - - #endif - - bs->active = 1; - bs->waitEvents = 0; - - DebugCounter_Increment(&bsys->d_fds_counter); - return 1; -} - -void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs) -{ - ASSERT(bs->active) - DebugCounter_Decrement(&bsys->d_fds_counter); - - bs->active = 0; - - #ifdef BADVPN_USE_EPOLL - - // delete epoll entry - struct epoll_event event; - memset(&event, 0, sizeof(event)); - ASSERT_FORCE(epoll_ctl(bsys->efd, EPOLL_CTL_DEL, bs->fd, &event) == 0) - - // write through epoll returned pointer - if (bs->epoll_returned_ptr) { - *bs->epoll_returned_ptr = NULL; - } - - #endif - - #ifdef BADVPN_USE_KEVENT - - // delete kevents - update_kevent_fd_events(bsys, bs, 0); - - // write through kevent returned pointer - if (bs->kevent_returned_ptr) { - *bs->kevent_returned_ptr = NULL; - } - - #endif - - #ifdef BADVPN_USE_POLL - - // invalidate results entry - if (bs->poll_returned_index != -1) { - ASSERT(bs->poll_returned_index >= bsys->poll_results_pos) - ASSERT(bs->poll_returned_index < bsys->poll_results_num) - ASSERT(bsys->poll_results_bfds[bs->poll_returned_index] == bs) - - bsys->poll_results_bfds[bs->poll_returned_index] = NULL; - } - - // remove from enabled fds list - LinkedList1_Remove(&bsys->poll_enabled_fds_list, &bs->poll_enabled_fds_list_node); - bsys->poll_num_enabled_fds--; - - #endif -} - -void BReactor_SetFileDescriptorEvents (BReactor *bsys, BFileDescriptor *bs, int events) -{ - ASSERT(bs->active) - ASSERT(!(events&~(BREACTOR_READ|BREACTOR_WRITE))) - - if (bs->waitEvents == events) { - return; - } - - #ifdef BADVPN_USE_EPOLL - - // calculate epoll events - int eevents = 0; - if ((events & BREACTOR_READ)) { - eevents |= EPOLLIN; - } - if ((events & BREACTOR_WRITE)) { - eevents |= EPOLLOUT; - } - - // update epoll entry - struct epoll_event event; - memset(&event, 0, sizeof(event)); - event.events = eevents; - event.data.ptr = bs; - ASSERT_FORCE(epoll_ctl(bsys->efd, EPOLL_CTL_MOD, bs->fd, &event) == 0) - - #endif - - #ifdef BADVPN_USE_KEVENT - - update_kevent_fd_events(bsys, bs, events); - - #endif - - // update events - bs->waitEvents = events; -} - -#endif - -void BReactorLimit_Init (BReactorLimit *o, BReactor *reactor, int limit) -{ - DebugObject_Access(&reactor->d_obj); - ASSERT(limit > 0) - - // init arguments - o->reactor = reactor; - o->limit = limit; - - // set count zero - o->count = 0; - - DebugCounter_Increment(&reactor->d_limits_ctr); - DebugObject_Init(&o->d_obj); -} - -void BReactorLimit_Free (BReactorLimit *o) -{ - BReactor *reactor = o->reactor; - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&reactor->d_limits_ctr); - - // remove from active limits list - if (o->count > 0) { - LinkedList1_Remove(&reactor->active_limits_list, &o->active_limits_list_node); - } -} - -int BReactorLimit_Increment (BReactorLimit *o) -{ - BReactor *reactor = o->reactor; - DebugObject_Access(&o->d_obj); - - // check count against limit - if (o->count >= o->limit) { - return 0; - } - - // increment count - o->count++; - - // if limit was zero, add to active limits list - if (o->count == 1) { - LinkedList1_Append(&reactor->active_limits_list, &o->active_limits_list_node); - } - - return 1; -} - -void BReactorLimit_SetLimit (BReactorLimit *o, int limit) -{ - DebugObject_Access(&o->d_obj); - ASSERT(limit > 0) - - // set limit - o->limit = limit; -} - -#ifdef BADVPN_USE_KEVENT - -int BReactorKEvent_Init (BReactorKEvent *o, BReactor *reactor, BReactorKEvent_handler handler, void *user, uintptr_t ident, short filter, u_int fflags, intptr_t data) -{ - DebugObject_Access(&reactor->d_obj); - - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - o->ident = ident; - o->filter = filter; - - // add kevent - struct kevent event; - memset(&event, 0, sizeof(event)); - event.ident = o->ident; - event.filter = o->filter; - event.flags = EV_ADD; - event.fflags = fflags; - event.data = data; - event.udata = &o->kevent_tag; - if (kevent(o->reactor->kqueue_fd, &event, 1, NULL, 0, NULL) < 0) { - return 0; - } - - // set kevent tag - o->kevent_tag = KEVENT_TAG_KEVENT; - - // set kevent returned pointer - o->kevent_returned_ptr = NULL; - - DebugObject_Init(&o->d_obj); - DebugCounter_Increment(&o->reactor->d_kevent_ctr); - return 1; -} - -void BReactorKEvent_Free (BReactorKEvent *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->reactor->d_kevent_ctr); - - // write through kevent returned pointer - if (o->kevent_returned_ptr) { - *o->kevent_returned_ptr = NULL; - } - - // delete kevent - struct kevent event; - memset(&event, 0, sizeof(event)); - event.ident = o->ident; - event.filter = o->filter; - event.flags = EV_DELETE; - ASSERT_FORCE(kevent(o->reactor->kqueue_fd, &event, 1, NULL, 0, NULL) == 0) -} - -#endif - -#ifdef BADVPN_USE_WINAPI - -HANDLE BReactor_GetIOCPHandle (BReactor *reactor) -{ - DebugObject_Access(&reactor->d_obj); - - return reactor->iocp_handle; -} - -void BReactorIOCPOverlapped_Init (BReactorIOCPOverlapped *o, BReactor *reactor, void *user, BReactorIOCPOverlapped_handler handler) -{ - DebugObject_Access(&reactor->d_obj); - - // init arguments - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // zero overlapped - memset(&o->olap, 0, sizeof(o->olap)); - - // append to IOCP list - LinkedList1_Append(&reactor->iocp_list, &o->iocp_list_node); - - // set not ready - o->is_ready = 0; - - DebugObject_Init(&o->d_obj); -} - -void BReactorIOCPOverlapped_Free (BReactorIOCPOverlapped *o) -{ - BReactor *reactor = o->reactor; - DebugObject_Free(&o->d_obj); - - // remove from IOCP ready list - if (o->is_ready) { - LinkedList1_Remove(&reactor->iocp_ready_list, &o->ready_list_node); - } - - // remove from IOCP list - LinkedList1_Remove(&reactor->iocp_list, &o->iocp_list_node); -} - -void BReactorIOCPOverlapped_Wait (BReactorIOCPOverlapped *o, int *out_succeeded, DWORD *out_bytes) -{ - BReactor *reactor = o->reactor; - DebugObject_Access(&o->d_obj); - - // wait for IOCP events until we get an event for this olap - while (!o->is_ready) { - DWORD bytes = 0; - ULONG_PTR key; - BReactorIOCPOverlapped *olap = NULL; - BOOL res = GetQueuedCompletionStatus(reactor->iocp_handle, &bytes, &key, (OVERLAPPED **)&olap, INFINITE); - - ASSERT_FORCE(olap) - DebugObject_Access(&olap->d_obj); - ASSERT(olap->reactor == reactor) - - // regular I/O should be done synchronously, so we shoudln't ever get a second completion before an - // existing one is dispatched. If however PostQueuedCompletionStatus is being used to signal events, - // just discard any excess events. - if (!olap->is_ready) { - set_iocp_ready(olap, (res == TRUE), bytes); - } - } - - // remove from IOCP ready list - LinkedList1_Remove(&reactor->iocp_ready_list, &o->ready_list_node); - - // set not ready - o->is_ready = 0; - - if (out_succeeded) { - *out_succeeded = o->ready_succeeded; - } - if (out_bytes) { - *out_bytes = o->ready_bytes; - } -} - -#endif diff --git a/external/badvpn_dns/system/BReactor_badvpn.h b/external/badvpn_dns/system/BReactor_badvpn.h deleted file mode 100644 index 2c5ab4c..0000000 --- a/external/badvpn_dns/system/BReactor_badvpn.h +++ /dev/null @@ -1,572 +0,0 @@ -/** - * @file BReactor_badvpn.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Event loop that supports file desciptor (Linux) or HANDLE (Windows) events - * and timers. - */ - -#ifndef BADVPN_SYSTEM_BREACTOR_H -#define BADVPN_SYSTEM_BREACTOR_H - -#if (defined(BADVPN_USE_WINAPI) + defined(BADVPN_USE_EPOLL) + defined(BADVPN_USE_KEVENT) + defined(BADVPN_USE_POLL)) != 1 -#error Unknown event backend or too many event backends -#endif - -#ifdef BADVPN_USE_WINAPI -#include <windows.h> -#endif - -#ifdef BADVPN_USE_EPOLL -#include <sys/epoll.h> -#endif - -#ifdef BADVPN_USE_KEVENT -#include <sys/types.h> -#include <sys/event.h> -#include <sys/time.h> -#endif - -#ifdef BADVPN_USE_POLL -#include <poll.h> -#endif - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/debugcounter.h> -#include <base/DebugObject.h> -#include <structure/LinkedList1.h> -#include <structure/CAvl.h> -#include <system/BTime.h> -#include <base/BPending.h> - -struct BSmallTimer_t; -typedef struct BSmallTimer_t *BReactor_timerstree_link; - -#include "BReactor_badvpn_timerstree.h" -#include <structure/CAvl_decl.h> - -#define BTIMER_SET_ABSOLUTE 1 -#define BTIMER_SET_RELATIVE 2 - -/** - * Handler function invoked when the timer expires. - * The timer was in running state. - * The timer enters not running state before this function is invoked. - * This function is being called from within the timer's previosly - * associated reactor. - * - * @param timer pointer to the timer. Use the {@link UPPER_OBJECT} macro - * to obtain the pointer to the containing structure. - */ -typedef void (*BSmallTimer_handler) (struct BSmallTimer_t *timer); - -/** - * Handler function invoked when the timer expires. - * The timer was in running state. - * The timer enters not running state before this function is invoked. - * This function is being called from within the timer's previosly - * associated reactor. - * - * @param user value passed to {@link BTimer_Init} - */ -typedef void (*BTimer_handler) (void *user); - -/** - * Timer object used with {@link BReactor}. - */ -typedef struct BSmallTimer_t { - union { - BSmallTimer_handler smalll; // MSVC doesn't like "small" - BTimer_handler heavy; - } handler; - union { - LinkedList1Node list_node; - struct BSmallTimer_t *tree_child[2]; - } u; - struct BSmallTimer_t *tree_parent; - btime_t absTime; - int8_t tree_balance; - uint8_t state; - uint8_t is_small; -} BSmallTimer; - -/** - * Initializes the timer object. - * The timer object is initialized in not running state. - * - * @param bt the object - * @param handler handler function invoked when the timer expires - */ -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler); - -/** - * Checks if the timer is running. - * - * @param bt the object - * @return 1 if running, 0 if not running - */ -int BSmallTimer_IsRunning (BSmallTimer *bt); - -/** - * Timer object used with {@link BReactor}. This is a legacy wrapper - * around {@link BSmallTimer} with an extra field for the default time. - */ -typedef struct { - BSmallTimer base; - void *user; - btime_t msTime; -} BTimer; - -/** - * Initializes the timer object. - * The timer object is initialized in not running state. - * - * @param bt the object - * @param msTime default timeout in milliseconds - * @param handler handler function invoked when the timer expires - * @param user value to pass to the handler function - */ -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user); - -/** - * Checks if the timer is running. - * - * @param bt the object - * @return 1 if running, 0 if not running - */ -int BTimer_IsRunning (BTimer *bt); - -#ifndef BADVPN_USE_WINAPI - -struct BFileDescriptor_t; - -#define BREACTOR_READ (1 << 0) -#define BREACTOR_WRITE (1 << 1) -#define BREACTOR_ERROR (1 << 2) -#define BREACTOR_HUP (1 << 3) - -/** - * Handler function invoked by the reactor when one or more events are detected. - * The events argument will contain a subset of the monitored events (BREACTOR_READ, BREACTOR_WRITE), - * plus possibly the error event (BREACTOR_ERROR). - * The file descriptor object is in active state, being called from within - * the associated reactor. - * - * @param user value passed to {@link BFileDescriptor_Init} - * @param events bitmask composed of a subset of monitored events (BREACTOR_READ, BREACTOR_WRITE), - * and possibly the error event BREACTOR_ERROR and the hang-up event BREACTOR_HUP. - * Will be nonzero. - */ -typedef void (*BFileDescriptor_handler) (void *user, int events); - -/** - * File descriptor object used with {@link BReactor}. - */ -typedef struct BFileDescriptor_t { - int fd; - BFileDescriptor_handler handler; - void *user; - int active; - int waitEvents; - - #ifdef BADVPN_USE_EPOLL - struct BFileDescriptor_t **epoll_returned_ptr; - #endif - - #ifdef BADVPN_USE_KEVENT - int kevent_tag; - int **kevent_returned_ptr; - #endif - - #ifdef BADVPN_USE_POLL - LinkedList1Node poll_enabled_fds_list_node; - int poll_returned_index; - #endif -} BFileDescriptor; - -/** - * Intializes the file descriptor object. - * The object is initialized in not active state. - * - * @param bs file descriptor object to initialize - * @param fb file descriptor to represent - * @param handler handler function invoked by the reactor when a monitored event is detected - * @param user value passed to the handler functuon - */ -void BFileDescriptor_Init (BFileDescriptor *bs, int fd, BFileDescriptor_handler handler, void *user); - -#endif - -// BReactor - -#define BSYSTEM_MAX_RESULTS 64 -#define BSYSTEM_MAX_HANDLES 64 -#define BSYSTEM_MAX_POLL_FDS 4096 - -/** - * Event loop that supports file desciptor (Linux) or HANDLE (Windows) events - * and timers. - */ -typedef struct { - int exiting; - int exit_code; - - // jobs - BPendingGroup pending_jobs; - - // timers - BReactor__TimersTree timers_tree; - LinkedList1 timers_expired_list; - - // limits - LinkedList1 active_limits_list; - - #ifdef BADVPN_USE_WINAPI - LinkedList1 iocp_list; - HANDLE iocp_handle; - LinkedList1 iocp_ready_list; - #endif - - #ifdef BADVPN_USE_EPOLL - int efd; // epoll fd - struct epoll_event epoll_results[BSYSTEM_MAX_RESULTS]; // epoll returned events buffer - int epoll_results_num; // number of events in the array - int epoll_results_pos; // number of events processed so far - #endif - - #ifdef BADVPN_USE_KEVENT - int kqueue_fd; - struct kevent kevent_results[BSYSTEM_MAX_RESULTS]; - int kevent_results_num; - int kevent_results_pos; - #endif - - #ifdef BADVPN_USE_POLL - LinkedList1 poll_enabled_fds_list; - int poll_num_enabled_fds; - int poll_results_num; - int poll_results_pos; - struct pollfd *poll_results_pollfds; - BFileDescriptor **poll_results_bfds; - #endif - - DebugObject d_obj; - #ifndef BADVPN_USE_WINAPI - DebugCounter d_fds_counter; - #endif - #ifdef BADVPN_USE_KEVENT - DebugCounter d_kevent_ctr; - #endif - DebugCounter d_limits_ctr; -} BReactor; - -/** - * Initializes the reactor. - * {@link BLog_Init} must have been done. - * {@link BTime_Init} must have been done. - * - * @param bsys the object - * @return 1 on success, 0 on failure - */ -int BReactor_Init (BReactor *bsys) WARN_UNUSED; - -/** - * Frees the reactor. - * Must not be called from within the event loop ({@link BReactor_Exec}). - * There must be no {@link BPending} or {@link BSmallPending} objects using the - * pending group returned by {@link BReactor_PendingGroup}. - * There must be no running timers in this reactor. - * There must be no limit objects in this reactor. - * There must be no file descriptors or handles registered - * with this reactor. - * There must be no {@link BReactorKEvent} objects in this reactor. - * - * @param bsys the object - */ -void BReactor_Free (BReactor *bsys); - -/** - * Runs the event loop. - * - * @param bsys the object - * @return value passed to {@link BReactor_Quit} - */ -int BReactor_Exec (BReactor *bsys); - -/** - * Causes the event loop ({@link BReactor_Exec}) to cease - * dispatching events and return. - * Any further calls of {@link BReactor_Exec} will return immediately. - * - * @param bsys the object - * @param code value {@link BReactor_Exec} should return. If this is - * called more than once, it will return the last code. - */ -void BReactor_Quit (BReactor *bsys, int code); - -/** - * Starts a timer to expire at the specified time. - * The timer must have been initialized with {@link BSmallTimer_Init}. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters running state, associated with this reactor. - * - * @param bsys the object - * @param bt timer to start - * @param mode interpretation of time (BTIMER_SET_ABSOLUTE or BTIMER_SET_RELATIVE) - * @param time absolute or relative expiration time - */ -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time); - -/** - * Stops a timer. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters not running state. - * - * @param bsys the object - * @param bt timer to stop - */ -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt); - -/** - * Starts a timer to expire after its default time. - * The timer must have been initialized with {@link BTimer_Init}. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters running state, associated with this reactor. - * - * @param bsys the object - * @param bt timer to start - */ -void BReactor_SetTimer (BReactor *bsys, BTimer *bt); - -/** - * Starts a timer to expire after a given time. - * The timer must have been initialized with {@link BTimer_Init}. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters running state, associated with this reactor. - * - * @param bsys the object - * @param bt timer to start - * @param after relative expiration time - */ -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after); - -/** - * Starts a timer to expire at the specified time. - * The timer must have been initialized with {@link BTimer_Init}. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters running state, associated with this reactor. - * The timer's expiration time is set to the time argument. - * - * @param bsys the object - * @param bt timer to start - * @param time absolute expiration time (according to {@link btime_gettime}) - */ -void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time); - -/** - * Stops a timer. - * If the timer is in running state, it must be associated with this reactor. - * The timer enters not running state. - * - * @param bsys the object - * @param bt timer to stop - */ -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt); - -/** - * Returns a {@link BPendingGroup} object that can be used to schedule jobs for - * the reactor to execute. These jobs have complete priority over other events - * (timers, file descriptors and Windows handles). - * The returned pending group may only be used as an argument to {@link BPending_Init}, - * and must not be accessed by other means. - * All {@link BPending} and {@link BSmallPending} objects using this group must be - * freed before freeing the reactor. - * - * @param bsys the object - * @return pending group for scheduling jobs for the reactor to execute - */ -BPendingGroup * BReactor_PendingGroup (BReactor *bsys); - -/** - * Executes pending jobs until either: - * - the reference job is reached, or - * - {@link BReactor_Quit} is called. - * The reference job must be reached before the job list empties. - * The reference job will not be executed. - * - * WARNING: Use with care. This should only be used to to work around third-party software - * that does not integrade into the jobs system. In particular, you should think about: - * - the effects the jobs to be executed may have, and - * - the environment those jobs expect to be executed in. - * - * @param bsys the object - * @param ref reference job. It is not accessed in any way, only its address is compared to - * pending jobs before they are executed. - * @return 1 if the reference job was reached, - * 0 if {@link BReactor_Quit} was called (either while executing a job, or before) - */ -int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref); - -#ifndef BADVPN_USE_WINAPI - -/** - * Starts monitoring a file descriptor. - * - * @param bsys the object - * @param bs file descriptor object. Must have been initialized with - * {@link BFileDescriptor_Init} Must be in not active state. - * On success, the file descriptor object enters active state, - * associated with this reactor. - * @return 1 on success, 0 on failure - */ -int BReactor_AddFileDescriptor (BReactor *bsys, BFileDescriptor *bs) WARN_UNUSED; - -/** - * Stops monitoring a file descriptor. - * - * @param bsys the object - * @param bs {@link BFileDescriptor} object. Must be in active state, - * associated with this reactor. The file descriptor object - * enters not active state. - */ -void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs); - -/** - * Sets monitored file descriptor events. - * - * @param bsys the object - * @param bs {@link BFileDescriptor} object. Must be in active state, - * associated with this reactor. - * @param events events to watch for. Must not have any bits other than - * BREACTOR_READ and BREACTOR_WRITE. - * This overrides previosly monitored events. - */ -void BReactor_SetFileDescriptorEvents (BReactor *bsys, BFileDescriptor *bs, int events); - -#endif - -typedef struct { - BReactor *reactor; - int limit; - int count; - LinkedList1Node active_limits_list_node; - DebugObject d_obj; -} BReactorLimit; - -/** - * Initializes a limit object. - * A limit object consists of a counter integer, which is initialized to - * zero, is incremented by {@link BReactorLimit_Increment} up to \a limit, - * and is reset to zero every time the event loop performs a wait. - * If the event loop has processed all detected events, and before performing - * a wait, it determines that timers have expired, the counter will not be reset. - * - * @param o the object - * @param reactor reactor the object is tied to - * @param limit maximum counter value. Must be >0. - */ -void BReactorLimit_Init (BReactorLimit *o, BReactor *reactor, int limit); - -/** - * Frees a limit object. - * - * @param o the object - */ -void BReactorLimit_Free (BReactorLimit *o); - -/** - * Attempts to increment the counter of a limit object. - * - * @param o the object - * @return 1 if the counter was lesser than the limit and was incremented, - * 0 if the counter was greater or equal to the limit and could not be - * incremented - */ -int BReactorLimit_Increment (BReactorLimit *o); - -/** - * Sets the limit of a limit object. - * - * @param o the object - * @param limit new limit. Must be >0. - */ -void BReactorLimit_SetLimit (BReactorLimit *o, int limit); - -#ifdef BADVPN_USE_KEVENT - -typedef void (*BReactorKEvent_handler) (void *user, u_int fflags, intptr_t data); - -typedef struct { - BReactor *reactor; - BReactorKEvent_handler handler; - void *user; - uintptr_t ident; - short filter; - int kevent_tag; - int **kevent_returned_ptr; - DebugObject d_obj; -} BReactorKEvent; - -int BReactorKEvent_Init (BReactorKEvent *o, BReactor *reactor, BReactorKEvent_handler handler, void *user, uintptr_t ident, short filter, u_int fflags, intptr_t data); -void BReactorKEvent_Free (BReactorKEvent *o); - -#endif - -#ifdef BADVPN_USE_WINAPI - -#define BREACTOR_IOCP_EVENT_SUCCEEDED 1 -#define BREACTOR_IOCP_EVENT_FAILED 2 -#define BREACTOR_IOCP_EVENT_EXITING 3 - -typedef void (*BReactorIOCPOverlapped_handler) (void *user, int event, DWORD bytes); - -typedef struct { - OVERLAPPED olap; - BReactor *reactor; - void *user; - BReactorIOCPOverlapped_handler handler; - LinkedList1Node iocp_list_node; - int is_ready; - LinkedList1Node ready_list_node; - int ready_succeeded; - DWORD ready_bytes; - DebugObject d_obj; -} BReactorIOCPOverlapped; - -HANDLE BReactor_GetIOCPHandle (BReactor *reactor); - -void BReactorIOCPOverlapped_Init (BReactorIOCPOverlapped *o, BReactor *reactor, void *user, BReactorIOCPOverlapped_handler handler); -void BReactorIOCPOverlapped_Free (BReactorIOCPOverlapped *o); -void BReactorIOCPOverlapped_Wait (BReactorIOCPOverlapped *o, int *out_succeeded, DWORD *out_bytes); - -#endif - -#endif diff --git a/external/badvpn_dns/system/BReactor_badvpn_timerstree.h b/external/badvpn_dns/system/BReactor_badvpn_timerstree.h deleted file mode 100644 index 3cecd75..0000000 --- a/external/badvpn_dns/system/BReactor_badvpn_timerstree.h +++ /dev/null @@ -1,13 +0,0 @@ -#define CAVL_PARAM_NAME BReactor__TimersTree -#define CAVL_PARAM_FEATURE_COUNTS 0 -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0 -#define CAVL_PARAM_FEATURE_NOKEYS 1 -#define CAVL_PARAM_TYPE_ENTRY struct BSmallTimer_t -#define CAVL_PARAM_TYPE_LINK BReactor_timerstree_link -#define CAVL_PARAM_TYPE_ARG int -#define CAVL_PARAM_VALUE_NULL ((BReactor_timerstree_link)NULL) -#define CAVL_PARAM_FUN_DEREF(arg, link) (link) -#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_timers((entry1).link, (entry2).link) -#define CAVL_PARAM_MEMBER_CHILD u.tree_child -#define CAVL_PARAM_MEMBER_BALANCE tree_balance -#define CAVL_PARAM_MEMBER_PARENT tree_parent diff --git a/external/badvpn_dns/system/BReactor_emscripten.c b/external/badvpn_dns/system/BReactor_emscripten.c deleted file mode 100644 index f90af55..0000000 --- a/external/badvpn_dns/system/BReactor_emscripten.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @file BReactor_emscripten.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <inttypes.h> - -#include <emscripten/emscripten.h> - -#include "BReactor_emscripten.h" - -#include <misc/debug.h> - -#include <generated/blog_channel_BReactor.h> - -static void assert_timer (BTimer *bt, BReactor *reactor) -{ - ASSERT(bt->active == 0 || bt->active == 1); - ASSERT(bt->active == 0 || bt->reactor); - ASSERT(bt->active == 0 || (!reactor || bt->reactor == reactor)); -} - -static void dispatch_pending (BReactor *o) -{ - while (BPendingGroup_HasJobs(&o->pending_jobs)) { - BPendingGroup_ExecuteJob(&o->pending_jobs); - } -} - -__attribute__((used)) -void breactor_timer_cb (BReactor *reactor, BTimer *bt) -{ - assert_timer(bt, reactor); - ASSERT(bt->active); - ASSERT(!BPendingGroup_HasJobs(&reactor->pending_jobs)); - - bt->active = 0; - - bt->handler(bt->handler_pointer); - dispatch_pending(reactor); -} - -static void small_timer_handler (void *vbt) -{ - BSmallTimer *bt = vbt; - - bt->handler(bt); -} - -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user) -{ - bt->msTime = msTime; - bt->handler = handler; - bt->handler_pointer = user; - bt->active = 0; -} - -int BTimer_IsRunning (BTimer *bt) -{ - assert_timer(bt, NULL); - - return bt->active; -} - -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler) -{ - BTimer_Init(&bt->timer, 0, small_timer_handler, bt); - bt->handler = handler; -} - -int BSmallTimer_IsRunning (BSmallTimer *bt) -{ - return BTimer_IsRunning(&bt->timer); -} - -void BReactor_EmscriptenInit (BReactor *bsys) -{ - BPendingGroup_Init(&bsys->pending_jobs); - - DebugObject_Init(&bsys->d_obj); -} - -void BReactor_EmscriptenFree (BReactor *bsys) -{ - DebugObject_Free(&bsys->d_obj); - ASSERT(!BPendingGroup_HasJobs(&bsys->pending_jobs)); -} - -void BReactor_EmscriptenSync (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - dispatch_pending(bsys); -} - -BPendingGroup * BReactor_PendingGroup (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - return &bsys->pending_jobs; -} - -void BReactor_SetTimer (BReactor *bsys, BTimer *bt) -{ - BReactor_SetTimerAfter(bsys, bt, bt->msTime); -} - -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after) -{ - DebugObject_Access(&bsys->d_obj); - assert_timer(bt, bsys); - - if (bt->active) { - BReactor_RemoveTimer(bsys, bt); - } - - char cmd[120]; - sprintf(cmd, "setTimeout(function(){Module.ccall('breactor_timer_cb','null',['number','number'],[%d,%d]);},%"PRIi64")", (int)bsys, (int)bt, after); - - bt->active = 1; - bt->timerid = emscripten_run_script_int(cmd); - bt->reactor = bsys; -} - -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt) -{ - DebugObject_Access(&bsys->d_obj); - assert_timer(bt, bsys); - - if (!bt->active) { - return; - } - - char cmd[30]; - sprintf(cmd, "clearTimeout(%d)", bt->timerid); - - emscripten_run_script(cmd); - bt->active = 0; -} - -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time) -{ - ASSERT(mode == BTIMER_SET_RELATIVE) - - BReactor_SetTimerAfter(bsys, &bt->timer, time); -} - -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt) -{ - BReactor_RemoveTimer(bsys, &bt->timer); -} diff --git a/external/badvpn_dns/system/BReactor_emscripten.h b/external/badvpn_dns/system/BReactor_emscripten.h deleted file mode 100644 index c004d16..0000000 --- a/external/badvpn_dns/system/BReactor_emscripten.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file BReactor_emscripten.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SYSTEM_BREACTOR_H -#define BADVPN_SYSTEM_BREACTOR_H - -#include <stdint.h> - -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <system/BTime.h> - -#define BTIMER_SET_RELATIVE 2 - -typedef struct BReactor_s BReactor; - -typedef void (*BTimer_handler) (void *user); - -typedef struct BTimer_t { - btime_t msTime; - BTimer_handler handler; - void *handler_pointer; - uint8_t active; - int timerid; - BReactor *reactor; -} BTimer; - -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user); -int BTimer_IsRunning (BTimer *bt); - -struct BSmallTimer_t; - -typedef void (*BSmallTimer_handler) (struct BSmallTimer_t *timer); - -typedef struct BSmallTimer_t { - BTimer timer; - BSmallTimer_handler handler; -} BSmallTimer; - -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler); -int BSmallTimer_IsRunning (BSmallTimer *bt); - -struct BReactor_s { - BPendingGroup pending_jobs; - DebugObject d_obj; -}; - -void BReactor_EmscriptenInit (BReactor *bsys); -void BReactor_EmscriptenFree (BReactor *bsys); -void BReactor_EmscriptenSync (BReactor *bsys); - -BPendingGroup * BReactor_PendingGroup (BReactor *bsys); - -void BReactor_SetTimer (BReactor *bsys, BTimer *bt); -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after); -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt); - -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time); -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt); - -#endif diff --git a/external/badvpn_dns/system/BReactor_glib.c b/external/badvpn_dns/system/BReactor_glib.c deleted file mode 100644 index 63f0fd6..0000000 --- a/external/badvpn_dns/system/BReactor_glib.c +++ /dev/null @@ -1,524 +0,0 @@ -/** - * @file BReactor_glib.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <base/BLog.h> - -#include "BReactor_glib.h" - -#include <generated/blog_channel_BReactor.h> - -struct fd_source { - GSource source; - BFileDescriptor *bfd; -}; - -static void assert_timer (BSmallTimer *bt) -{ - ASSERT(bt->is_small == 0 || bt->is_small == 1) - ASSERT(bt->active == 0 || bt->active == 1) - ASSERT(!bt->active || bt->reactor) - ASSERT(!bt->active || bt->source) -} - -static void dispatch_pending (BReactor *o) -{ - while (!o->exiting && BPendingGroup_HasJobs(&o->pending_jobs)) { - BPendingGroup_ExecuteJob(&o->pending_jobs); - } -} - -static void reset_limits (BReactor *o) -{ - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&o->active_limits_list)) { - BReactorLimit *limit = UPPER_OBJECT(list_node, BReactorLimit, active_limits_list_node); - ASSERT(limit->count > 0) - limit->count = 0; - LinkedList1_Remove(&o->active_limits_list, &limit->active_limits_list_node); - } -} - -static gushort get_glib_wait_events (int ev) -{ - gushort gev = G_IO_ERR | G_IO_HUP; - - if (ev & BREACTOR_READ) { - gev |= G_IO_IN; - } - - if (ev & BREACTOR_WRITE) { - gev |= G_IO_OUT; - } - - return gev; -} - -static int get_fd_dispatchable_events (BFileDescriptor *bfd) -{ - ASSERT(bfd->active) - - int ev = 0; - - if ((bfd->waitEvents & BREACTOR_READ) && (bfd->pollfd.revents & G_IO_IN)) { - ev |= BREACTOR_READ; - } - - if ((bfd->waitEvents & BREACTOR_WRITE) && (bfd->pollfd.revents & G_IO_OUT)) { - ev |= BREACTOR_WRITE; - } - - if ((bfd->pollfd.revents & G_IO_ERR)) { - ev |= BREACTOR_ERROR; - } - - if ((bfd->pollfd.revents & G_IO_HUP)) { - ev |= BREACTOR_HUP; - } - - return ev; -} - -static gboolean timer_source_handler (gpointer data) -{ - BSmallTimer *bt = (void *)data; - assert_timer(bt); - ASSERT(bt->active) - - BReactor *reactor = bt->reactor; - - if (reactor->exiting) { - return FALSE; - } - - g_source_destroy(bt->source); - g_source_unref(bt->source); - bt->active = 0; - DebugCounter_Decrement(&reactor->d_timers_ctr); - - if (bt->is_small) { - bt->handler.smalll(bt); - } else { - BTimer *btimer = UPPER_OBJECT(bt, BTimer, base); - bt->handler.heavy(btimer->user); - } - - dispatch_pending(reactor); - reset_limits(reactor); - - return FALSE; -} - -static gboolean fd_source_func_prepare (GSource *source, gint *timeout) -{ - BFileDescriptor *bfd = ((struct fd_source *)source)->bfd; - ASSERT(bfd->active) - ASSERT(bfd->source == source) - - *timeout = -1; - return FALSE; -} - -static gboolean fd_source_func_check (GSource *source) -{ - BFileDescriptor *bfd = ((struct fd_source *)source)->bfd; - ASSERT(bfd->active) - ASSERT(bfd->source == source) - - return (get_fd_dispatchable_events(bfd) ? TRUE : FALSE); -} - -static gboolean fd_source_func_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) -{ - BFileDescriptor *bfd = ((struct fd_source *)source)->bfd; - BReactor *reactor = bfd->reactor; - ASSERT(bfd->active) - ASSERT(bfd->source == source) - - if (reactor->exiting) { - return TRUE; - } - - int events = get_fd_dispatchable_events(bfd); - if (!events) { - return TRUE; - } - - bfd->handler(bfd->user, events); - dispatch_pending(reactor); - reset_limits(reactor); - - return TRUE; -} - -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler) -{ - bt->handler.smalll = handler; - bt->active = 0; - bt->is_small = 1; -} - -int BSmallTimer_IsRunning (BSmallTimer *bt) -{ - assert_timer(bt); - - return bt->active; -} - -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user) -{ - bt->base.handler.heavy = handler; - bt->base.active = 0; - bt->base.is_small = 0; - bt->user = user; - bt->msTime = msTime; -} - -int BTimer_IsRunning (BTimer *bt) -{ - return BSmallTimer_IsRunning(&bt->base); -} - -void BFileDescriptor_Init (BFileDescriptor *bs, int fd, BFileDescriptor_handler handler, void *user) -{ - bs->fd = fd; - bs->handler = handler; - bs->user = user; - bs->active = 0; -} - -int BReactor_Init (BReactor *bsys) -{ - return BReactor_InitFromExistingGMainLoop(bsys, g_main_loop_new(NULL, FALSE), 1); -} - -void BReactor_Free (BReactor *bsys) -{ - DebugObject_Free(&bsys->d_obj); - DebugCounter_Free(&bsys->d_timers_ctr); - DebugCounter_Free(&bsys->d_limits_ctr); - DebugCounter_Free(&bsys->d_fds_counter); - ASSERT(!BPendingGroup_HasJobs(&bsys->pending_jobs)) - ASSERT(LinkedList1_IsEmpty(&bsys->active_limits_list)) - - // free job queue - BPendingGroup_Free(&bsys->pending_jobs); - - // unref main loop if needed - if (bsys->unref_gloop_on_free) { - g_main_loop_unref(bsys->gloop); - } -} - -int BReactor_Exec (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - // dispatch pending jobs (until exiting) and reset limits - dispatch_pending(bsys); - reset_limits(bsys); - - // if exiting, do not enter glib loop - if (bsys->exiting) { - return bsys->exit_code; - } - - // enter glib loop - g_main_loop_run(bsys->gloop); - - ASSERT(bsys->exiting) - - return bsys->exit_code; -} - -void BReactor_Quit (BReactor *bsys, int code) -{ - DebugObject_Access(&bsys->d_obj); - - // remember exiting - bsys->exiting = 1; - bsys->exit_code = code; - - // request termination of glib loop - g_main_loop_quit(bsys->gloop); -} - -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time) -{ - DebugObject_Access(&bsys->d_obj); - assert_timer(bt); - - // remove timer if it's already set - BReactor_RemoveSmallTimer(bsys, bt); - - // if mode is absolute, subtract current time - if (mode == BTIMER_SET_ABSOLUTE) { - btime_t now = btime_gettime(); - time = (time < now ? 0 : time - now); - } - - // set active and reactor - bt->active = 1; - bt->reactor = bsys; - - // init source - bt->source = g_timeout_source_new(time); - g_source_set_callback(bt->source, timer_source_handler, bt, NULL); - g_source_attach(bt->source, g_main_loop_get_context(bsys->gloop)); - - DebugCounter_Increment(&bsys->d_timers_ctr); -} - -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt) -{ - DebugObject_Access(&bsys->d_obj); - assert_timer(bt); - - // do nothing if timer is not active - if (!bt->active) { - return; - } - - // free source - g_source_destroy(bt->source); - g_source_unref(bt->source); - - // set not active - bt->active = 0; - - DebugCounter_Decrement(&bsys->d_timers_ctr); -} - -void BReactor_SetTimer (BReactor *bsys, BTimer *bt) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, bt->msTime); -} - -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, after); -} - -void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time) -{ - BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_ABSOLUTE, time); -} - -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt) -{ - return BReactor_RemoveSmallTimer(bsys, &bt->base); -} - -BPendingGroup * BReactor_PendingGroup (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - return &bsys->pending_jobs; -} - -int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref) -{ - DebugObject_Access(&bsys->d_obj); - ASSERT(ref) - - while (!bsys->exiting) { - ASSERT(BPendingGroup_HasJobs(&bsys->pending_jobs)) - - if (BPendingGroup_PeekJob(&bsys->pending_jobs) == ref) { - return 1; - } - - BPendingGroup_ExecuteJob(&bsys->pending_jobs); - } - - return 0; -} - -int BReactor_AddFileDescriptor (BReactor *bsys, BFileDescriptor *bs) -{ - DebugObject_Access(&bsys->d_obj); - ASSERT(!bs->active) - - // set active, no wait events, and set reactor - bs->active = 1; - bs->waitEvents = 0; - bs->reactor = bsys; - - // create source - bs->source = g_source_new(&bsys->fd_source_funcs, sizeof(struct fd_source)); - ((struct fd_source *)bs->source)->bfd = bs; - - // init pollfd - bs->pollfd.fd = bs->fd; - bs->pollfd.events = get_glib_wait_events(bs->waitEvents); - bs->pollfd.revents = 0; - - // start source - g_source_add_poll(bs->source, &bs->pollfd); - g_source_attach(bs->source, g_main_loop_get_context(bsys->gloop)); - - DebugCounter_Increment(&bsys->d_fds_counter); - return 1; -} - -void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs) -{ - DebugObject_Access(&bsys->d_obj); - DebugCounter_Decrement(&bsys->d_fds_counter); - ASSERT(bs->active) - - // free source - g_source_destroy(bs->source); - g_source_unref(bs->source); - - // set not active - bs->active = 0; -} - -void BReactor_SetFileDescriptorEvents (BReactor *bsys, BFileDescriptor *bs, int events) -{ - DebugObject_Access(&bsys->d_obj); - ASSERT(bs->active) - ASSERT(!(events&~(BREACTOR_READ|BREACTOR_WRITE))) - - // set new wait events - bs->waitEvents = events; - - // update pollfd wait events - bs->pollfd.events = get_glib_wait_events(bs->waitEvents); -} - -int BReactor_InitFromExistingGMainLoop (BReactor *bsys, GMainLoop *gloop, int unref_gloop_on_free) -{ - ASSERT(gloop) - ASSERT(unref_gloop_on_free == !!unref_gloop_on_free) - - // set not exiting - bsys->exiting = 0; - - // set gloop and unref on free flag - bsys->gloop = gloop; - bsys->unref_gloop_on_free = unref_gloop_on_free; - - // init fd source functions table - memset(&bsys->fd_source_funcs, 0, sizeof(bsys->fd_source_funcs)); - bsys->fd_source_funcs.prepare = fd_source_func_prepare; - bsys->fd_source_funcs.check = fd_source_func_check; - bsys->fd_source_funcs.dispatch = fd_source_func_dispatch; - bsys->fd_source_funcs.finalize = NULL; - - // init job queue - BPendingGroup_Init(&bsys->pending_jobs); - - // init active limits list - LinkedList1_Init(&bsys->active_limits_list); - - DebugCounter_Init(&bsys->d_fds_counter); - DebugCounter_Init(&bsys->d_limits_ctr); - DebugCounter_Init(&bsys->d_timers_ctr); - DebugObject_Init(&bsys->d_obj); - return 1; -} - -GMainLoop * BReactor_GetGMainLoop (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - return bsys->gloop; -} - -int BReactor_SynchronizeAll (BReactor *bsys) -{ - DebugObject_Access(&bsys->d_obj); - - dispatch_pending(bsys); - - return !bsys->exiting; -} - -void BReactorLimit_Init (BReactorLimit *o, BReactor *reactor, int limit) -{ - DebugObject_Access(&reactor->d_obj); - ASSERT(limit > 0) - - // init arguments - o->reactor = reactor; - o->limit = limit; - - // set count zero - o->count = 0; - - DebugCounter_Increment(&reactor->d_limits_ctr); - DebugObject_Init(&o->d_obj); -} - -void BReactorLimit_Free (BReactorLimit *o) -{ - BReactor *reactor = o->reactor; - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&reactor->d_limits_ctr); - - // remove from active limits list - if (o->count > 0) { - LinkedList1_Remove(&reactor->active_limits_list, &o->active_limits_list_node); - } -} - -int BReactorLimit_Increment (BReactorLimit *o) -{ - BReactor *reactor = o->reactor; - DebugObject_Access(&o->d_obj); - - // check count against limit - if (o->count >= o->limit) { - return 0; - } - - // increment count - o->count++; - - // if limit was zero, add to active limits list - if (o->count == 1) { - LinkedList1_Append(&reactor->active_limits_list, &o->active_limits_list_node); - } - - return 1; -} - -void BReactorLimit_SetLimit (BReactorLimit *o, int limit) -{ - DebugObject_Access(&o->d_obj); - ASSERT(limit > 0) - - // set limit - o->limit = limit; -} diff --git a/external/badvpn_dns/system/BReactor_glib.h b/external/badvpn_dns/system/BReactor_glib.h deleted file mode 100644 index 0102be9..0000000 --- a/external/badvpn_dns/system/BReactor_glib.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file BReactor_glib.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SYSTEM_BREACTOR_H -#define BADVPN_SYSTEM_BREACTOR_H - -#include <stdint.h> - -#include <glib.h> - -#include <misc/debug.h> -#include <misc/debugcounter.h> -#include <misc/offset.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <base/BPending.h> -#include <system/BTime.h> - -typedef struct BReactor_s BReactor; - -struct BSmallTimer_t; - -#define BTIMER_SET_ABSOLUTE 1 -#define BTIMER_SET_RELATIVE 2 - -typedef void (*BSmallTimer_handler) (struct BSmallTimer_t *timer); -typedef void (*BTimer_handler) (void *user); - -typedef struct BSmallTimer_t { - union { - BSmallTimer_handler smalll; // MSVC doesn't like "small" - BTimer_handler heavy; - } handler; - BReactor *reactor; - GSource *source; - uint8_t active; - uint8_t is_small; -} BSmallTimer; - -void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler); -int BSmallTimer_IsRunning (BSmallTimer *bt); - -typedef struct { - BSmallTimer base; - void *user; - btime_t msTime; -} BTimer; - -void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user); -int BTimer_IsRunning (BTimer *bt); - -struct BFileDescriptor_t; - -#define BREACTOR_READ (1 << 0) -#define BREACTOR_WRITE (1 << 1) -#define BREACTOR_ERROR (1 << 2) -#define BREACTOR_HUP (1 << 3) - -typedef void (*BFileDescriptor_handler) (void *user, int events); - -typedef struct BFileDescriptor_t { - int fd; - BFileDescriptor_handler handler; - void *user; - int active; - int waitEvents; - BReactor *reactor; - GSource *source; - GPollFD pollfd; -} BFileDescriptor; - -void BFileDescriptor_Init (BFileDescriptor *bs, int fd, BFileDescriptor_handler handler, void *user); - -struct BReactor_s { - int exiting; - int exit_code; - GMainLoop *gloop; - int unref_gloop_on_free; - GSourceFuncs fd_source_funcs; - BPendingGroup pending_jobs; - LinkedList1 active_limits_list; - - DebugCounter d_fds_counter; - DebugCounter d_limits_ctr; - DebugCounter d_timers_ctr; - DebugObject d_obj; -}; - -int BReactor_Init (BReactor *bsys) WARN_UNUSED; -void BReactor_Free (BReactor *bsys); -int BReactor_Exec (BReactor *bsys); -void BReactor_Quit (BReactor *bsys, int code); -void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time); -void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt); -void BReactor_SetTimer (BReactor *bsys, BTimer *bt); -void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after); -void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time); -void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt); -BPendingGroup * BReactor_PendingGroup (BReactor *bsys); -int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref); -int BReactor_AddFileDescriptor (BReactor *bsys, BFileDescriptor *bs) WARN_UNUSED; -void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs); -void BReactor_SetFileDescriptorEvents (BReactor *bsys, BFileDescriptor *bs, int events); - -int BReactor_InitFromExistingGMainLoop (BReactor *bsys, GMainLoop *gloop, int unref_gloop_on_free); -GMainLoop * BReactor_GetGMainLoop (BReactor *bsys); -int BReactor_SynchronizeAll (BReactor *bsys); - -typedef struct { - BReactor *reactor; - int limit; - int count; - LinkedList1Node active_limits_list_node; - DebugObject d_obj; -} BReactorLimit; - -void BReactorLimit_Init (BReactorLimit *o, BReactor *reactor, int limit); -void BReactorLimit_Free (BReactorLimit *o); -int BReactorLimit_Increment (BReactorLimit *o); -void BReactorLimit_SetLimit (BReactorLimit *o, int limit); - -#endif diff --git a/external/badvpn_dns/system/BSignal.c b/external/badvpn_dns/system/BSignal.c deleted file mode 100644 index 520a167..0000000 --- a/external/badvpn_dns/system/BSignal.c +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @file BSignal.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef BADVPN_USE_WINAPI -#include <windows.h> -#else -#include <signal.h> -#include <system/BUnixSignal.h> -#endif - -#include <misc/debug.h> -#include <base/BLog.h> - -#include <system/BSignal.h> - -#include <generated/blog_channel_BSignal.h> - -static struct { - int initialized; - int finished; - BReactor *reactor; - BSignal_handler handler; - void *user; - #ifdef BADVPN_USE_WINAPI - BReactorIOCPOverlapped olap; - CRITICAL_SECTION iocp_handle_mutex; - HANDLE iocp_handle; - #else - BUnixSignal signal; - #endif -} bsignal_global = { - 0 -}; - -#ifdef BADVPN_USE_WINAPI - -static void olap_handler (void *user, int event, DWORD bytes) -{ - ASSERT(bsignal_global.initialized) - ASSERT(!(event == BREACTOR_IOCP_EVENT_EXITING) || bsignal_global.finished) - - if (event == BREACTOR_IOCP_EVENT_EXITING) { - BReactorIOCPOverlapped_Free(&bsignal_global.olap); - return; - } - - if (!bsignal_global.finished) { - // call handler - bsignal_global.handler(bsignal_global.user); - return; - } -} - -static BOOL WINAPI ctrl_handler (DWORD type) -{ - EnterCriticalSection(&bsignal_global.iocp_handle_mutex); - - if (bsignal_global.iocp_handle) { - PostQueuedCompletionStatus(bsignal_global.iocp_handle, 0, 0, &bsignal_global.olap.olap); - } - - LeaveCriticalSection(&bsignal_global.iocp_handle_mutex); - - return TRUE; -} - -#else - -static void unix_signal_handler (void *user, int signo) -{ - ASSERT(signo == SIGTERM || signo == SIGINT) - ASSERT(bsignal_global.initialized) - ASSERT(!bsignal_global.finished) - - BLog(BLOG_DEBUG, "Dispatching signal"); - - // call handler - bsignal_global.handler(bsignal_global.user); - return; -} - -#endif - -int BSignal_Init (BReactor *reactor, BSignal_handler handler, void *user) -{ - ASSERT(!bsignal_global.initialized) - - // init arguments - bsignal_global.reactor = reactor; - bsignal_global.handler = handler; - bsignal_global.user = user; - - BLog(BLOG_DEBUG, "BSignal initializing"); - - #ifdef BADVPN_USE_WINAPI - - // init olap - BReactorIOCPOverlapped_Init(&bsignal_global.olap, bsignal_global.reactor, NULL, olap_handler); - - // init handler mutex - InitializeCriticalSection(&bsignal_global.iocp_handle_mutex); - - // remember IOCP handle - bsignal_global.iocp_handle = BReactor_GetIOCPHandle(bsignal_global.reactor); - - // configure ctrl handler - if (!SetConsoleCtrlHandler(ctrl_handler, TRUE)) { - BLog(BLOG_ERROR, "SetConsoleCtrlHandler failed"); - goto fail1; - } - - #else - - sigset_t sset; - ASSERT_FORCE(sigemptyset(&sset) == 0) - ASSERT_FORCE(sigaddset(&sset, SIGTERM) == 0) - ASSERT_FORCE(sigaddset(&sset, SIGINT) == 0) - - // init BUnixSignal - if (!BUnixSignal_Init(&bsignal_global.signal, bsignal_global.reactor, sset, unix_signal_handler, NULL)) { - BLog(BLOG_ERROR, "BUnixSignal_Init failed"); - goto fail0; - } - - #endif - - bsignal_global.initialized = 1; - bsignal_global.finished = 0; - - return 1; - - #ifdef BADVPN_USE_WINAPI -fail1: - DeleteCriticalSection(&bsignal_global.iocp_handle_mutex); - BReactorIOCPOverlapped_Free(&bsignal_global.olap); - #endif - -fail0: - return 0; -} - -void BSignal_Finish (void) -{ - ASSERT(bsignal_global.initialized) - ASSERT(!bsignal_global.finished) - - #ifdef BADVPN_USE_WINAPI - - // forget IOCP handle - EnterCriticalSection(&bsignal_global.iocp_handle_mutex); - bsignal_global.iocp_handle = NULL; - LeaveCriticalSection(&bsignal_global.iocp_handle_mutex); - - #else - - // free BUnixSignal - BUnixSignal_Free(&bsignal_global.signal, 0); - - #endif - - bsignal_global.finished = 1; -} diff --git a/external/badvpn_dns/system/BSignal.h b/external/badvpn_dns/system/BSignal.h deleted file mode 100644 index 41f17e2..0000000 --- a/external/badvpn_dns/system/BSignal.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file BSignal.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A global object for catching program termination requests. - */ - -#ifndef BADVPN_SYSTEM_BSIGNAL_H -#define BADVPN_SYSTEM_BSIGNAL_H - -#include <misc/debug.h> -#include <system/BReactor.h> - -typedef void (*BSignal_handler) (void *user); - -/** - * Initializes signal handling. - * The object is created in not capturing state. - * {@link BLog_Init} must have been done. - * - * WARNING: make sure this won't interfere with other components: - * - on Linux, this uses {@link BUnixSignal} to catch SIGTERM and SIGINT, - * - on Windows, this sets up a handler with SetConsoleCtrlHandler. - * - * @param reactor {@link BReactor} from which the handler will be called - * @param handler callback function invoked from the reactor - * @param user value passed to callback function - * @return 1 on success, 0 on failure - */ -int BSignal_Init (BReactor *reactor, BSignal_handler handler, void *user) WARN_UNUSED; - -/** - * Finishes signal handling. - * {@link BSignal_Init} must not be called again. - */ -void BSignal_Finish (void); - -#endif diff --git a/external/badvpn_dns/system/BThreadSignal.c b/external/badvpn_dns/system/BThreadSignal.c deleted file mode 100644 index 7d68c1b..0000000 --- a/external/badvpn_dns/system/BThreadSignal.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file BThreadSignal.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <errno.h> -#include <unistd.h> - -#include <misc/debug.h> -#include <misc/nonblocking.h> -#include <base/BLog.h> - -#include "BThreadSignal.h" - -#include <generated/blog_channel_BThreadSignal.h> - -static void bfd_handler (void *user, int events) -{ - BThreadSignal *o = user; - DebugObject_Access(&o->d_obj); - - char byte; - ssize_t res = read(o->pipe[0], &byte, sizeof(byte)); - - if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - return; - } - - if (res < 0) { - BLog(BLOG_ERROR, "read failed"); - return; - } - - if (res != sizeof(byte)) { - BLog(BLOG_ERROR, "bad read"); - return; - } - - o->handler(o); -} - -int BThreadSignal_Init (BThreadSignal *o, BReactor *reactor, BThreadSignal_handler handler) -{ - o->reactor = reactor; - o->handler = handler; - - if (pipe(o->pipe) < 0) { - BLog(BLOG_ERROR, "pipe failed"); - goto fail0; - } - - if (!badvpn_set_nonblocking(o->pipe[0]) || !badvpn_set_nonblocking(o->pipe[1])) { - BLog(BLOG_ERROR, "badvpn_set_nonblocking failed"); - goto fail1; - } - - BFileDescriptor_Init(&o->bfd, o->pipe[0], bfd_handler, o); - - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (close(o->pipe[1]) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - if (close(o->pipe[0]) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -fail0: - return 0; -} - -void BThreadSignal_Free (BThreadSignal *o) -{ - DebugObject_Free(&o->d_obj); - - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - if (close(o->pipe[1]) < 0) { - BLog(BLOG_ERROR, "close failed"); - } - if (close(o->pipe[0]) < 0) { - BLog(BLOG_ERROR, "close failed"); - } -} - -int BThreadSignal_Thread_Signal (BThreadSignal *o) -{ - DebugObject_Access(&o->d_obj); - - char byte = 0; - ssize_t res = write(o->pipe[1], &byte, sizeof(byte)); - - if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - return 0; - } - - if (res < 0) { - BLog(BLOG_ERROR, "write failed"); - } else if (res != sizeof(byte)) { - BLog(BLOG_ERROR, "bad write"); - } - - return 1; -} diff --git a/external/badvpn_dns/system/BThreadSignal.h b/external/badvpn_dns/system/BThreadSignal.h deleted file mode 100644 index 2c8d816..0000000 --- a/external/badvpn_dns/system/BThreadSignal.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file BThreadSignal.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_B_THREAD_SIGNAL_H -#define BADVPN_B_THREAD_SIGNAL_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> - -typedef struct BThreadSignal_s BThreadSignal; - -typedef void (*BThreadSignal_handler) (BThreadSignal *thread_signal); - -struct BThreadSignal_s { - BReactor *reactor; - BThreadSignal_handler handler; - int pipe[2]; - BFileDescriptor bfd; - DebugObject d_obj; -}; - -int BThreadSignal_Init (BThreadSignal *o, BReactor *reactor, BThreadSignal_handler handler) WARN_UNUSED; -void BThreadSignal_Free (BThreadSignal *o); -int BThreadSignal_Thread_Signal (BThreadSignal *o); - -#endif diff --git a/external/badvpn_dns/system/BTime.c b/external/badvpn_dns/system/BTime.c deleted file mode 100644 index a1fa9e7..0000000 --- a/external/badvpn_dns/system/BTime.c +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file BTime.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <system/BTime.h> - -#ifndef BADVPN_PLUGIN -struct _BTime_global btime_global = { - #ifndef NDEBUG - 0 - #endif -}; -#endif diff --git a/external/badvpn_dns/system/BTime.h b/external/badvpn_dns/system/BTime.h deleted file mode 100644 index 6998814..0000000 --- a/external/badvpn_dns/system/BTime.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @file BTime.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * System time abstraction used by {@link BReactor}. - */ - -#ifndef BADVPN_SYSTEM_BTIME_H -#define BADVPN_SYSTEM_BTIME_H - -#if defined(BADVPN_USE_WINAPI) -#include <windows.h> -#elif defined(BADVPN_EMSCRIPTEN) -#include <emscripten/emscripten.h> -#else -#include <time.h> -#include <sys/time.h> -#endif - -#include <stdint.h> - -#include <misc/debug.h> -#include <misc/overflow.h> -#include <base/BLog.h> - -#include <generated/blog_channel_BTime.h> - -typedef int64_t btime_t; - -#define BTIME_MIN INT64_MIN - -struct _BTime_global { - #ifndef NDEBUG - int initialized; // initialized statically - #endif - #if defined(BADVPN_USE_WINAPI) - LARGE_INTEGER start_time; - #elif defined(BADVPN_EMSCRIPTEN) - btime_t start_time; - #else - btime_t start_time; - int use_gettimeofday; - #endif -}; - -extern struct _BTime_global btime_global; - -static void BTime_Init (void) -{ - ASSERT(!btime_global.initialized) - - #if defined(BADVPN_USE_WINAPI) - - ASSERT_FORCE(QueryPerformanceCounter(&btime_global.start_time)) - - #elif defined(BADVPN_EMSCRIPTEN) - - btime_global.start_time = emscripten_get_now(); - - #else - - struct timespec ts; - if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { - BLog(BLOG_WARNING, "CLOCK_MONOTONIC is not available. Timers will be confused by clock changes."); - - struct timeval tv; - ASSERT_FORCE(gettimeofday(&tv, NULL) == 0) - - btime_global.start_time = (int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec/1000; - btime_global.use_gettimeofday = 1; - } else { - btime_global.start_time = (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec/1000000; - btime_global.use_gettimeofday = 0; - } - - #endif - - #ifndef NDEBUG - btime_global.initialized = 1; - #endif -} - -static btime_t btime_gettime (void) -{ - ASSERT(btime_global.initialized) - - #if defined(BADVPN_USE_WINAPI) - - LARGE_INTEGER count; - LARGE_INTEGER freq; - ASSERT_FORCE(QueryPerformanceCounter(&count)) - ASSERT_FORCE(QueryPerformanceFrequency(&freq)) - return (((count.QuadPart - btime_global.start_time.QuadPart) * 1000) / freq.QuadPart); - - #elif defined(BADVPN_EMSCRIPTEN) - - return (btime_t)emscripten_get_now() - btime_global.start_time; - - #else - - if (btime_global.use_gettimeofday) { - struct timeval tv; - ASSERT_FORCE(gettimeofday(&tv, NULL) == 0) - return ((int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec/1000); - } else { - struct timespec ts; - ASSERT_FORCE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0) - return (((int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec/1000000) - btime_global.start_time); - } - - #endif -} - -static btime_t btime_add (btime_t t1, btime_t t2) -{ - // handle overflow - int overflows = add_int64_overflows(t1, t2); - btime_t sum; - if (overflows != 0) { - if (overflows > 0) { - sum = INT64_MAX; - } else { - sum = INT64_MIN; - } - } else { - sum = t1 + t2; - } - - return sum; -} - -static btime_t btime_getpast (void) -{ - return INT64_MIN; -} - -#endif diff --git a/external/badvpn_dns/system/BUnixSignal.c b/external/badvpn_dns/system/BUnixSignal.c deleted file mode 100644 index 94edd6b..0000000 --- a/external/badvpn_dns/system/BUnixSignal.c +++ /dev/null @@ -1,406 +0,0 @@ -/** - * @file BUnixSignal.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <inttypes.h> -#include <stdlib.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <string.h> - -#ifdef BADVPN_USE_SIGNALFD -#include <sys/signalfd.h> -#endif - -#include <misc/balloc.h> -#include <misc/nonblocking.h> -#include <base/BLog.h> - -#include <system/BUnixSignal.h> - -#include <generated/blog_channel_BUnixSignal.h> - -#define BUNIXSIGNAL_MAX_SIGNALS 64 - -#ifdef BADVPN_USE_SIGNALFD - -static void signalfd_handler (BUnixSignal *o, int events) -{ - DebugObject_Access(&o->d_obj); - - // read a signal - struct signalfd_siginfo siginfo; - int bytes = read(o->signalfd_fd, &siginfo, sizeof(siginfo)); - if (bytes < 0) { - int error = errno; - if (error == EAGAIN || error == EWOULDBLOCK) { - return; - } - BLog(BLOG_ERROR, "read failed (%d)", error); - return; - } - ASSERT_FORCE(bytes == sizeof(siginfo)) - - // check signal - if (siginfo.ssi_signo > INT_MAX) { - BLog(BLOG_ERROR, "read returned out of int range signo (%"PRIu32")", siginfo.ssi_signo); - return; - } - int signo = siginfo.ssi_signo; - if (sigismember(&o->signals, signo) <= 0) { - BLog(BLOG_ERROR, "read returned wrong signo (%d)", signo); - return; - } - - BLog(BLOG_DEBUG, "dispatching signal %d", signo); - - // call handler - o->handler(o->user, signo); - return; -} - -#endif - -#ifdef BADVPN_USE_KEVENT - -static void kevent_handler (struct BUnixSignal_kevent_entry *entry, u_int fflags, intptr_t data) -{ - BUnixSignal *o = entry->parent; - DebugObject_Access(&o->d_obj); - - // call signal - o->handler(o->user, entry->signo); - return; -} - -#endif - -#ifdef BADVPN_USE_SELFPIPE - -struct BUnixSignal_selfpipe_entry *bunixsignal_selfpipe_entries[BUNIXSIGNAL_MAX_SIGNALS]; - -static void free_selfpipe_entry (struct BUnixSignal_selfpipe_entry *entry) -{ - BUnixSignal *o = entry->parent; - - // uninstall signal handler - struct sigaction act; - memset(&act, 0, sizeof(act)); - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - ASSERT_FORCE(sigaction(entry->signo, &act, NULL) == 0) - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &entry->pipe_read_bfd); - - // close pipe - ASSERT_FORCE(close(entry->pipefds[0]) == 0) - ASSERT_FORCE(close(entry->pipefds[1]) == 0) -} - -static void pipe_read_fd_handler (struct BUnixSignal_selfpipe_entry *entry, int events) -{ - BUnixSignal *o = entry->parent; - DebugObject_Access(&o->d_obj); - - // read a byte - uint8_t b; - if (read(entry->pipefds[0], &b, sizeof(b)) < 0) { - int error = errno; - if (error == EAGAIN || error == EWOULDBLOCK) { - return; - } - BLog(BLOG_ERROR, "read failed (%d)", error); - return; - } - - // call handler - o->handler(o->user, entry->signo); - return; -} - -static void signal_handler (int signo) -{ - ASSERT(signo >= 0) - ASSERT(signo < BUNIXSIGNAL_MAX_SIGNALS) - - struct BUnixSignal_selfpipe_entry *entry = bunixsignal_selfpipe_entries[signo]; - - uint8_t b = 0; - write(entry->pipefds[1], &b, sizeof(b)); -} - -#endif - -int BUnixSignal_Init (BUnixSignal *o, BReactor *reactor, sigset_t signals, BUnixSignal_handler handler, void *user) -{ - // init arguments - o->reactor = reactor; - o->signals = signals; - o->handler = handler; - o->user = user; - - #ifdef BADVPN_USE_SIGNALFD - - // init signalfd fd - if ((o->signalfd_fd = signalfd(-1, &o->signals, 0)) < 0) { - BLog(BLOG_ERROR, "signalfd failed"); - goto fail0; - } - - // set non-blocking - if (fcntl(o->signalfd_fd, F_SETFL, O_NONBLOCK) < 0) { - BLog(BLOG_ERROR, "cannot set non-blocking"); - goto fail1; - } - - // init signalfd BFileDescriptor - BFileDescriptor_Init(&o->signalfd_bfd, o->signalfd_fd, (BFileDescriptor_handler)signalfd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->signalfd_bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->signalfd_bfd, BREACTOR_READ); - - // block signals - if (sigprocmask(SIG_BLOCK, &o->signals, 0) < 0) { - BLog(BLOG_ERROR, "sigprocmask block failed"); - goto fail2; - } - - #endif - - #ifdef BADVPN_USE_KEVENT - - // count signals - int num_signals = 0; - for (int i = 0; i < BUNIXSIGNAL_MAX_SIGNALS; i++) { - if (!sigismember(&o->signals, i)) { - continue; - } - num_signals++; - } - - // allocate array - if (!(o->entries = BAllocArray(num_signals, sizeof(o->entries[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - // init kevents - o->num_entries = 0; - for (int i = 0; i < BUNIXSIGNAL_MAX_SIGNALS; i++) { - if (!sigismember(&o->signals, i)) { - continue; - } - struct BUnixSignal_kevent_entry *entry = &o->entries[o->num_entries]; - entry->parent = o; - entry->signo = i; - if (!BReactorKEvent_Init(&entry->kevent, o->reactor, (BReactorKEvent_handler)kevent_handler, entry, entry->signo, EVFILT_SIGNAL, 0, 0)) { - BLog(BLOG_ERROR, "BReactorKEvent_Init failed"); - goto fail2; - } - o->num_entries++; - } - - // block signals - if (sigprocmask(SIG_BLOCK, &o->signals, 0) < 0) { - BLog(BLOG_ERROR, "sigprocmask block failed"); - goto fail2; - } - - #endif - - #ifdef BADVPN_USE_SELFPIPE - - // count signals - int num_signals = 0; - for (int i = 1; i < BUNIXSIGNAL_MAX_SIGNALS; i++) { - if (!sigismember(&o->signals, i)) { - continue; - } - num_signals++; - } - - // allocate array - if (!(o->entries = BAllocArray(num_signals, sizeof(o->entries[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - // init entries - o->num_entries = 0; - for (int i = 1; i < BUNIXSIGNAL_MAX_SIGNALS; i++) { - if (!sigismember(&o->signals, i)) { - continue; - } - - struct BUnixSignal_selfpipe_entry *entry = &o->entries[o->num_entries]; - entry->parent = o; - entry->signo = i; - - // init pipe - if (pipe(entry->pipefds) < 0) { - BLog(BLOG_ERROR, "pipe failed"); - goto loop_fail0; - } - - // set pipe ends non-blocking - if (!badvpn_set_nonblocking(entry->pipefds[0]) || !badvpn_set_nonblocking(entry->pipefds[1])) { - BLog(BLOG_ERROR, "set nonblocking failed"); - goto loop_fail1; - } - - // init read end BFileDescriptor - BFileDescriptor_Init(&entry->pipe_read_bfd, entry->pipefds[0], (BFileDescriptor_handler)pipe_read_fd_handler, entry); - if (!BReactor_AddFileDescriptor(o->reactor, &entry->pipe_read_bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto loop_fail1; - } - BReactor_SetFileDescriptorEvents(o->reactor, &entry->pipe_read_bfd, BREACTOR_READ); - - // set global entry pointer - bunixsignal_selfpipe_entries[entry->signo] = entry; - - // install signal handler - struct sigaction act; - memset(&act, 0, sizeof(act)); - act.sa_handler = signal_handler; - sigemptyset(&act.sa_mask); - if (sigaction(entry->signo, &act, NULL) < 0) { - BLog(BLOG_ERROR, "sigaction failed"); - goto loop_fail2; - } - - o->num_entries++; - - continue; - - loop_fail2: - BReactor_RemoveFileDescriptor(o->reactor, &entry->pipe_read_bfd); - loop_fail1: - ASSERT_FORCE(close(entry->pipefds[0]) == 0) - ASSERT_FORCE(close(entry->pipefds[1]) == 0) - loop_fail0: - goto fail2; - } - - #endif - - DebugObject_Init(&o->d_obj); - - return 1; - - #ifdef BADVPN_USE_SIGNALFD -fail2: - BReactor_RemoveFileDescriptor(o->reactor, &o->signalfd_bfd); -fail1: - ASSERT_FORCE(close(o->signalfd_fd) == 0) - #endif - - #ifdef BADVPN_USE_KEVENT -fail2: - while (o->num_entries > 0) { - BReactorKEvent_Free(&o->entries[o->num_entries - 1].kevent); - o->num_entries--; - } - BFree(o->entries); - #endif - - #ifdef BADVPN_USE_SELFPIPE -fail2: - while (o->num_entries > 0) { - free_selfpipe_entry(&o->entries[o->num_entries - 1]); - o->num_entries--; - } - BFree(o->entries); - #endif - -fail0: - return 0; -} - -void BUnixSignal_Free (BUnixSignal *o, int unblock) -{ - ASSERT(unblock == 0 || unblock == 1) - DebugObject_Free(&o->d_obj); - - #ifdef BADVPN_USE_SIGNALFD - - if (unblock) { - // unblock signals - ASSERT_FORCE(sigprocmask(SIG_UNBLOCK, &o->signals, 0) == 0) - } - - // free signalfd BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->signalfd_bfd); - - // free signalfd fd - ASSERT_FORCE(close(o->signalfd_fd) == 0) - - #endif - - #ifdef BADVPN_USE_KEVENT - - if (unblock) { - // unblock signals - ASSERT_FORCE(sigprocmask(SIG_UNBLOCK, &o->signals, 0) == 0) - } - - // free kevents - while (o->num_entries > 0) { - BReactorKEvent_Free(&o->entries[o->num_entries - 1].kevent); - o->num_entries--; - } - - // free array - BFree(o->entries); - - #endif - - #ifdef BADVPN_USE_SELFPIPE - - if (!unblock) { - // block signals - if (sigprocmask(SIG_BLOCK, &o->signals, 0) < 0) { - BLog(BLOG_ERROR, "sigprocmask block failed"); - } - } - - // free entries - while (o->num_entries > 0) { - free_selfpipe_entry(&o->entries[o->num_entries - 1]); - o->num_entries--; - } - - // free array - BFree(o->entries); - - #endif -} diff --git a/external/badvpn_dns/system/BUnixSignal.h b/external/badvpn_dns/system/BUnixSignal.h deleted file mode 100644 index 2438be9..0000000 --- a/external/badvpn_dns/system/BUnixSignal.h +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file BUnixSignal.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object for catching unix signals. - */ - -#ifndef BADVPN_SYSTEM_BUNIXSIGNAL_H -#define BADVPN_SYSTEM_BUNIXSIGNAL_H - -#if (defined(BADVPN_USE_SIGNALFD) + defined(BADVPN_USE_KEVENT) + defined(BADVPN_USE_SELFPIPE)) != 1 -#error Unknown signal backend or too many signal backends -#endif - -#include <unistd.h> -#include <signal.h> - -#include <misc/debug.h> -#include <system/BReactor.h> -#include <base/DebugObject.h> - -struct BUnixSignal_s; - -/** - * Handler function called when a signal is received. - * - * @param user as in {@link BUnixSignal_Init} - * @param signo signal number. Will be one of the signals provided to {@link signals}. - */ -typedef void (*BUnixSignal_handler) (void *user, int signo); - -#ifdef BADVPN_USE_KEVENT -struct BUnixSignal_kevent_entry { - struct BUnixSignal_s *parent; - int signo; - BReactorKEvent kevent; -}; -#endif - -#ifdef BADVPN_USE_SELFPIPE -struct BUnixSignal_selfpipe_entry { - struct BUnixSignal_s *parent; - int signo; - int pipefds[2]; - BFileDescriptor pipe_read_bfd; -}; -#endif - -/** - * Object for catching unix signals. - */ -typedef struct BUnixSignal_s { - BReactor *reactor; - sigset_t signals; - BUnixSignal_handler handler; - void *user; - - #ifdef BADVPN_USE_SIGNALFD - int signalfd_fd; - BFileDescriptor signalfd_bfd; - #endif - - #ifdef BADVPN_USE_KEVENT - struct BUnixSignal_kevent_entry *entries; - int num_entries; - #endif - - #ifdef BADVPN_USE_SELFPIPE - struct BUnixSignal_selfpipe_entry *entries; - int num_entries; - #endif - - DebugObject d_obj; -} BUnixSignal; - -/** - * Initializes the object. - * {@link BLog_Init} must have been done. - * - * WARNING: for every signal number there should be at most one {@link BUnixSignal} - * object handling it (or anything else that could interfere). - * - * This blocks the signal using sigprocmask() and sets up signalfd() for receiving - * signals. - * - * @param o the object - * @param reactor reactor we live in - * @param signals signals to handle. See man 3 sigsetops. - * @param handler handler function to call when a signal is received - * @param user value passed to callback function - * @return 1 on success, 0 on failure - */ -int BUnixSignal_Init (BUnixSignal *o, BReactor *reactor, sigset_t signals, BUnixSignal_handler handler, void *user) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - * @param unblock whether to unblock the signals using sigprocmask(). Not unblocking it - * can be used while the program is exiting gracefully to prevent the - * signals from being handled handled according to its default disposition - * after this function is called. Must be 0 or 1. - */ -void BUnixSignal_Free (BUnixSignal *o, int unblock); - -#endif diff --git a/external/badvpn_dns/system/CMakeLists.txt b/external/badvpn_dns/system/CMakeLists.txt deleted file mode 100644 index 99f7333..0000000 --- a/external/badvpn_dns/system/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -set(BSYSTEM_ADDITIONAL_LIBS) -set(BSYSTEM_ADDITIONAL_SOURCES) - -if (NOT EMSCRIPTEN) - list(APPEND BSYSTEM_ADDITIONAL_SOURCES - BSignal.c - BNetwork.c - ) - - if (WIN32) - list(APPEND BSYSTEM_ADDITIONAL_LIBS ws2_32 mswsock) - list(APPEND BSYSTEM_ADDITIONAL_SOURCES - BConnection_win.c - BDatagram_win.c - ) - endif () - - if (NOT WIN32) - list(APPEND BSYSTEM_ADDITIONAL_SOURCES - BUnixSignal.c - BConnection_unix.c - BDatagram_unix.c - BProcess.c - BInputProcess.c - BThreadSignal.c - BLockReactor.c - ) - endif () -endif () - -if (BREACTOR_BACKEND STREQUAL "badvpn") - list(APPEND BSYSTEM_ADDITIONAL_SOURCES BReactor_badvpn.c) -elseif (BREACTOR_BACKEND STREQUAL "glib") - list(APPEND BSYSTEM_ADDITIONAL_SOURCES BReactor_glib.c) - list(APPEND BSYSTEM_ADDITIONAL_LIBS ${GLIB2_LIBRARIES}) -elseif (BREACTOR_BACKEND STREQUAL "emscripten") - list(APPEND BSYSTEM_ADDITIONAL_SOURCES BReactor_emscripten.c) -endif () - -set(SYSTEM_SOURCES - BTime.c - ${BSYSTEM_ADDITIONAL_SOURCES} -) -badvpn_add_library(system "base;flow" "${BSYSTEM_ADDITIONAL_LIBS}" "${SYSTEM_SOURCES}") diff --git a/external/badvpn_dns/tests/CMakeLists.txt b/external/badvpn_dns/tests/CMakeLists.txt deleted file mode 100644 index ebb0d62..0000000 --- a/external/badvpn_dns/tests/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_executable(chunkbuffer2_test chunkbuffer2_test.c) - -add_executable(bproto_test bproto_test.c) - -if (BUILDING_THREADWORK) - add_executable(threadwork_test threadwork_test.c) - target_link_libraries(threadwork_test threadwork) -endif () diff --git a/external/badvpn_dns/tests/bproto_test.bproto b/external/badvpn_dns/tests/bproto_test.bproto deleted file mode 100644 index 4641a74..0000000 --- a/external/badvpn_dns/tests/bproto_test.bproto +++ /dev/null @@ -1,9 +0,0 @@ -message msg1 { - required uint16 a = 5; - optional uint32 b = 6; - required repeated uint64 c = 7; - repeated uint16 d = 8; - required uint8 e = 9; - required data f = 10; - required data("4") g = 11; -}; diff --git a/external/badvpn_dns/tests/bproto_test.c b/external/badvpn_dns/tests/bproto_test.c deleted file mode 100644 index 067695b..0000000 --- a/external/badvpn_dns/tests/bproto_test.c +++ /dev/null @@ -1,76 +0,0 @@ -#include <string.h> -#include <stdint.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <misc/balloc.h> - -#include <generated/bproto_bproto_test.h> - -int main () -{ - uint16_t a = 17501; - uint64_t c = 82688926; - uint16_t d1 = 1517; - uint16_t d2 = 1518; - uint8_t e = 72; - const char *f = "hello world"; - const char *g = "helo"; - - // encode message - - int len = msg1_SIZEa + msg1_SIZEc + msg1_SIZEd + msg1_SIZEd + msg1_SIZEe + msg1_SIZEf(strlen(f)) + msg1_SIZEg; - - uint8_t *msg = (uint8_t *)BAlloc(len); - ASSERT_FORCE(msg) - msg1Writer writer; - msg1Writer_Init(&writer, msg); - msg1Writer_Adda(&writer, a); - msg1Writer_Addc(&writer, c); - msg1Writer_Addd(&writer, d1); - msg1Writer_Addd(&writer, d2); - msg1Writer_Adde(&writer, e); - uint8_t *f_dst = msg1Writer_Addf(&writer, strlen(f)); - memcpy(f_dst, f, strlen(f)); - uint8_t *g_dst = msg1Writer_Addg(&writer); - memcpy(g_dst, g, strlen(g)); - int len2 = msg1Writer_Finish(&writer); - ASSERT_EXECUTE(len2 == len) - - // parse message - - msg1Parser parser; - ASSERT_EXECUTE(msg1Parser_Init(&parser, msg, len)) - - // check parse results - - uint16_t p_a; - uint64_t p_c; - uint16_t p_d1; - uint16_t p_d2; - uint8_t p_e; - uint8_t *p_f; - int p_f_len; - uint8_t *p_g; - ASSERT_EXECUTE(msg1Parser_Geta(&parser, &p_a)) - ASSERT_EXECUTE(msg1Parser_Getc(&parser, &p_c)) - ASSERT_EXECUTE(msg1Parser_Getd(&parser, &p_d1)) - ASSERT_EXECUTE(msg1Parser_Getd(&parser, &p_d2)) - ASSERT_EXECUTE(msg1Parser_Gete(&parser, &p_e)) - ASSERT_EXECUTE(msg1Parser_Getf(&parser, &p_f, &p_f_len)) - ASSERT_EXECUTE(msg1Parser_Getg(&parser, &p_g)) - - ASSERT(p_a == a) - ASSERT(p_c == c) - ASSERT(p_d1 == d1) - ASSERT(p_d2 == d2) - ASSERT(p_e == e) - ASSERT(p_f_len == strlen(f) && !memcmp(p_f, f, p_f_len)) - ASSERT(!memcmp(p_g, g, strlen(g))) - - ASSERT(msg1Parser_GotEverything(&parser)) - - BFree(msg); - - return 0; -} diff --git a/external/badvpn_dns/tests/chunkbuffer2_test.c b/external/badvpn_dns/tests/chunkbuffer2_test.c deleted file mode 100644 index ff94bb3..0000000 --- a/external/badvpn_dns/tests/chunkbuffer2_test.c +++ /dev/null @@ -1,86 +0,0 @@ -#include <misc/debug.h> -#include <structure/ChunkBuffer2.h> - -int main () -{ - struct ChunkBuffer2_block blocks[16]; - ChunkBuffer2 buf; - ChunkBuffer2_Init(&buf, blocks, 16, 4 * sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.input_avail == 15 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == NULL) - ASSERT_FORCE(buf.output_avail == -1) - - ChunkBuffer2_SubmitPacket(&buf, sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[3]) - ASSERT_FORCE(buf.input_avail == 13 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.output_avail == 1 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_SubmitPacket(&buf, 8 * sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[12]) - ASSERT_FORCE(buf.input_avail == 4 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.output_avail == 1 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_SubmitPacket(&buf, 4 * sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == NULL) - ASSERT_FORCE(buf.input_avail == -1) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.output_avail == 1 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_ConsumePacket(&buf); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.input_avail == 1 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[3]) - ASSERT_FORCE(buf.output_avail == 8 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_ConsumePacket(&buf); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.input_avail == 10 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[12]) - ASSERT_FORCE(buf.output_avail == 4 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_SubmitPacket(&buf, 9 * sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[11]) - ASSERT_FORCE(buf.input_avail == 0 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[12]) - ASSERT_FORCE(buf.output_avail == 4 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_ConsumePacket(&buf); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[11]) - ASSERT_FORCE(buf.input_avail == 5 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.output_avail == 9 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_SubmitPacket(&buf, 1 * sizeof(struct ChunkBuffer2_block)); - - ASSERT_FORCE(buf.input_dest == NULL) - ASSERT_FORCE(buf.input_avail == -1) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.output_avail == 9 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_ConsumePacket(&buf); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.input_avail == 9 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == (uint8_t *)&blocks[11]) - ASSERT_FORCE(buf.output_avail == 1 * sizeof(struct ChunkBuffer2_block)) - - ChunkBuffer2_ConsumePacket(&buf); - - ASSERT_FORCE(buf.input_dest == (uint8_t *)&blocks[1]) - ASSERT_FORCE(buf.input_avail == 15 * sizeof(struct ChunkBuffer2_block)) - ASSERT_FORCE(buf.output_dest == NULL) - ASSERT_FORCE(buf.output_avail == -1) - - return 0; -} diff --git a/external/badvpn_dns/tests/threadwork_test.c b/external/badvpn_dns/tests/threadwork_test.c deleted file mode 100644 index 9c18b4b..0000000 --- a/external/badvpn_dns/tests/threadwork_test.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <stddef.h> -#include <stdio.h> - -#include <misc/debug.h> -#include <base/BLog.h> -#include <base/DebugObject.h> -#include <threadwork/BThreadWork.h> - -BReactor reactor; -BThreadWorkDispatcher twd; -BThreadWork tw1; -BThreadWork tw2; -BThreadWork tw3; -int num_left; - -static void handler_done (void *user) -{ - printf("work done\n"); - - num_left--; - - if (num_left == 0) { - printf("all works done, quitting\n"); - BReactor_Quit(&reactor, 0); - } -} - -static void work_func (void *user) -{ - unsigned int x = 0; - - for (int i = 0; i < 10000; i++) { - for (int j = 0; j < 10000; j++) { - x++; - } - } -} - -static void dummy_works (int n) -{ - for (int i = 0; i < n; i++) { - BThreadWork tw_tmp; - BThreadWork_Init(&tw_tmp, &twd, handler_done, NULL, work_func, NULL); - BThreadWork_Free(&tw_tmp); - } -} - -int main () -{ - BLog_InitStdout(); - BLog_SetChannelLoglevel(BLOG_CHANNEL_BThreadWork, BLOG_DEBUG); - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BThreadWorkDispatcher_Init(&twd, &reactor, 1)) { - DEBUG("BThreadWorkDispatcher_Init failed"); - goto fail2; - } - - dummy_works(200); - - BThreadWork_Init(&tw1, &twd, handler_done, NULL, work_func, NULL); - - BThreadWork_Init(&tw2, &twd, handler_done, NULL, work_func, NULL); - - BThreadWork_Init(&tw3, &twd, handler_done, NULL, work_func, NULL); - - dummy_works(200); - - num_left = 3; - - BReactor_Exec(&reactor); - - BThreadWork_Free(&tw3); - BThreadWork_Free(&tw2); - BThreadWork_Free(&tw1); - BThreadWorkDispatcher_Free(&twd); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); - DebugObjectGlobal_Finish(); - return 0; -} diff --git a/external/badvpn_dns/threadwork/BThreadWork.c b/external/badvpn_dns/threadwork/BThreadWork.c deleted file mode 100644 index 3c29f95..0000000 --- a/external/badvpn_dns/threadwork/BThreadWork.c +++ /dev/null @@ -1,451 +0,0 @@ -/** - * @file BThreadWork.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stddef.h> - -#ifdef BADVPN_THREADWORK_USE_PTHREAD - #include <unistd.h> - #include <errno.h> - #include <fcntl.h> -#endif - -#include <misc/offset.h> -#include <base/BLog.h> - -#include <generated/blog_channel_BThreadWork.h> - -#include <threadwork/BThreadWork.h> - -#ifdef BADVPN_THREADWORK_USE_PTHREAD - -static void * dispatcher_thread (struct BThreadWorkDispatcher_thread *t) -{ - BThreadWorkDispatcher *o = t->d; - - ASSERT_FORCE(pthread_mutex_lock(&o->mutex) == 0) - - while (1) { - // exit if requested - if (o->cancel) { - break; - } - - if (LinkedList1_IsEmpty(&o->pending_list)) { - // wait for event - ASSERT_FORCE(pthread_cond_wait(&t->new_cond, &o->mutex) == 0) - continue; - } - - // grab the work - BThreadWork *w = UPPER_OBJECT(LinkedList1_GetFirst(&o->pending_list), BThreadWork, list_node); - ASSERT(w->state == BTHREADWORK_STATE_PENDING) - LinkedList1_Remove(&o->pending_list, &w->list_node); - t->running_work = w; - w->state = BTHREADWORK_STATE_RUNNING; - - // do the work - ASSERT_FORCE(pthread_mutex_unlock(&o->mutex) == 0) - w->work_func(w->work_func_user); - ASSERT_FORCE(pthread_mutex_lock(&o->mutex) == 0) - - // release the work - t->running_work = NULL; - LinkedList1_Append(&o->finished_list, &w->list_node); - w->state = BTHREADWORK_STATE_FINISHED; - ASSERT_FORCE(sem_post(&w->finished_sem) == 0) - - // write to pipe - uint8_t b = 0; - int res = write(o->pipe[1], &b, sizeof(b)); - if (res < 0) { - int error = errno; - ASSERT_FORCE(error == EAGAIN || error == EWOULDBLOCK) - } - } - - ASSERT_FORCE(pthread_mutex_unlock(&o->mutex) == 0) - - return NULL; -} - -static void dispatch_job (BThreadWorkDispatcher *o) -{ - ASSERT(o->num_threads > 0) - - // lock - ASSERT_FORCE(pthread_mutex_lock(&o->mutex) == 0) - - // check for finished job - if (LinkedList1_IsEmpty(&o->finished_list)) { - ASSERT_FORCE(pthread_mutex_unlock(&o->mutex) == 0) - return; - } - - // grab finished job - BThreadWork *w = UPPER_OBJECT(LinkedList1_GetFirst(&o->finished_list), BThreadWork, list_node); - ASSERT(w->state == BTHREADWORK_STATE_FINISHED) - LinkedList1_Remove(&o->finished_list, &w->list_node); - - // schedule more - if (!LinkedList1_IsEmpty(&o->finished_list)) { - BPending_Set(&o->more_job); - } - - // set state forgotten - w->state = BTHREADWORK_STATE_FORGOTTEN; - - // unlock - ASSERT_FORCE(pthread_mutex_unlock(&o->mutex) == 0) - - // call handler - w->handler_done(w->user); - return; -} - -static void pipe_fd_handler (BThreadWorkDispatcher *o, int events) -{ - ASSERT(o->num_threads > 0) - DebugObject_Access(&o->d_obj); - - // read data from pipe - uint8_t b[64]; - int res = read(o->pipe[0], b, sizeof(b)); - if (res < 0) { - int error = errno; - ASSERT_FORCE(error == EAGAIN || error == EWOULDBLOCK) - } else { - ASSERT(res > 0) - } - - dispatch_job(o); - return; -} - -static void more_job_handler (BThreadWorkDispatcher *o) -{ - ASSERT(o->num_threads > 0) - DebugObject_Access(&o->d_obj); - - dispatch_job(o); - return; -} - -static void stop_threads (BThreadWorkDispatcher *o) -{ - // set cancelling - ASSERT_FORCE(pthread_mutex_lock(&o->mutex) == 0) - o->cancel = 1; - ASSERT_FORCE(pthread_mutex_unlock(&o->mutex) == 0) - - while (o->num_threads > 0) { - struct BThreadWorkDispatcher_thread *t = &o->threads[o->num_threads - 1]; - - // wake up thread - ASSERT_FORCE(pthread_cond_signal(&t->new_cond) == 0) - - // wait for thread to exit - ASSERT_FORCE(pthread_join(t->thread, NULL) == 0) - - // free condition variable - ASSERT_FORCE(pthread_cond_destroy(&t->new_cond) == 0) - - o->num_threads--; - } -} - -#endif - -static void work_job_handler (BThreadWork *o) -{ - #ifdef BADVPN_THREADWORK_USE_PTHREAD - ASSERT(o->d->num_threads == 0) - #endif - DebugObject_Access(&o->d_obj); - - // do the work - o->work_func(o->work_func_user); - - // call handler - o->handler_done(o->user); - return; -} - -int BThreadWorkDispatcher_Init (BThreadWorkDispatcher *o, BReactor *reactor, int num_threads_hint) -{ - // init arguments - o->reactor = reactor; - - if (num_threads_hint < 0) { - num_threads_hint = 2; - } - if (num_threads_hint > BTHREADWORK_MAX_THREADS) { - num_threads_hint = BTHREADWORK_MAX_THREADS; - } - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - - if (num_threads_hint > 0) { - // init pending list - LinkedList1_Init(&o->pending_list); - - // init finished list - LinkedList1_Init(&o->finished_list); - - // init mutex - if (pthread_mutex_init(&o->mutex, NULL) != 0) { - BLog(BLOG_ERROR, "pthread_mutex_init failed"); - goto fail0; - } - - // init pipe - if (pipe(o->pipe) < 0) { - BLog(BLOG_ERROR, "pipe failed"); - goto fail1; - } - - // set read end non-blocking - if (fcntl(o->pipe[0], F_SETFL, O_NONBLOCK) < 0) { - BLog(BLOG_ERROR, "fcntl failed"); - goto fail2; - } - - // set write end non-blocking - if (fcntl(o->pipe[1], F_SETFL, O_NONBLOCK) < 0) { - BLog(BLOG_ERROR, "fcntl failed"); - goto fail2; - } - - // init BFileDescriptor - BFileDescriptor_Init(&o->bfd, o->pipe[0], (BFileDescriptor_handler)pipe_fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail2; - } - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, BREACTOR_READ); - - // init more job - BPending_Init(&o->more_job, BReactor_PendingGroup(o->reactor), (BPending_handler)more_job_handler, o); - - // set not cancelling - o->cancel = 0; - - // init threads - o->num_threads = 0; - for (int i = 0; i < num_threads_hint; i++) { - struct BThreadWorkDispatcher_thread *t = &o->threads[i]; - - // set parent pointer - t->d = o; - - // set no running work - t->running_work = NULL; - - // init condition variable - if (pthread_cond_init(&t->new_cond, NULL) != 0) { - BLog(BLOG_ERROR, "pthread_cond_init failed"); - goto fail3; - } - - // init thread - if (pthread_create(&t->thread, NULL, (void * (*) (void *))dispatcher_thread, t) != 0) { - BLog(BLOG_ERROR, "pthread_create failed"); - ASSERT_FORCE(pthread_cond_destroy(&t->new_cond) == 0) - goto fail3; - } - - o->num_threads++; - } - } - - #endif - - DebugObject_Init(&o->d_obj); - DebugCounter_Init(&o->d_ctr); - return 1; - - #ifdef BADVPN_THREADWORK_USE_PTHREAD -fail3: - stop_threads(o); - BPending_Free(&o->more_job); - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); -fail2: - ASSERT_FORCE(close(o->pipe[0]) == 0) - ASSERT_FORCE(close(o->pipe[1]) == 0) -fail1: - ASSERT_FORCE(pthread_mutex_destroy(&o->mutex) == 0) -fail0: - return 0; - #endif -} - -void BThreadWorkDispatcher_Free (BThreadWorkDispatcher *o) -{ - #ifdef BADVPN_THREADWORK_USE_PTHREAD - if (o->num_threads > 0) { - ASSERT(LinkedList1_IsEmpty(&o->pending_list)) - for (int i = 0; i < o->num_threads; i++) { ASSERT(!o->threads[i].running_work) } - ASSERT(LinkedList1_IsEmpty(&o->finished_list)) - } - #endif - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - - if (o->num_threads > 0) { - // stop threads - stop_threads(o); - - // free more job - BPending_Free(&o->more_job); - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - // free pipe - ASSERT_FORCE(close(o->pipe[0]) == 0) - ASSERT_FORCE(close(o->pipe[1]) == 0) - - // free mutex - ASSERT_FORCE(pthread_mutex_destroy(&o->mutex) == 0) - } - - #endif -} - -int BThreadWorkDispatcher_UsingThreads (BThreadWorkDispatcher *o) -{ - #ifdef BADVPN_THREADWORK_USE_PTHREAD - return (o->num_threads > 0); - #else - return 0; - #endif -} - -void BThreadWork_Init (BThreadWork *o, BThreadWorkDispatcher *d, BThreadWork_handler_done handler_done, void *user, BThreadWork_work_func work_func, void *work_func_user) -{ - DebugObject_Access(&d->d_obj); - - // init arguments - o->d = d; - o->handler_done = handler_done; - o->user = user; - o->work_func = work_func; - o->work_func_user = work_func_user; - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - if (d->num_threads > 0) { - // set state - o->state = BTHREADWORK_STATE_PENDING; - - // init finished semaphore - ASSERT_FORCE(sem_init(&o->finished_sem, 0, 0) == 0) - - // post work - ASSERT_FORCE(pthread_mutex_lock(&d->mutex) == 0) - LinkedList1_Append(&d->pending_list, &o->list_node); - for (int i = 0; i < d->num_threads; i++) { - if (!d->threads[i].running_work) { - ASSERT_FORCE(pthread_cond_signal(&d->threads[i].new_cond) == 0) - break; - } - } - ASSERT_FORCE(pthread_mutex_unlock(&d->mutex) == 0) - } else { - #endif - // schedule job - BPending_Init(&o->job, BReactor_PendingGroup(d->reactor), (BPending_handler)work_job_handler, o); - BPending_Set(&o->job); - #ifdef BADVPN_THREADWORK_USE_PTHREAD - } - #endif - - DebugObject_Init(&o->d_obj); - DebugCounter_Increment(&d->d_ctr); -} - -void BThreadWork_Free (BThreadWork *o) -{ - BThreadWorkDispatcher *d = o->d; - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&d->d_ctr); - - #ifdef BADVPN_THREADWORK_USE_PTHREAD - if (d->num_threads > 0) { - ASSERT_FORCE(pthread_mutex_lock(&d->mutex) == 0) - - switch (o->state) { - case BTHREADWORK_STATE_PENDING: { - BLog(BLOG_DEBUG, "remove pending work"); - - // remove from pending list - LinkedList1_Remove(&d->pending_list, &o->list_node); - } break; - - case BTHREADWORK_STATE_RUNNING: { - BLog(BLOG_DEBUG, "remove running work"); - - // wait for the work to finish running - ASSERT_FORCE(pthread_mutex_unlock(&d->mutex) == 0) - ASSERT_FORCE(sem_wait(&o->finished_sem) == 0) - ASSERT_FORCE(pthread_mutex_lock(&d->mutex) == 0) - - ASSERT(o->state == BTHREADWORK_STATE_FINISHED) - - // remove from finished list - LinkedList1_Remove(&d->finished_list, &o->list_node); - } break; - - case BTHREADWORK_STATE_FINISHED: { - BLog(BLOG_DEBUG, "remove finished work"); - - // remove from finished list - LinkedList1_Remove(&d->finished_list, &o->list_node); - } break; - - case BTHREADWORK_STATE_FORGOTTEN: { - BLog(BLOG_DEBUG, "remove forgotten work"); - } break; - - default: - ASSERT(0); - } - - ASSERT_FORCE(pthread_mutex_unlock(&d->mutex) == 0) - - // free finished semaphore - ASSERT_FORCE(sem_destroy(&o->finished_sem) == 0) - } else { - #endif - BPending_Free(&o->job); - #ifdef BADVPN_THREADWORK_USE_PTHREAD - } - #endif -} diff --git a/external/badvpn_dns/threadwork/BThreadWork.h b/external/badvpn_dns/threadwork/BThreadWork.h deleted file mode 100644 index e29c080..0000000 --- a/external/badvpn_dns/threadwork/BThreadWork.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file BThreadWork.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * System for performing computations (possibly) in parallel with the event loop - * in a different thread. - */ - -#ifndef BADVPN_BTHREADWORK_BTHREADWORK_H -#define BADVPN_BTHREADWORK_BTHREADWORK_H - -#ifdef BADVPN_THREADWORK_USE_PTHREAD - #include <pthread.h> - #include <semaphore.h> -#endif - -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> - -#define BTHREADWORK_STATE_PENDING 1 -#define BTHREADWORK_STATE_RUNNING 2 -#define BTHREADWORK_STATE_FINISHED 3 -#define BTHREADWORK_STATE_FORGOTTEN 4 - -#define BTHREADWORK_MAX_THREADS 8 - -struct BThreadWork_s; -struct BThreadWorkDispatcher_s; - -/** - * Function called to do the work for a {@link BThreadWork}. - * The function may be called in another thread, in parallel with the event loop. - * - * @param user as work_func_user in {@link BThreadWork_Init} - */ -typedef void (*BThreadWork_work_func) (void *user); - -/** - * Handler called when a {@link BThreadWork} work is done. - * - * @param user as in {@link BThreadWork_Init} - */ -typedef void (*BThreadWork_handler_done) (void *user); - -#ifdef BADVPN_THREADWORK_USE_PTHREAD -struct BThreadWorkDispatcher_thread { - struct BThreadWorkDispatcher_s *d; - struct BThreadWork_s *running_work; - pthread_cond_t new_cond; - pthread_t thread; -}; -#endif - -typedef struct BThreadWorkDispatcher_s { - BReactor *reactor; - #ifdef BADVPN_THREADWORK_USE_PTHREAD - LinkedList1 pending_list; - LinkedList1 finished_list; - pthread_mutex_t mutex; - int pipe[2]; - BFileDescriptor bfd; - BPending more_job; - int cancel; - int num_threads; - struct BThreadWorkDispatcher_thread threads[BTHREADWORK_MAX_THREADS]; - #endif - DebugObject d_obj; - DebugCounter d_ctr; -} BThreadWorkDispatcher; - -typedef struct BThreadWork_s { - BThreadWorkDispatcher *d; - BThreadWork_handler_done handler_done; - void *user; - BThreadWork_work_func work_func; - void *work_func_user; - union { - #ifdef BADVPN_THREADWORK_USE_PTHREAD - struct { - LinkedList1Node list_node; - int state; - sem_t finished_sem; - }; - #endif - struct { - BPending job; - }; - }; - DebugObject d_obj; -} BThreadWork; - -/** - * Initializes the work dispatcher. - * Works may be started using {@link BThreadWork_Init}. - * - * @param o the object - * @param reactor reactor we live in - * @param num_threads_hint hint for the number of threads to use: - * <0 - A choice will be made automatically, probably based on the number of CPUs. - * 0 - No additional threads will be used, and computations will be performed directly - * in the event loop in job handlers. - * @return 1 on success, 0 on failure - */ -int BThreadWorkDispatcher_Init (BThreadWorkDispatcher *o, BReactor *reactor, int num_threads_hint) WARN_UNUSED; - -/** - * Frees the work dispatcher. - * There must be no {@link BThreadWork}'s with this dispatcher. - * - * @param o the object - */ -void BThreadWorkDispatcher_Free (BThreadWorkDispatcher *o); - -/** - * Determines whether threads are being used for computations, or computations - * are done in the event loop. - * - * @return 1 if threads are being used, 0 if not - */ -int BThreadWorkDispatcher_UsingThreads (BThreadWorkDispatcher *o); - -/** - * Initializes the work. - * - * @param o the object - * @param d work dispatcher - * @param handler_done handler to call when the work is done - * @param user argument to handler - * @param work_func function that will do the work, possibly from another thread - * @param work_func_user argument to work_func - */ -void BThreadWork_Init (BThreadWork *o, BThreadWorkDispatcher *d, BThreadWork_handler_done handler_done, void *user, BThreadWork_work_func work_func, void *work_func_user); - -/** - * Frees the work. - * After this function returns, the work function will either have fully executed, - * or not called at all, and never will be. - * - * @param o the object - */ -void BThreadWork_Free (BThreadWork *o); - -#endif diff --git a/external/badvpn_dns/threadwork/CMakeLists.txt b/external/badvpn_dns/threadwork/CMakeLists.txt deleted file mode 100644 index 5f223ae..0000000 --- a/external/badvpn_dns/threadwork/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(BADVPN_THREADWORK_EXTRA_LIBS) -if (BADVPN_THREADWORK_USE_PTHREAD) - list(APPEND BADVPN_THREADWORK_EXTRA_LIBS pthread) -endif () - -badvpn_add_library(threadwork "system" "${BADVPN_THREADWORK_EXTRA_LIBS}" BThreadWork.c) diff --git a/external/badvpn_dns/tun2socks/CMakeLists.txt b/external/badvpn_dns/tun2socks/CMakeLists.txt deleted file mode 100644 index 8c8597c..0000000 --- a/external/badvpn_dns/tun2socks/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_executable(badvpn-tun2socks - tun2socks.c - SocksUdpGwClient.c -) -target_link_libraries(badvpn-tun2socks system flow tuntap lwip socksclient udpgw_client) - -install( - TARGETS badvpn-tun2socks - RUNTIME DESTINATION bin -) - -install( - FILES badvpn-tun2socks.8 - DESTINATION share/man/man8 -) diff --git a/external/badvpn_dns/tun2socks/SocksUdpGwClient.c b/external/badvpn_dns/tun2socks/SocksUdpGwClient.c deleted file mode 100644 index 949d114..0000000 --- a/external/badvpn_dns/tun2socks/SocksUdpGwClient.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <misc/debug.h> -#include <base/BLog.h> - -#include <tun2socks/SocksUdpGwClient.h> - -#include <generated/blog_channel_SocksUdpGwClient.h> - -static void free_socks (SocksUdpGwClient *o); -static void try_connect (SocksUdpGwClient *o); -static void reconnect_timer_handler (SocksUdpGwClient *o); -static void socks_client_handler (SocksUdpGwClient *o, int event); -static void udpgw_handler_servererror (SocksUdpGwClient *o); -static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len); - -static void free_socks (SocksUdpGwClient *o) -{ - ASSERT(o->have_socks) - - // disconnect udpgw client from SOCKS - if (o->socks_up) { - UdpGwClient_DisconnectServer(&o->udpgw_client); - } - - // free SOCKS client - BSocksClient_Free(&o->socks_client); - - // set have no SOCKS - o->have_socks = 0; -} - -static void try_connect (SocksUdpGwClient *o) -{ - ASSERT(!o->have_socks) - ASSERT(!BTimer_IsRunning(&o->reconnect_timer)) - - // init SOCKS client - if (!BSocksClient_Init(&o->socks_client, o->socks_server_addr, o->auth_info, o->num_auth_info, o->remote_udpgw_addr, (BSocksClient_handler)socks_client_handler, o, o->reactor)) { - BLog(BLOG_ERROR, "BSocksClient_Init failed"); - goto fail0; - } - - // set have SOCKS - o->have_socks = 1; - - // set SOCKS not up - o->socks_up = 0; - - return; - -fail0: - // set reconnect timer - BReactor_SetTimer(o->reactor, &o->reconnect_timer); -} - -static void reconnect_timer_handler (SocksUdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_socks) - - // try connecting - try_connect(o); -} - -static void socks_client_handler (SocksUdpGwClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_socks) - - switch (event) { - case BSOCKSCLIENT_EVENT_UP: { - ASSERT(!o->socks_up) - - BLog(BLOG_INFO, "SOCKS up"); - - // connect udpgw client to SOCKS - if (!UdpGwClient_ConnectServer(&o->udpgw_client, BSocksClient_GetSendInterface(&o->socks_client), BSocksClient_GetRecvInterface(&o->socks_client))) { - BLog(BLOG_ERROR, "UdpGwClient_ConnectServer failed"); - goto fail0; - } - - // set SOCKS up - o->socks_up = 1; - - return; - - fail0: - // free SOCKS - free_socks(o); - - // set reconnect timer - BReactor_SetTimer(o->reactor, &o->reconnect_timer); - } break; - - case BSOCKSCLIENT_EVENT_ERROR: - case BSOCKSCLIENT_EVENT_ERROR_CLOSED: { - BLog(BLOG_INFO, "SOCKS error"); - - // free SOCKS - free_socks(o); - - // set reconnect timer - BReactor_SetTimer(o->reactor, &o->reconnect_timer); - } break; - - default: ASSERT(0); - } -} - -static void udpgw_handler_servererror (SocksUdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_socks) - ASSERT(o->socks_up) - - BLog(BLOG_ERROR, "client reports server error"); - - // free SOCKS - free_socks(o); - - // set reconnect timer - BReactor_SetTimer(o->reactor, &o->reconnect_timer); -} - -static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // submit to user - o->handler_received(o->user, local_addr, remote_addr, data, data_len); - return; -} - -int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, - BAddr socks_server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info, - BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user, - SocksUdpGwClient_handler_received handler_received) -{ - // see asserts in UdpGwClient_Init - ASSERT(!BAddr_IsInvalid(&socks_server_addr)) - ASSERT(remote_udpgw_addr.type == BADDR_TYPE_IPV4 || remote_udpgw_addr.type == BADDR_TYPE_IPV6) - - // init arguments - o->udp_mtu = udp_mtu; - o->socks_server_addr = socks_server_addr; - o->auth_info = auth_info; - o->num_auth_info = num_auth_info; - o->remote_udpgw_addr = remote_udpgw_addr; - o->reactor = reactor; - o->user = user; - o->handler_received = handler_received; - - // init udpgw client - if (!UdpGwClient_Init(&o->udpgw_client, udp_mtu, max_connections, send_buffer_size, keepalive_time, o->reactor, o, - (UdpGwClient_handler_servererror)udpgw_handler_servererror, - (UdpGwClient_handler_received)udpgw_handler_received - )) { - goto fail0; - } - - // init reconnect timer - BTimer_Init(&o->reconnect_timer, reconnect_time, (BTimer_handler)reconnect_timer_handler, o); - - // set have no SOCKS - o->have_socks = 0; - - // try connecting - try_connect(o); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void SocksUdpGwClient_Free (SocksUdpGwClient *o) -{ - DebugObject_Free(&o->d_obj); - - // free SOCKS - if (o->have_socks) { - free_socks(o); - } - - // free reconnect timer - BReactor_RemoveTimer(o->reactor, &o->reconnect_timer); - - // free udpgw client - UdpGwClient_Free(&o->udpgw_client); -} - -void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - // see asserts in UdpGwClient_SubmitPacket - - // submit to udpgw client - UdpGwClient_SubmitPacket(&o->udpgw_client, local_addr, remote_addr, is_dns, data, data_len); -} - diff --git a/external/badvpn_dns/tun2socks/SocksUdpGwClient.h b/external/badvpn_dns/tun2socks/SocksUdpGwClient.h deleted file mode 100644 index 217e0ec..0000000 --- a/external/badvpn_dns/tun2socks/SocksUdpGwClient.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_TUN2SOCKS_SOCKSUDPGWCLIENT_H -#define BADVPN_TUN2SOCKS_SOCKSUDPGWCLIENT_H - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <udpgw_client/UdpGwClient.h> -#include <socksclient/BSocksClient.h> - -typedef void (*SocksUdpGwClient_handler_received) (void *user, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len); - -typedef struct { - int udp_mtu; - BAddr socks_server_addr; - const struct BSocksClient_auth_info *auth_info; - size_t num_auth_info; - BAddr remote_udpgw_addr; - BReactor *reactor; - void *user; - SocksUdpGwClient_handler_received handler_received; - UdpGwClient udpgw_client; - BTimer reconnect_timer; - int have_socks; - BSocksClient socks_client; - int socks_up; - DebugObject d_obj; -} SocksUdpGwClient; - -int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, - BAddr socks_server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info, - BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user, - SocksUdpGwClient_handler_received handler_received) WARN_UNUSED; -void SocksUdpGwClient_Free (SocksUdpGwClient *o); -void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len); - -#endif diff --git a/external/badvpn_dns/tun2socks/badvpn-tun2socks.8 b/external/badvpn_dns/tun2socks/badvpn-tun2socks.8 deleted file mode 100644 index d1ab50c..0000000 --- a/external/badvpn_dns/tun2socks/badvpn-tun2socks.8 +++ /dev/null @@ -1,126 +0,0 @@ -.TH badvpn-tun2socks 8 "February 2012" -.SH NAME -badvpn-tun2socks - create a TUN device to route TCP traffic through a SOCKS server -.SH SYNOPSIS -.PP -.B -badvpn-tun2socks -.br - [\fB--help\fR] -.br - [\fB--version\fR] -.br - [\fB--logger\fR <stdout/syslog>] -.br - [\fB--syslog-facility\fR <string>] [\fB--syslog-ident\fR <string>] -.br - [\fB--loglevel\fR <0-5/none/error/warning/notice/info/debug>] -.br - [\fB--channel-loglevel\fR <channel-name> <0-5/none/error/warning/notice/info/debug>] ... -.br - [\fB--tundev\fR <name>] -.br - \fB--netif-ipaddr\fR <ipaddr> -.br - \fB--netif-netmask\fR <ipnetmask> -.br - \fB--socks-server-addr\fR <addr> -.br - [\fB--udpgw-remote-server-addr\fR <addr>] -.br - [\fB--udpgw-max-connections\fR <number>] -.br - [\fB--udpgw-connection-buffer-size\fR <number>] -.PP -Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6). -.SH DESCRIPTION -.PP -badvpn-tun2socks -is a network utility used to "socksify" TCP connections at the network -layer. It implements a TUN device which accepts all incoming TCP -connections (regardless of destination IP), and forwards them through -a SOCKS server. This allows you to forward all connections through -SOCKS, without any need for application support. It can be used, for -example, to forward connections through a remote SSH server. -.SH EXAMPLE -.PP -This example demonstrates using tun2socks in combination with SSH's dynamic forwarding feature. - -Connect to the SSH server, passing -D localhost:1080 to the ssh -command to enable dynamic forwarding. This will make ssh open a local -SOCKS server which tun2socks forward connection through. - -First create a TUN device (eg. using openvpn): - -.nf - openvpn --mktun --dev tun0 --user <someuser> -.fi - -Configure the IP of the new tun device: - -.nf - ifconfig tun0 10.0.0.1 netmask 255.255.255.0 -.fi - -Now start the badvpn-tun2socks program: - -.nf - badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 \ - --socks-server-addr 127.0.0.1:1080 -.fi - -Note that the address 10.0.0.2 is not a typo. It specifies the IP address of the virtual -router inside the TUN device, and must be different from the IP of the -TUN interface itself (but in the same subnet). - -Now you should be able to ping the virtual router's IP (10.0.0.2): - -.nf - ping -n 10.0.0.2 -.fi - -All that remains is to route connections through the TUN device -instead of the existing default gateway. This is done as follows: - -1. Add a route to the SSH server through your existing gateway, with a -lower metric than the original default route. - -2. If your DNS servers are in a network that is not direcly attached (e.g. in the Internet), -also add routes for them (like for the SSH server). This is -needed because tun2socks does not forward UDP by default (see below). - -3. Add a default route through the virtual router in the TUN device, -with a lower metric than the original default route, but higher than -the SSH and DNS routes. - -This will make all external connections go through the TUN device, -except for the SSH connection (else SSH would go through the TUN -device, which would go through... SSH). - -For example (assuming there are no existing default routes with metric -<=6; otherwise remove them or change their metrics): - -.nf - route add <IP_of_SSH_server> gw <IP_of_original_gateway> metric 5 - <same for DNS> - route add default gw 10.0.0.2 metric 6 -.fi -.SH UDP FORWARDING -tun2socks can forward UDP, however this requires a forwarder daemon, badvpn-udpgw to run -on the remote SSH server: - -.nf - badvpn-udpgw --listen-addr 127.0.0.1:7300 -.fi - -Then tell tun2socks to forward UDP via the forwarder: - -.nf - --udpgw-remote-server-addr 127.0.0.1:7300 -.fi -.SH COPYRIGHT -.PP -Copyright (co 2010 Ambroz Bizjak ambrop7@gmail.com -.br -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/external/badvpn_dns/tun2socks/tun2socks.c b/external/badvpn_dns/tun2socks/tun2socks.c deleted file mode 100644 index 51c3fb9..0000000 --- a/external/badvpn_dns/tun2socks/tun2socks.c +++ /dev/null @@ -1,2138 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdint.h> -#include <stdio.h> -#include <stddef.h> -#include <string.h> -#include <limits.h> - -// PSIPHON -#include "jni.h" - -#include <misc/version.h> -#include <misc/loggers_string.h> -#include <misc/loglevel.h> -#include <misc/minmax.h> -#include <misc/offset.h> -#include <misc/dead.h> -#include <misc/ipv4_proto.h> -#include <misc/ipv6_proto.h> -#include <misc/udp_proto.h> -#include <misc/byteorder.h> -#include <misc/balloc.h> -#include <misc/open_standard_streams.h> -#include <misc/read_file.h> -#include <misc/ipaddr6.h> -#include <misc/concat_strings.h> -#include <structure/LinkedList1.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BSignal.h> -#include <system/BAddr.h> -#include <system/BNetwork.h> -#include <flow/SinglePacketBuffer.h> -#include <socksclient/BSocksClient.h> -#include <tuntap/BTap.h> -#include <lwip/init.h> -#include <lwip/tcp_impl.h> -#include <lwip/netif.h> -#include <lwip/tcp.h> -#include <tun2socks/SocksUdpGwClient.h> - -#ifndef BADVPN_USE_WINAPI -#include <base/BLog_syslog.h> -#endif - -#include <tun2socks/tun2socks.h> - -#include <generated/blog_channel_tun2socks.h> - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -#define SYNC_DECL \ - BPending sync_mark; \ - -#define SYNC_FROMHERE \ - BPending_Init(&sync_mark, BReactor_PendingGroup(&ss), NULL, NULL); \ - BPending_Set(&sync_mark); - -#define SYNC_BREAK \ - BPending_Free(&sync_mark); - -#define SYNC_COMMIT \ - BReactor_Synchronize(&ss, &sync_mark.base); \ - BPending_Free(&sync_mark); - - -// command-line options -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - char *tundev; - char *netif_ipaddr; - char *netif_netmask; - char *netif_ip6addr; - char *socks_server_addr; - char *username; - char *password; - char *password_file; - int append_source_to_username; - char *udpgw_remote_server_addr; - int udpgw_max_connections; - int udpgw_connection_buffer_size; - int udpgw_transparent_dns; - - // ==== PSIPHON ==== - int tun_fd; - int tun_mtu; - int set_signal; - // ==== PSIPHON ==== -} options; - -// TCP client -struct tcp_client { - dead_t dead; - dead_t dead_client; - LinkedList1Node list_node; - BAddr local_addr; - BAddr remote_addr; - struct tcp_pcb *pcb; - int client_closed; - uint8_t buf[TCP_WND]; - int buf_used; - char *socks_username; - BSocksClient socks_client; - int socks_up; - int socks_closed; - StreamPassInterface *socks_send_if; - StreamRecvInterface *socks_recv_if; - uint8_t socks_recv_buf[CLIENT_SOCKS_RECV_BUF_SIZE]; - int socks_recv_buf_used; - int socks_recv_buf_sent; - int socks_recv_waiting; - int socks_recv_tcp_pending; -}; - -// IP address of netif -BIPAddr netif_ipaddr; - -// netmask of netif -BIPAddr netif_netmask; - -// IP6 address of netif -struct ipv6_addr netif_ip6addr; - -// SOCKS server address -BAddr socks_server_addr; - -// allocated password file contents -uint8_t *password_file_contents; - -// SOCKS authentication information -struct BSocksClient_auth_info socks_auth_info[2]; -size_t socks_num_auth_info; - -// remote udpgw server addr, if provided -BAddr udpgw_remote_server_addr; - -// reactor -BReactor ss; - -// set to 1 by terminate -int quitting; - -// TUN device -BTap device; - -// device write buffer -uint8_t *device_write_buf; - -// device reading -SinglePacketBuffer device_read_buffer; -PacketPassInterface device_read_interface; - -// udpgw client -SocksUdpGwClient udpgw_client; -int udp_mtu; - -// TCP timer -BTimer tcp_timer; - -// job for initializing lwip -BPending lwip_init_job; - -// lwip netif -int have_netif; -struct netif netif; - -// lwip TCP listener -struct tcp_pcb *listener; - -// lwip TCP/IPv6 listener -struct tcp_pcb *listener_ip6; - -// TCP clients -LinkedList1 tcp_clients; - -// number of clients -int num_clients; - -// ==== PSIPHON ==== -static void run (void); -static void init_arguments (const char* program_name); -// ==== PSIPHON ==== - -static void terminate (void); -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static BAddr baddr_from_lwip (int is_ipv6, const ipX_addr_t *ipx_addr, uint16_t port_hostorder); -static void lwip_init_job_hadler (void *unused); -static void tcp_timer_handler (void *unused); -static void device_error_handler (void *unused); -static void device_read_handler_send (void *unused, uint8_t *data, int data_len); -static int process_device_udp_packet (uint8_t *data, int data_len); -static err_t netif_init_func (struct netif *netif); -static err_t netif_output_func (struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr); -static err_t netif_output_ip6_func (struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr); -static err_t common_netif_output (struct netif *netif, struct pbuf *p); -static err_t netif_input_func (struct pbuf *p, struct netif *inp); -static void client_logfunc (struct tcp_client *client); -static void client_log (struct tcp_client *client, int level, const char *fmt, ...); -static err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err); -static void client_handle_freed_client (struct tcp_client *client); -static void client_free_client (struct tcp_client *client); -static void client_abort_client (struct tcp_client *client); -static void client_free_socks (struct tcp_client *client); -static void client_murder (struct tcp_client *client); -static void client_dealloc (struct tcp_client *client); -static void client_err_func (void *arg, err_t err); -static err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); -static void client_socks_handler (struct tcp_client *client, int event); -static void client_send_to_socks (struct tcp_client *client); -static void client_socks_send_handler_done (struct tcp_client *client, int data_len); -static void client_socks_recv_initiate (struct tcp_client *client); -static void client_socks_recv_handler_done (struct tcp_client *client, int data_len); -static int client_socks_recv_send_out (struct tcp_client *client); -static err_t client_sent_func (void *arg, struct tcp_pcb *tpcb, u16_t len); -static void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len); - - -//==== PSIPHON ==== - - -JNIEnv* g_env = 0; - -void PsiphonLog(const char *levelStr, const char *channelStr, const char *msgStr) -{ - if (!g_env) - { - return; - } - // Note: we could cache the class and method references if log is called frequently - - jstring level = (*g_env)->NewStringUTF(g_env, levelStr); - jstring channel = (*g_env)->NewStringUTF(g_env, channelStr); - jstring msg = (*g_env)->NewStringUTF(g_env, msgStr); - - jclass cls = (*g_env)->FindClass(g_env, "org/torproject/android/vpn/Tun2Socks"); - jmethodID logMethod = (*g_env)->GetStaticMethodID(g_env, cls, "logTun2Socks", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - (*g_env)->CallStaticVoidMethod(g_env, cls, logMethod, level, channel, msg); - - (*g_env)->DeleteLocalRef(g_env, cls); - - (*g_env)->DeleteLocalRef(g_env, level); - (*g_env)->DeleteLocalRef(g_env, channel); - (*g_env)->DeleteLocalRef(g_env, msg); -} - -// org.torproject.android.vpn.Tun2Socks.runTun2Socks -JNIEXPORT jint JNICALL Java_org_torproject_android_vpn_Tun2Socks_runTun2Socks( - JNIEnv* env, - jclass cls, - jint vpnInterfaceFileDescriptor, - jint vpnInterfaceMTU, - jstring vpnIpAddress, - jstring vpnNetMask, - jstring socksServerAddress, - jstring udpgwServerAddress, - jint udpgwTransparentDNS) -{ - g_env = env; - - const char* vpnIpAddressStr = (*env)->GetStringUTFChars(env, vpnIpAddress, 0); - const char* vpnNetMaskStr = (*env)->GetStringUTFChars(env, vpnNetMask, 0); - const char* socksServerAddressStr = (*env)->GetStringUTFChars(env, socksServerAddress, 0); - const char* udpgwServerAddressStr = (*env)->GetStringUTFChars(env, udpgwServerAddress, 0); - - init_arguments("Drobot tun2socks"); - - options.netif_ipaddr = (char*)vpnIpAddressStr; - options.netif_netmask = (char*)vpnNetMaskStr; - options.socks_server_addr = (char*)socksServerAddressStr; - options.udpgw_remote_server_addr = (char*)udpgwServerAddressStr; - options.udpgw_transparent_dns = udpgwTransparentDNS; - options.tun_fd = vpnInterfaceFileDescriptor; - options.tun_mtu = vpnInterfaceMTU; - options.set_signal = 0; - options.loglevel = 4; - - BLog_InitPsiphon(); - - run(); - - (*env)->ReleaseStringUTFChars(env, vpnIpAddress, vpnIpAddressStr); - (*env)->ReleaseStringUTFChars(env, vpnNetMask, vpnNetMaskStr); - (*env)->ReleaseStringUTFChars(env, socksServerAddress, socksServerAddressStr); - (*env)->ReleaseStringUTFChars(env, udpgwServerAddress, udpgwServerAddressStr); - - g_env = 0; - - // TODO: return success/error - - return 1; -} - -JNIEXPORT jint JNICALL Java_org_torproject_android_vpn_Tun2Socks_terminateTun2Socks( - jclass cls, - JNIEnv* env) -{ - terminate(); - return 0; -} - -// from tcp_helper.c -/** Remove all pcbs on the given list. */ -static void tcp_remove(struct tcp_pcb* pcb_list) -{ - struct tcp_pcb *pcb = pcb_list; - struct tcp_pcb *pcb2; - - while(pcb != NULL) - { - pcb2 = pcb; - pcb = pcb->next; - tcp_abort(pcb2); - } -} - - - -void run() -{ - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // clear password contents pointer - password_file_contents = NULL; - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // set not quitting - quitting = 0; - - // PSIPHON - if (options.set_signal) { - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - } - - // PSIPHON - if (options.tun_fd) { - // use supplied file descriptor - if (!BTap_InitWithFD(&device, &ss, options.tun_fd, options.tun_mtu, device_error_handler, NULL, 1)) { - BLog(BLOG_ERROR, "BTap_InitWithFD failed"); - goto fail3; - } - } else { - // init TUN device - if (!BTap_Init(&device, &ss, options.tundev, device_error_handler, NULL, 1)) { - BLog(BLOG_ERROR, "BTap_Init failed"); - goto fail3; - } - } - - // NOTE: the order of the following is important: - // first device writing must evaluate, - // then lwip (so it can send packets to the device), - // then device reading (so it can pass received packets to lwip). - - // init device reading - PacketPassInterface_Init(&device_read_interface, BTap_GetMTU(&device), device_read_handler_send, NULL, BReactor_PendingGroup(&ss)); - if (!SinglePacketBuffer_Init(&device_read_buffer, BTap_GetOutput(&device), &device_read_interface, BReactor_PendingGroup(&ss))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail4; - } - - if (options.udpgw_remote_server_addr && !options.udpgw_transparent_dns) { - // compute maximum UDP payload size we need to pass through udpgw - udp_mtu = BTap_GetMTU(&device) - (int)(sizeof(struct ipv4_header) + sizeof(struct udp_header)); - if (options.netif_ip6addr) { - int udp_ip6_mtu = BTap_GetMTU(&device) - (int)(sizeof(struct ipv6_header) + sizeof(struct udp_header)); - if (udp_mtu < udp_ip6_mtu) { - udp_mtu = udp_ip6_mtu; - } - } - if (udp_mtu < 0) { - udp_mtu = 0; - } - - // make sure our UDP payloads aren't too large for udpgw - int udpgw_mtu = udpgw_compute_mtu(udp_mtu); - if (udpgw_mtu < 0 || udpgw_mtu > PACKETPROTO_MAXPAYLOAD) { - BLog(BLOG_ERROR, "device MTU is too large for UDP"); - goto fail4a; - } - - // init udpgw client - if (!SocksUdpGwClient_Init(&udpgw_client, udp_mtu, DEFAULT_UDPGW_MAX_CONNECTIONS, options.udpgw_connection_buffer_size, UDPGW_KEEPALIVE_TIME, - socks_server_addr, socks_auth_info, socks_num_auth_info, - udpgw_remote_server_addr, UDPGW_RECONNECT_TIME, &ss, NULL, udpgw_client_handler_received - )) { - BLog(BLOG_ERROR, "SocksUdpGwClient_Init failed"); - goto fail4a; - } - } - - // init lwip init job - BPending_Init(&lwip_init_job, BReactor_PendingGroup(&ss), lwip_init_job_hadler, NULL); - BPending_Set(&lwip_init_job); - - // init device write buffer - if (!(device_write_buf = (uint8_t *)BAlloc(BTap_GetMTU(&device)))) { - BLog(BLOG_ERROR, "BAlloc failed"); - goto fail5; - } - - // init TCP timer - // it won't trigger before lwip is initialized, becuase the lwip init is a job - BTimer_Init(&tcp_timer, TCP_TMR_INTERVAL, tcp_timer_handler, NULL); - BReactor_SetTimer(&ss, &tcp_timer); - - // set no netif - have_netif = 0; - - // set no listener - listener = NULL; - listener_ip6 = NULL; - - // init clients list - LinkedList1_Init(&tcp_clients); - - // init number of clients - num_clients = 0; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - // free clients - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&tcp_clients)) { - struct tcp_client *client = UPPER_OBJECT(node, struct tcp_client, list_node); - client_murder(client); - } - - // free listener - if (listener_ip6) { - tcp_close(listener_ip6); - } - if (listener) { - tcp_close(listener); - } - - // free netif - if (have_netif) { - netif_remove(&netif); - } - - // ==== PSIPHON ==== - // The existing tun2socks cleanup sometimes leaves some TCP connections - // in the TIME_WAIT state. With regular tun2socks, these will be cleaned up - // by process termination. Since we re-init tun2socks within one process, - // and tcp_bind_to_netif requires no TCP connections bound to the network - // interface, we need to explicitly clean these up. Since we're also closing - // both sources of tunneled packets (VPN fd and SOCKS sockets), there should - // be no need to keep these TCP connections in TIME_WAIT between tun2socks - // invocations. - // After further testing, we found at least one TCP connection left in the - // active list (with state SYN_RCVD). Now we're aborting the active list - // as well, and the bound list for good measure. - tcp_remove(tcp_bound_pcbs); - tcp_remove(tcp_active_pcbs); - tcp_remove(tcp_tw_pcbs); - // ==== PSIPHON ==== - - - BReactor_RemoveTimer(&ss, &tcp_timer); - BFree(device_write_buf); -fail5: - BPending_Free(&lwip_init_job); - if (options.udpgw_remote_server_addr && !options.udpgw_transparent_dns) { - SocksUdpGwClient_Free(&udpgw_client); - } -fail4a: - SinglePacketBuffer_Free(&device_read_buffer); -fail4: - PacketPassInterface_Free(&device_read_interface); - BTap_Free(&device); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&ss); -fail1: - BFree(password_file_contents); - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); -} - -void terminate (void) -{ - ASSERT(!quitting) - - BLog(BLOG_NOTICE, "tearing down"); - - // set quitting - quitting = 1; - - // exit event loop - BReactor_Quit(&ss, 1); -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--tundev <name>]\n" - " --netif-ipaddr <ipaddr>\n" - " --netif-netmask <ipnetmask>\n" - " --socks-server-addr <addr>\n" - " [--netif-ip6addr <addr>]\n" - " [--username <username>]\n" - " [--password <password>]\n" - " [--password-file <file>]\n" - " [--append-source-to-username]\n" - " [--udpgw-remote-server-addr <addr>]\n" - " [--udpgw-max-connections <number>]\n" - " [--udpgw-connection-buffer-size <number>]\n" - " [--udpgw-transparent-dns]\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -//==== PSIPHON ==== - -void init_arguments (const char* program_name) -{ - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = (char*)program_name; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.tundev = NULL; - options.netif_ipaddr = NULL; - options.netif_netmask = NULL; - options.netif_ip6addr = NULL; - options.socks_server_addr = NULL; - options.username = NULL; - options.password = NULL; - options.password_file = NULL; - options.append_source_to_username = 0; - options.udpgw_remote_server_addr = NULL; - options.udpgw_max_connections = DEFAULT_UDPGW_MAX_CONNECTIONS; - options.udpgw_connection_buffer_size = DEFAULT_UDPGW_CONNECTION_BUFFER_SIZE; - options.udpgw_transparent_dns = 0; - - options.tun_fd = 0; - options.set_signal = 1; -} - -//==== PSIPHON ==== - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - // PSIPHON - init_arguments(argv[0]); - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--tundev")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.tundev = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--netif-ipaddr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.netif_ipaddr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--netif-netmask")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.netif_netmask = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--netif-ip6addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.netif_ip6addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--socks-server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.socks_server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--username")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.username = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--password")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.password = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--password-file")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.password_file = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--append-source-to-username")) { - options.append_source_to_username = 1; - } - else if (!strcmp(arg, "--udpgw-remote-server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.udpgw_remote_server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--udpgw-max-connections")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.udpgw_max_connections = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--udpgw-connection-buffer-size")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.udpgw_connection_buffer_size = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--udpgw-transparent-dns")) { - options.udpgw_transparent_dns = 1; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.netif_ipaddr) { - fprintf(stderr, "--netif-ipaddr is required\n"); - return 0; - } - - if (!options.netif_netmask) { - fprintf(stderr, "--netif-netmask is required\n"); - return 0; - } - - if (!options.socks_server_addr) { - fprintf(stderr, "--socks-server-addr is required\n"); - return 0; - } - - if (options.username) { - if (!options.password && !options.password_file) { - fprintf(stderr, "username given but password not given\n"); - return 0; - } - - if (options.password && options.password_file) { - fprintf(stderr, "--password and --password-file cannot both be given\n"); - return 0; - } - } - - return 1; -} - -int process_arguments (void) -{ - ASSERT(!password_file_contents) - - // resolve netif ipaddr - if (!BIPAddr_Resolve(&netif_ipaddr, options.netif_ipaddr, 0)) { - BLog(BLOG_ERROR, "netif ipaddr: BIPAddr_Resolve failed"); - return 0; - } - if (netif_ipaddr.type != BADDR_TYPE_IPV4) { - BLog(BLOG_ERROR, "netif ipaddr: must be an IPv4 address"); - return 0; - } - - // resolve netif netmask - if (!BIPAddr_Resolve(&netif_netmask, options.netif_netmask, 0)) { - BLog(BLOG_ERROR, "netif netmask: BIPAddr_Resolve failed"); - return 0; - } - if (netif_netmask.type != BADDR_TYPE_IPV4) { - BLog(BLOG_ERROR, "netif netmask: must be an IPv4 address"); - return 0; - } - - // parse IP6 address - if (options.netif_ip6addr) { - if (!ipaddr6_parse_ipv6_addr(options.netif_ip6addr, &netif_ip6addr)) { - BLog(BLOG_ERROR, "netif ip6addr: incorrect"); - return 0; - } - } - - // resolve SOCKS server address - if (!BAddr_Parse2(&socks_server_addr, options.socks_server_addr, NULL, 0, 0)) { - BLog(BLOG_ERROR, "socks server addr: BAddr_Parse2 failed"); - return 0; - } - - // add none socks authentication method - socks_auth_info[0] = BSocksClient_auth_none(); - socks_num_auth_info = 1; - - // add password socks authentication method - if (options.username) { - const char *password; - size_t password_len; - if (options.password) { - password = options.password; - password_len = strlen(options.password); - } else { - if (!read_file(options.password_file, &password_file_contents, &password_len)) { - BLog(BLOG_ERROR, "failed to read password file"); - return 0; - } - password = (char *)password_file_contents; - } - - socks_auth_info[socks_num_auth_info++] = BSocksClient_auth_password( - options.username, strlen(options.username), - password, password_len - ); - } - - // resolve remote udpgw server address - if (options.udpgw_remote_server_addr) { - if (!BAddr_Parse2(&udpgw_remote_server_addr, options.udpgw_remote_server_addr, NULL, 0, 0)) { - BLog(BLOG_ERROR, "remote udpgw server addr: BAddr_Parse2 failed"); - return 0; - } - } - - return 1; -} - -void signal_handler (void *unused) -{ - ASSERT(!quitting) - - BLog(BLOG_NOTICE, "termination requested"); - - terminate(); -} - -BAddr baddr_from_lwip (int is_ipv6, const ipX_addr_t *ipx_addr, uint16_t port_hostorder) -{ - BAddr addr; - if (is_ipv6) { - BAddr_InitIPv6(&addr, (uint8_t *)ipx_addr->ip6.addr, hton16(port_hostorder)); - } else { - BAddr_InitIPv4(&addr, ipx_addr->ip4.addr, hton16(port_hostorder)); - } - return addr; -} - -void lwip_init_job_hadler (void *unused) -{ - ASSERT(!quitting) - ASSERT(netif_ipaddr.type == BADDR_TYPE_IPV4) - ASSERT(netif_netmask.type == BADDR_TYPE_IPV4) - ASSERT(!have_netif) - ASSERT(!listener) - ASSERT(!listener_ip6) - - BLog(BLOG_DEBUG, "lwip init"); - - // NOTE: the device may fail during this, but there's no harm in not checking - // for that at every step - - // init lwip - lwip_init(); - - // make addresses for netif - ip_addr_t addr; - addr.addr = netif_ipaddr.ipv4; - ip_addr_t netmask; - netmask.addr = netif_netmask.ipv4; - ip_addr_t gw; - ip_addr_set_any(&gw); - - // init netif - if (!netif_add(&netif, &addr, &netmask, &gw, NULL, netif_init_func, netif_input_func)) { - BLog(BLOG_ERROR, "netif_add failed"); - goto fail; - } - have_netif = 1; - - // set netif up - netif_set_up(&netif); - - // set netif pretend TCP - netif_set_pretend_tcp(&netif, 1); - - // set netif default - netif_set_default(&netif); - - if (options.netif_ip6addr) { - // add IPv6 address - memcpy(netif_ip6_addr(&netif, 0), netif_ip6addr.bytes, sizeof(netif_ip6addr.bytes)); - netif_ip6_addr_set_state(&netif, 0, IP6_ADDR_VALID); - } - - // init listener - struct tcp_pcb *l = tcp_new(); - if (!l) { - BLog(BLOG_ERROR, "tcp_new failed"); - goto fail; - } - - // bind listener - if (tcp_bind_to_netif(l, "ho0") != ERR_OK) { - BLog(BLOG_ERROR, "tcp_bind_to_netif failed"); - tcp_close(l); - goto fail; - } - - // listen listener - if (!(listener = tcp_listen(l))) { - BLog(BLOG_ERROR, "tcp_listen failed"); - tcp_close(l); - goto fail; - } - - // setup listener accept handler - tcp_accept(listener, listener_accept_func); - - if (options.netif_ip6addr) { - struct tcp_pcb *l_ip6 = tcp_new_ip6(); - if (!l_ip6) { - BLog(BLOG_ERROR, "tcp_new_ip6 failed"); - goto fail; - } - - if (tcp_bind_to_netif(l_ip6, "ho0") != ERR_OK) { - BLog(BLOG_ERROR, "tcp_bind_to_netif failed"); - tcp_close(l_ip6); - goto fail; - } - - if (!(listener_ip6 = tcp_listen(l_ip6))) { - BLog(BLOG_ERROR, "tcp_listen failed"); - tcp_close(l_ip6); - goto fail; - } - - tcp_accept(listener_ip6, listener_accept_func); - } - - return; - -fail: - if (!quitting) { - terminate(); - } -} - -void tcp_timer_handler (void *unused) -{ - ASSERT(!quitting) - - BLog(BLOG_DEBUG, "TCP timer"); - - // schedule next timer - // TODO: calculate timeout so we don't drift - BReactor_SetTimer(&ss, &tcp_timer); - - tcp_tmr(); - return; -} - -void device_error_handler (void *unused) -{ - ASSERT(!quitting) - - BLog(BLOG_ERROR, "device error"); - - terminate(); - return; -} - -void device_read_handler_send (void *unused, uint8_t *data, int data_len) -{ - ASSERT(!quitting) - ASSERT(data_len >= 0) - - BLog(BLOG_DEBUG, "device: received packet"); - - // accept packet - PacketPassInterface_Done(&device_read_interface); - - // process DNS directly - if (process_device_dns_packet(data, data_len)) { - BLog(BLOG_INFO, "end processing dns packet"); - return; - } - - // process UDP directly - if (process_device_udp_packet(data, data_len)) { - return; - } - - // obtain pbuf - if (data_len > UINT16_MAX) { - BLog(BLOG_WARNING, "device read: packet too large"); - return; - } - struct pbuf *p = pbuf_alloc(PBUF_RAW, data_len, PBUF_POOL); - if (!p) { - BLog(BLOG_WARNING, "device read: pbuf_alloc failed"); - return; - } - - // write packet to pbuf - ASSERT_FORCE(pbuf_take(p, data, data_len) == ERR_OK) - - // pass pbuf to input - if (netif.input(p, &netif) != ERR_OK) { - BLog(BLOG_WARNING, "device read: input failed"); - pbuf_free(p); - } -} - -int process_device_dns_packet (uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - - // do nothing if we don't have dnsgw - if (!options.udpgw_remote_server_addr || !options.udpgw_transparent_dns) { - BLog(BLOG_WARNING, "No dnsgw to process dns packet"); - goto fail; - } - - static BAddr local_addr; - static BAddr remote_addr; - static int init = 0; - - int to_dns; - int from_dns; - int packet_length = 0; - - uint8_t ip_version = 0; - if (data_len > 0) { - ip_version = (data[0] >> 4); - } - - switch (ip_version) { - case 4: { - // ignore non-UDP packets - if (data_len < sizeof(struct ipv4_header) || data[offsetof(struct ipv4_header, protocol)] != IPV4_PROTOCOL_UDP) { - goto fail; - } - - // parse IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check(data, data_len, &ipv4_header, &data, &data_len)) { - goto fail; - } - - // parse UDP - struct udp_header udp_header; - if (!udp_check(data, data_len, &udp_header, &data, &data_len)) { - goto fail; - } - - // verify UDP checksum - uint16_t checksum_in_packet = udp_header.checksum; - udp_header.checksum = 0; - uint16_t checksum_computed = udp_checksum(&udp_header, data, data_len, ipv4_header.source_address, ipv4_header.destination_address); - if (checksum_in_packet != checksum_computed) { - goto fail; - } - - // to port 53 is considered a DNS packet - to_dns = udp_header.dest_port == hton16(53); - - // from port 8153 is considered a DNS packet - from_dns = udp_header.source_port == udpgw_remote_server_addr.ipv4.port; - - // if not DNS packet, just bypass it. - if (!to_dns && !from_dns) { - BLog(BLOG_WARNING, "No to_dns and from_dns packet: bypass"); - goto fail; - } - - // modify DNS packet - if (to_dns) { - BLog(BLOG_INFO, "UDP: to DNS %d bytes", data_len); - - // construct addresses - if (!init) { - init = 1; - BAddr_InitIPv4(&local_addr, ipv4_header.source_address, udp_header.source_port); - BAddr_InitIPv4(&remote_addr, ipv4_header.destination_address, udp_header.dest_port); - } - - // build IP header - ipv4_header.destination_address = udpgw_remote_server_addr.ipv4.ip; - ipv4_header.source_address = netif_ipaddr.ipv4; - - // build UDP header - udp_header.dest_port = udpgw_remote_server_addr.ipv4.port; - - } else if (from_dns) { - - // if not initialized - if (!init) { - goto fail; - } - - BLog(BLOG_INFO, "UDP: from DNS %d bytes", data_len); - - // build IP header - ipv4_header.source_address = remote_addr.ipv4.ip; - ipv4_header.destination_address = local_addr.ipv4.ip; - - // build UDP header - udp_header.source_port = remote_addr.ipv4.port; - - } - - // update IPv4 header's checksum - ipv4_header.checksum = hton16(0); - ipv4_header.checksum = ipv4_checksum(&ipv4_header, NULL, 0); - - // update UDP header's checksum - udp_header.checksum = hton16(0); - udp_header.checksum = udp_checksum(&udp_header, data, data_len, - ipv4_header.source_address, ipv4_header.destination_address); - - // write packet - memcpy(device_write_buf, &ipv4_header, sizeof(ipv4_header)); - memcpy(device_write_buf + sizeof(ipv4_header), &udp_header, sizeof(udp_header)); - memcpy(device_write_buf + sizeof(ipv4_header) + sizeof(udp_header), data, data_len); - packet_length = sizeof(ipv4_header) + sizeof(udp_header) + data_len; - - } break; - - case 6: { - // TODO: support IPv6 DNS Gateway - goto fail; - } break; - - default: { - goto fail; - } break; - } - - // submit packet - BTap_Send(&device, device_write_buf, packet_length); - - return 1; - -fail: - return 0; -} - -int process_device_udp_packet (uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - - // do nothing if we don't have udpgw - if (!options.udpgw_remote_server_addr || options.udpgw_transparent_dns) { - goto fail; - } - - BAddr local_addr; - BAddr remote_addr; - int is_dns; - - uint8_t ip_version = 0; - if (data_len > 0) { - ip_version = (data[0] >> 4); - } - - switch (ip_version) { - case 4: { - // ignore non-UDP packets - if (data_len < sizeof(struct ipv4_header) || data[offsetof(struct ipv4_header, protocol)] != IPV4_PROTOCOL_UDP) { - goto fail; - } - - // parse IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check(data, data_len, &ipv4_header, &data, &data_len)) { - goto fail; - } - - // parse UDP - struct udp_header udp_header; - if (!udp_check(data, data_len, &udp_header, &data, &data_len)) { - goto fail; - } - - // verify UDP checksum - uint16_t checksum_in_packet = udp_header.checksum; - udp_header.checksum = 0; - uint16_t checksum_computed = udp_checksum(&udp_header, data, data_len, ipv4_header.source_address, ipv4_header.destination_address); - if (checksum_in_packet != checksum_computed) { - goto fail; - } - - BLog(BLOG_INFO, "UDP: from device %d bytes", data_len); - - // construct addresses - BAddr_InitIPv4(&local_addr, ipv4_header.source_address, udp_header.source_port); - // BAddr_InitIPv4(&remote_addr, ipv4_header.destination_address, udp_header.dest_port); - - // if transparent DNS is enabled, any packet arriving at out netif - // address to port 53 is considered a DNS packet - is_dns = (options.udpgw_transparent_dns && - ipv4_header.destination_address == netif_ipaddr.ipv4 && - udp_header.dest_port == hton16(53)); - - if (is_dns) - {//change DNS port to 5400 for Orbot Tor access - - BAddr_InitIPv4(&remote_addr, ipv4_header.destination_address,udp_header.dest_port); - //BAddr_InitIPv4(&remote_addr, ipv4_header.source_address,hton16(5400)); - - } - else - { - BAddr_InitIPv4(&remote_addr, ipv4_header.destination_address, udp_header.dest_port); - - } - - } break; - - case 6: { - // ignore if IPv6 support is disabled - if (!options.netif_ip6addr) { - goto fail; - } - - // ignore non-UDP packets - if (data_len < sizeof(struct ipv6_header) || data[offsetof(struct ipv6_header, next_header)] != IPV6_NEXT_UDP) { - goto fail; - } - - // parse IPv6 header - struct ipv6_header ipv6_header; - if (!ipv6_check(data, data_len, &ipv6_header, &data, &data_len)) { - goto fail; - } - - // parse UDP - struct udp_header udp_header; - if (!udp_check(data, data_len, &udp_header, &data, &data_len)) { - goto fail; - } - - // verify UDP checksum - uint16_t checksum_in_packet = udp_header.checksum; - udp_header.checksum = 0; - uint16_t checksum_computed = udp_ip6_checksum(&udp_header, data, data_len, ipv6_header.source_address, ipv6_header.destination_address); - if (checksum_in_packet != checksum_computed) { - goto fail; - } - - BLog(BLOG_INFO, "UDP/IPv6: from device %d bytes", data_len); - - // construct addresses - BAddr_InitIPv6(&local_addr, ipv6_header.source_address, udp_header.source_port); - BAddr_InitIPv6(&remote_addr, ipv6_header.destination_address, udp_header.dest_port); - - // TODO dns - is_dns = 0; - } break; - - default: { - goto fail; - } break; - } - - // check payload length - if (data_len > udp_mtu) { - BLog(BLOG_ERROR, "packet is too large, cannot send to udpgw"); - goto fail; - } - - // submit packet to udpgw - SocksUdpGwClient_SubmitPacket(&udpgw_client, local_addr, remote_addr, is_dns, data, data_len); - - return 1; - -fail: - return 0; -} - -err_t netif_init_func (struct netif *netif) -{ - BLog(BLOG_DEBUG, "netif func init"); - - netif->name[0] = 'h'; - netif->name[1] = 'o'; - netif->output = netif_output_func; - netif->output_ip6 = netif_output_ip6_func; - - return ERR_OK; -} - -err_t netif_output_func (struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) -{ - return common_netif_output(netif, p); -} - -err_t netif_output_ip6_func (struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr) -{ - return common_netif_output(netif, p); -} - -err_t common_netif_output (struct netif *netif, struct pbuf *p) -{ - SYNC_DECL - - BLog(BLOG_DEBUG, "device write: send packet"); - - if (quitting) { - return ERR_OK; - } - - // if there is just one chunk, send it directly, else via buffer - if (!p->next) { - if (p->len > BTap_GetMTU(&device)) { - BLog(BLOG_WARNING, "netif func output: no space left"); - goto out; - } - - SYNC_FROMHERE - BTap_Send(&device, (uint8_t *)p->payload, p->len); - SYNC_COMMIT - } else { - int len = 0; - do { - if (p->len > BTap_GetMTU(&device) - len) { - BLog(BLOG_WARNING, "netif func output: no space left"); - goto out; - } - memcpy(device_write_buf + len, p->payload, p->len); - len += p->len; - } while (p = p->next); - - SYNC_FROMHERE - BTap_Send(&device, device_write_buf, len); - SYNC_COMMIT - } - -out: - return ERR_OK; -} - -err_t netif_input_func (struct pbuf *p, struct netif *inp) -{ - uint8_t ip_version = 0; - if (p->len > 0) { - ip_version = (((uint8_t *)p->payload)[0] >> 4); - } - - switch (ip_version) { - case 4: { - return ip_input(p, inp); - } break; - case 6: { - if (options.netif_ip6addr) { - return ip6_input(p, inp); - } - } break; - } - - pbuf_free(p); - return ERR_OK; -} - -void client_logfunc (struct tcp_client *client) -{ - char local_addr_s[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->local_addr, local_addr_s); - char remote_addr_s[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->remote_addr, remote_addr_s); - - BLog_Append("%05d (%s %s): ", num_clients, local_addr_s, remote_addr_s); -} - -void client_log (struct tcp_client *client, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err) -{ - ASSERT(err == ERR_OK) - - // signal accepted - struct tcp_pcb *this_listener = (PCB_ISIPV6(newpcb) ? listener_ip6 : listener); - tcp_accepted(this_listener); - - // allocate client structure - struct tcp_client *client = (struct tcp_client *)malloc(sizeof(*client)); - if (!client) { - BLog(BLOG_ERROR, "listener accept: malloc failed"); - goto fail0; - } - client->socks_username = NULL; - - SYNC_DECL - SYNC_FROMHERE - - // read addresses - client->local_addr = baddr_from_lwip(PCB_ISIPV6(newpcb), &newpcb->local_ip, newpcb->local_port); - client->remote_addr = baddr_from_lwip(PCB_ISIPV6(newpcb), &newpcb->remote_ip, newpcb->remote_port); - - // get destination address - BAddr addr = client->local_addr; -#ifdef OVERRIDE_DEST_ADDR - ASSERT_FORCE(BAddr_Parse2(&addr, OVERRIDE_DEST_ADDR, NULL, 0, 1)) -#endif - - // add source address to username if requested - if (options.username && options.append_source_to_username) { - char addr_str[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->remote_addr, addr_str); - client->socks_username = concat_strings(3, options.username, "@", addr_str); - if (!client->socks_username) { - goto fail1; - } - socks_auth_info[1].password.username = client->socks_username; - socks_auth_info[1].password.username_len = strlen(client->socks_username); - } - - // init SOCKS - if (!BSocksClient_Init(&client->socks_client, socks_server_addr, socks_auth_info, socks_num_auth_info, - addr, (BSocksClient_handler)client_socks_handler, client, &ss)) { - BLog(BLOG_ERROR, "listener accept: BSocksClient_Init failed"); - goto fail1; - } - - // init dead vars - DEAD_INIT(client->dead); - DEAD_INIT(client->dead_client); - - // add to linked list - LinkedList1_Append(&tcp_clients, &client->list_node); - - // increment counter - ASSERT(num_clients >= 0) - num_clients++; - - // set pcb - client->pcb = newpcb; - - // set client not closed - client->client_closed = 0; - - // setup handler argument - tcp_arg(client->pcb, client); - - // setup handlers - tcp_err(client->pcb, client_err_func); - tcp_recv(client->pcb, client_recv_func); - - // setup buffer - client->buf_used = 0; - - // set SOCKS not up, not closed - client->socks_up = 0; - client->socks_closed = 0; - - client_log(client, BLOG_INFO, "accepted"); - - DEAD_ENTER(client->dead_client) - SYNC_COMMIT - DEAD_LEAVE2(client->dead_client) - if (DEAD_KILLED) { - return ERR_ABRT; - } - - return ERR_OK; - -fail1: - SYNC_BREAK - free(client->socks_username); - free(client); -fail0: - return ERR_MEM; -} - -void client_handle_freed_client (struct tcp_client *client) -{ - ASSERT(!client->client_closed) - - // pcb was taken care of by the caller - - // kill client dead var - DEAD_KILL(client->dead_client); - - // set client closed - client->client_closed = 1; - - // if we have data to be sent to SOCKS and can send it, keep sending - if (client->buf_used > 0 && !client->socks_closed) { - client_log(client, BLOG_INFO, "waiting untill buffered data is sent to SOCKS"); - } else { - if (!client->socks_closed) { - client_free_socks(client); - } else { - client_dealloc(client); - } - } -} - -void client_free_client (struct tcp_client *client) -{ - ASSERT(!client->client_closed) - - // remove callbacks - tcp_err(client->pcb, NULL); - tcp_recv(client->pcb, NULL); - tcp_sent(client->pcb, NULL); - - // free pcb - err_t err = tcp_close(client->pcb); - if (err != ERR_OK) { - client_log(client, BLOG_ERROR, "tcp_close failed (%d)", err); - tcp_abort(client->pcb); - } - - client_handle_freed_client(client); -} - -void client_abort_client (struct tcp_client *client) -{ - ASSERT(!client->client_closed) - - // remove callbacks - tcp_err(client->pcb, NULL); - tcp_recv(client->pcb, NULL); - tcp_sent(client->pcb, NULL); - - // free pcb - tcp_abort(client->pcb); - - client_handle_freed_client(client); -} - -void client_free_socks (struct tcp_client *client) -{ - ASSERT(!client->socks_closed) - - // stop sending to SOCKS - if (client->socks_up) { - // stop receiving from client - if (!client->client_closed) { - tcp_recv(client->pcb, NULL); - } - } - - // free SOCKS - BSocksClient_Free(&client->socks_client); - - // set SOCKS closed - client->socks_closed = 1; - - // if we have data to be sent to the client and we can send it, keep sending - if (client->socks_up && (client->socks_recv_buf_used >= 0 || client->socks_recv_tcp_pending > 0) && !client->client_closed) { - client_log(client, BLOG_INFO, "waiting until buffered data is sent to client"); - } else { - if (!client->client_closed) { - client_free_client(client); - } else { - client_dealloc(client); - } - } -} - -void client_murder (struct tcp_client *client) -{ - // free client - if (!client->client_closed) { - // remove callbacks - tcp_err(client->pcb, NULL); - tcp_recv(client->pcb, NULL); - tcp_sent(client->pcb, NULL); - - // abort - tcp_abort(client->pcb); - - // kill client dead var - DEAD_KILL(client->dead_client); - - // set client closed - client->client_closed = 1; - } - - // free SOCKS - if (!client->socks_closed) { - // free SOCKS - BSocksClient_Free(&client->socks_client); - - // set SOCKS closed - client->socks_closed = 1; - } - - // dealloc entry - client_dealloc(client); -} - -void client_dealloc (struct tcp_client *client) -{ - ASSERT(client->client_closed) - ASSERT(client->socks_closed) - - // decrement counter - ASSERT(num_clients > 0) - num_clients--; - - // remove client entry - LinkedList1_Remove(&tcp_clients, &client->list_node); - - // kill dead var - DEAD_KILL(client->dead); - - // free memory - free(client->socks_username); - free(client); -} - -void client_err_func (void *arg, err_t err) -{ - struct tcp_client *client = (struct tcp_client *)arg; - ASSERT(!client->client_closed) - - client_log(client, BLOG_INFO, "client error (%d)", (int)err); - - // the pcb was taken care of by the caller - client_handle_freed_client(client); -} - -err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - struct tcp_client *client = (struct tcp_client *)arg; - ASSERT(!client->client_closed) - ASSERT(err == ERR_OK) // checked in lwIP source. Otherwise, I've no idea what should - // be done with the pbuf in case of an error. - - if (!p) { - client_log(client, BLOG_INFO, "client closed"); - client_free_client(client); - return ERR_ABRT; - } - - ASSERT(p->tot_len > 0) - - // check if we have enough buffer - if (p->tot_len > sizeof(client->buf) - client->buf_used) { - client_log(client, BLOG_ERROR, "no buffer for data !?!"); - return ERR_MEM; - } - - // copy data to buffer - ASSERT_EXECUTE(pbuf_copy_partial(p, client->buf + client->buf_used, p->tot_len, 0) == p->tot_len) - client->buf_used += p->tot_len; - - // if there was nothing in the buffer before, and SOCKS is up, start send data - if (client->buf_used == p->tot_len && client->socks_up) { - ASSERT(!client->socks_closed) // this callback is removed when SOCKS is closed - - SYNC_DECL - SYNC_FROMHERE - client_send_to_socks(client); - DEAD_ENTER(client->dead_client) - SYNC_COMMIT - DEAD_LEAVE2(client->dead_client) - if (DEAD_KILLED) { - return ERR_ABRT; - } - } - - // free pbuff - pbuf_free(p); - - return ERR_OK; -} - -void client_socks_handler (struct tcp_client *client, int event) -{ - ASSERT(!client->socks_closed) - - switch (event) { - case BSOCKSCLIENT_EVENT_ERROR: { - client_log(client, BLOG_INFO, "SOCKS error"); - - client_free_socks(client); - } break; - - case BSOCKSCLIENT_EVENT_UP: { - ASSERT(!client->socks_up) - - client_log(client, BLOG_INFO, "SOCKS up"); - - // init sending - client->socks_send_if = BSocksClient_GetSendInterface(&client->socks_client); - StreamPassInterface_Sender_Init(client->socks_send_if, (StreamPassInterface_handler_done)client_socks_send_handler_done, client); - - // init receiving - client->socks_recv_if = BSocksClient_GetRecvInterface(&client->socks_client); - StreamRecvInterface_Receiver_Init(client->socks_recv_if, (StreamRecvInterface_handler_done)client_socks_recv_handler_done, client); - client->socks_recv_buf_used = -1; - client->socks_recv_tcp_pending = 0; - if (!client->client_closed) { - tcp_sent(client->pcb, client_sent_func); - } - - // set up - client->socks_up = 1; - - // start sending data if there is any - if (client->buf_used > 0) { - client_send_to_socks(client); - } - - // start receiving data if client is still up - if (!client->client_closed) { - client_socks_recv_initiate(client); - } - } break; - - case BSOCKSCLIENT_EVENT_ERROR_CLOSED: { - ASSERT(client->socks_up) - - client_log(client, BLOG_INFO, "SOCKS closed"); - - client_free_socks(client); - } break; - - default: - ASSERT(0); - } -} - -void client_send_to_socks (struct tcp_client *client) -{ - ASSERT(!client->socks_closed) - ASSERT(client->socks_up) - ASSERT(client->buf_used > 0) - - // schedule sending - StreamPassInterface_Sender_Send(client->socks_send_if, client->buf, client->buf_used); -} - -void client_socks_send_handler_done (struct tcp_client *client, int data_len) -{ - ASSERT(!client->socks_closed) - ASSERT(client->socks_up) - ASSERT(client->buf_used > 0) - ASSERT(data_len > 0) - ASSERT(data_len <= client->buf_used) - - // remove sent data from buffer - memmove(client->buf, client->buf + data_len, client->buf_used - data_len); - client->buf_used -= data_len; - - if (!client->client_closed) { - // confirm sent data - tcp_recved(client->pcb, data_len); - } - - if (client->buf_used > 0) { - // send any further data - StreamPassInterface_Sender_Send(client->socks_send_if, client->buf, client->buf_used); - } - else if (client->client_closed) { - // client was closed we've sent everything we had buffered; we're done with it - client_log(client, BLOG_INFO, "removing after client went down"); - - client_free_socks(client); - } -} - -void client_socks_recv_initiate (struct tcp_client *client) -{ - ASSERT(!client->client_closed) - ASSERT(!client->socks_closed) - ASSERT(client->socks_up) - ASSERT(client->socks_recv_buf_used == -1) - - StreamRecvInterface_Receiver_Recv(client->socks_recv_if, client->socks_recv_buf, sizeof(client->socks_recv_buf)); -} - -void client_socks_recv_handler_done (struct tcp_client *client, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= sizeof(client->socks_recv_buf)) - ASSERT(!client->socks_closed) - ASSERT(client->socks_up) - ASSERT(client->socks_recv_buf_used == -1) - - // if client was closed, stop receiving - if (client->client_closed) { - return; - } - - // set amount of data in buffer - client->socks_recv_buf_used = data_len; - client->socks_recv_buf_sent = 0; - client->socks_recv_waiting = 0; - - // send to client - if (client_socks_recv_send_out(client) < 0) { - return; - } - - // continue receiving if needed - if (client->socks_recv_buf_used == -1) { - client_socks_recv_initiate(client); - } -} - -int client_socks_recv_send_out (struct tcp_client *client) -{ - ASSERT(!client->client_closed) - ASSERT(client->socks_up) - ASSERT(client->socks_recv_buf_used > 0) - ASSERT(client->socks_recv_buf_sent < client->socks_recv_buf_used) - ASSERT(!client->socks_recv_waiting) - - // return value -1 means tcp_abort() was done, - // 0 means it wasn't and the client (pcb) is still up - - do { - int to_write = bmin_int(client->socks_recv_buf_used - client->socks_recv_buf_sent, tcp_sndbuf(client->pcb)); - if (to_write == 0) { - break; - } - - err_t err = tcp_write(client->pcb, client->socks_recv_buf + client->socks_recv_buf_sent, to_write, TCP_WRITE_FLAG_COPY); - if (err != ERR_OK) { - if (err == ERR_MEM) { - break; - } - - client_log(client, BLOG_INFO, "tcp_write failed (%d)", (int)err); - - client_abort_client(client); - return -1; - } - - client->socks_recv_buf_sent += to_write; - client->socks_recv_tcp_pending += to_write; - } while (client->socks_recv_buf_sent < client->socks_recv_buf_used); - - // start sending now - err_t err = tcp_output(client->pcb); - if (err != ERR_OK) { - client_log(client, BLOG_INFO, "tcp_output failed (%d)", (int)err); - - client_abort_client(client); - return -1; - } - - // more data to queue? - if (client->socks_recv_buf_sent < client->socks_recv_buf_used) { - if (client->socks_recv_tcp_pending == 0) { - client_log(client, BLOG_ERROR, "can't queue data, but all data was confirmed !?!"); - - client_abort_client(client); - return -1; - } - - // set waiting, continue in client_sent_func - client->socks_recv_waiting = 1; - return 0; - } - - // everything was queued - client->socks_recv_buf_used = -1; - - return 0; -} - -err_t client_sent_func (void *arg, struct tcp_pcb *tpcb, u16_t len) -{ - struct tcp_client *client = (struct tcp_client *)arg; - - ASSERT(!client->client_closed) - ASSERT(client->socks_up) - ASSERT(len > 0) - ASSERT(len <= client->socks_recv_tcp_pending) - - // decrement pending - client->socks_recv_tcp_pending -= len; - - // continue queuing - if (client->socks_recv_buf_used > 0) { - ASSERT(client->socks_recv_waiting) - ASSERT(client->socks_recv_buf_sent < client->socks_recv_buf_used) - - // set not waiting - client->socks_recv_waiting = 0; - - // possibly send more data - if (client_socks_recv_send_out(client) < 0) { - return ERR_ABRT; - } - - // we just queued some data, so it can't have been confirmed yet - ASSERT(client->socks_recv_tcp_pending > 0) - - // continue receiving if needed - if (client->socks_recv_buf_used == -1 && !client->socks_closed) { - SYNC_DECL - SYNC_FROMHERE - client_socks_recv_initiate(client); - DEAD_ENTER(client->dead_client) - SYNC_COMMIT - DEAD_LEAVE2(client->dead_client) - if (DEAD_KILLED) { - return ERR_ABRT; - } - } - - return ERR_OK; - } - - // have we sent everything after SOCKS was closed? - if (client->socks_closed && client->socks_recv_tcp_pending == 0) { - client_log(client, BLOG_INFO, "removing after SOCKS went down"); - client_free_client(client); - return ERR_ABRT; - } - - return ERR_OK; -} - -void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len) -{ - ASSERT(options.udpgw_remote_server_addr) - ASSERT(local_addr.type == BADDR_TYPE_IPV4 || local_addr.type == BADDR_TYPE_IPV6) - ASSERT(local_addr.type == remote_addr.type) - ASSERT(data_len >= 0) - - int packet_length = 0; - - switch (local_addr.type) { - case BADDR_TYPE_IPV4: { - BLog(BLOG_INFO, "UDP: from udpgw %d bytes", data_len); - - if (data_len > UINT16_MAX - (sizeof(struct ipv4_header) + sizeof(struct udp_header)) || - data_len > BTap_GetMTU(&device) - (int)(sizeof(struct ipv4_header) + sizeof(struct udp_header)) - ) { - BLog(BLOG_ERROR, "UDP: packet is too large"); - return; - } - - // build IP header - struct ipv4_header iph; - iph.version4_ihl4 = IPV4_MAKE_VERSION_IHL(sizeof(iph)); - iph.ds = hton8(0); - iph.total_length = hton16(sizeof(iph) + sizeof(struct udp_header) + data_len); - iph.identification = hton16(0); - iph.flags3_fragmentoffset13 = hton16(0); - iph.ttl = hton8(64); - iph.protocol = hton8(IPV4_PROTOCOL_UDP); - iph.checksum = hton16(0); - iph.source_address = remote_addr.ipv4.ip; - iph.destination_address = local_addr.ipv4.ip; - iph.checksum = ipv4_checksum(&iph, NULL, 0); - - // build UDP header - struct udp_header udph; - udph.source_port = remote_addr.ipv4.port; - udph.dest_port = local_addr.ipv4.port; - udph.length = hton16(sizeof(udph) + data_len); - udph.checksum = hton16(0); - udph.checksum = udp_checksum(&udph, data, data_len, iph.source_address, iph.destination_address); - - // write packet - memcpy(device_write_buf, &iph, sizeof(iph)); - memcpy(device_write_buf + sizeof(iph), &udph, sizeof(udph)); - memcpy(device_write_buf + sizeof(iph) + sizeof(udph), data, data_len); - packet_length = sizeof(iph) + sizeof(udph) + data_len; - } break; - - case BADDR_TYPE_IPV6: { - BLog(BLOG_INFO, "UDP/IPv6: from udpgw %d bytes", data_len); - - if (!options.netif_ip6addr) { - BLog(BLOG_ERROR, "got IPv6 packet from udpgw but IPv6 is disabled"); - return; - } - - if (data_len > UINT16_MAX - sizeof(struct udp_header) || - data_len > BTap_GetMTU(&device) - (int)(sizeof(struct ipv6_header) + sizeof(struct udp_header)) - ) { - BLog(BLOG_ERROR, "UDP/IPv6: packet is too large"); - return; - } - - // build IPv6 header - struct ipv6_header iph; - iph.version4_tc4 = hton8((6 << 4)); - iph.tc4_fl4 = hton8(0); - iph.fl = hton16(0); - iph.payload_length = hton16(sizeof(struct udp_header) + data_len); - iph.next_header = hton8(IPV6_NEXT_UDP); - iph.hop_limit = hton8(64); - memcpy(iph.source_address, remote_addr.ipv6.ip, 16); - memcpy(iph.destination_address, local_addr.ipv6.ip, 16); - - // build UDP header - struct udp_header udph; - udph.source_port = remote_addr.ipv6.port; - udph.dest_port = local_addr.ipv6.port; - udph.length = hton16(sizeof(udph) + data_len); - udph.checksum = hton16(0); - udph.checksum = udp_ip6_checksum(&udph, data, data_len, iph.source_address, iph.destination_address); - - // write packet - memcpy(device_write_buf, &iph, sizeof(iph)); - memcpy(device_write_buf + sizeof(iph), &udph, sizeof(udph)); - memcpy(device_write_buf + sizeof(iph) + sizeof(udph), data, data_len); - packet_length = sizeof(iph) + sizeof(udph) + data_len; - } break; - } - - // submit packet - BTap_Send(&device, device_write_buf, packet_length); -} diff --git a/external/badvpn_dns/tun2socks/tun2socks.h b/external/badvpn_dns/tun2socks/tun2socks.h deleted file mode 100644 index caf5778..0000000 --- a/external/badvpn_dns/tun2socks/tun2socks.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// name of the program -#define PROGRAM_NAME "tun2socks" - -// size of temporary buffer for passing data from the SOCKS server to TCP for sending -#define CLIENT_SOCKS_RECV_BUF_SIZE 8192 - -// maximum number of udpgw connections -#define DEFAULT_UDPGW_MAX_CONNECTIONS 256 - -// udpgw per-connection send buffer size, in number of packets -#define DEFAULT_UDPGW_CONNECTION_BUFFER_SIZE 8 - -// udpgw reconnect time after connection fails -#define UDPGW_RECONNECT_TIME 5000 - -// udpgw keepalive sending interval -#define UDPGW_KEEPALIVE_TIME 10000 - -// option to override the destination addresses to give the SOCKS server -//#define OVERRIDE_DEST_ADDR "10.111.0.2:2000" diff --git a/external/badvpn_dns/tunctl/CMakeLists.txt b/external/badvpn_dns/tunctl/CMakeLists.txt deleted file mode 100644 index 4cbebc8..0000000 --- a/external/badvpn_dns/tunctl/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_executable(badvpn-tunctl tunctl.c) - -install( - TARGETS badvpn-tunctl - RUNTIME DESTINATION bin -) diff --git a/external/badvpn_dns/tunctl/tunctl.c b/external/badvpn_dns/tunctl/tunctl.c deleted file mode 100644 index 4490adc..0000000 --- a/external/badvpn_dns/tunctl/tunctl.c +++ /dev/null @@ -1,352 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <linux/if_tun.h> -#include <pwd.h> -#include <grp.h> - -#include <misc/version.h> -#include <misc/open_standard_streams.h> - -#define PROGRAM_NAME "tunctl" - -#define TUN_DEVNODE "/dev/net/tun" - -struct { - int help; - int version; - int op; - char *device_name; - char *user; - char *group; -} options; - -#define OP_MKTUN 1 -#define OP_MKTAP 2 -#define OP_RMTUN 3 -#define OP_RMTAP 4 - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int make_tuntap (const char *ifname, int is_tun, const char *user, const char *group); -static int remove_tuntap (const char *ifname, int is_tun); - -int main (int argc, char *argv[]) -{ - int res = 1; - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Error: Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - if (options.op == OP_MKTUN || options.op == OP_MKTAP) { - if (!options.user && !options.group) { - fprintf(stderr, "WARNING: with neither --user nor --group, anyone will be able to use the device!\n"); - } - res = !make_tuntap(options.device_name, options.op == OP_MKTUN, options.user, options.group); - } else { - res = !remove_tuntap(options.device_name, options.op == OP_RMTUN); - } - -fail0: - return res; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s [--help] [--version]\n" - " %s --mktun <device_name> [--user <username>] [--group <groupname>]\n" - " %s --mktap <device_name> [--user <username>] [--group <groupname>]\n" - " %s --rmtun <device_name>\n" - " %s --rmtap <device_name>\n", - name, name, name, name, name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.op = -1; - options.device_name = NULL; - options.user = NULL; - options.group = NULL; - - for (int i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--mktun")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.op >= 0) { - fprintf(stderr, "%s: can only do one operation\n", arg); - return 0; - } - options.op = OP_MKTUN; - options.device_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--mktap")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.op >= 0) { - fprintf(stderr, "%s: can only do one operation\n", arg); - return 0; - } - options.op = OP_MKTAP; - options.device_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--rmtun")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.op >= 0) { - fprintf(stderr, "%s: can only do one operation\n", arg); - return 0; - } - options.op = OP_RMTUN; - options.device_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--rmtap")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.op >= 0) { - fprintf(stderr, "%s: can only do one operation\n", arg); - return 0; - } - options.op = OP_RMTAP; - options.device_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--user")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.user = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--group")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.group = argv[i + 1]; - i++; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (options.op < 0) { - fprintf(stderr, "--mktun, --mktap --rmtun or --rmtap is required\n"); - return 0; - } - - if ((options.user || options.group) && options.op != OP_MKTUN && options.op != OP_MKTAP) { - fprintf(stderr, "--user and --group only make sense for --mktun and --mktap\n"); - return 0; - } - - return 1; -} - -static int make_tuntap (const char *ifname, int is_tun, const char *user, const char *group) -{ - int res = 0; - - if (strlen(ifname) >= IFNAMSIZ) { - fprintf(stderr, "Error: ifname too long\n"); - goto fail0; - } - - int fd = open(TUN_DEVNODE, O_RDWR); - if (fd < 0) { - perror("open"); - fprintf(stderr, "Error: open tun failed\n"); - goto fail0; - } - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = (is_tun ? IFF_TUN : IFF_TAP); - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); - - if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { - perror("ioctl(TUNSETIFF)"); - fprintf(stderr, "Error: TUNSETIFF failed\n"); - goto fail1; - } - - uid_t uid = -1; - gid_t gid = -1; - - if (user) { - long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize < 0) { - bufsize = 16384; - } - - char *buf = malloc(bufsize); - if (!buf) { - fprintf(stderr, "Error: malloc failed\n"); - goto fail1; - } - - struct passwd pwd; - struct passwd *res; - getpwnam_r(user, &pwd, buf, bufsize, &res); - if (!res) { - fprintf(stderr, "Error: getpwnam_r failed\n"); - free(buf); - goto fail1; - } - - uid = pwd.pw_uid; - free(buf); - } - - if (group) { - long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); - if (bufsize < 0) { - bufsize = 16384; - } - - char *buf = malloc(bufsize); - if (!buf) { - fprintf(stderr, "Error: malloc failed\n"); - goto fail1; - } - - struct group grp; - struct group *res; - getgrnam_r(group, &grp, buf, bufsize, &res); - if (!res) { - fprintf(stderr, "Error: getgrnam_r failed\n"); - free(buf); - goto fail1; - } - - gid = grp.gr_gid; - free(buf); - } - - if (ioctl(fd, TUNSETOWNER, uid) < 0) { - perror("ioctl(TUNSETOWNER)"); - fprintf(stderr, "Error: TUNSETOWNER failed\n"); - goto fail1; - } - - if (ioctl(fd, TUNSETGROUP, gid) < 0) { - perror("ioctl(TUNSETGROUP)"); - fprintf(stderr, "Error: TUNSETGROUP failed\n"); - goto fail1; - } - - if (ioctl(fd, TUNSETPERSIST, (void *)1) < 0) { - perror("ioctl(TUNSETPERSIST)"); - fprintf(stderr, "Error: TUNSETPERSIST failed\n"); - goto fail1; - } - - res = 1; - -fail1: - close(fd); -fail0: - return res; -} - -static int remove_tuntap (const char *ifname, int is_tun) -{ - int res = 0; - - if (strlen(ifname) >= IFNAMSIZ) { - fprintf(stderr, "Error: ifname too long\n"); - goto fail0; - } - - int fd = open(TUN_DEVNODE, O_RDWR); - if (fd < 0) { - perror("open"); - fprintf(stderr, "Error: open tun failed\n"); - goto fail0; - } - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = (is_tun ? IFF_TUN : IFF_TAP); - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ifname); - - if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { - perror("ioctl(TUNSETIFF)"); - fprintf(stderr, "Error: TUNSETIFF failed\n"); - goto fail1; - } - - if (ioctl(fd, TUNSETPERSIST, (void *)0) < 0) { - perror("ioctl(TUNSETPERSIST)"); - fprintf(stderr, "Error: TUNSETPERSIST failed\n"); - goto fail1; - } - - res = 1; - -fail1: - close(fd); -fail0: - return res; -} diff --git a/external/badvpn_dns/tuntap/BTap.c b/external/badvpn_dns/tuntap/BTap.c deleted file mode 100644 index af12558..0000000 --- a/external/badvpn_dns/tuntap/BTap.c +++ /dev/null @@ -1,631 +0,0 @@ -/** - * @file BTap.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <stdio.h> - -#ifdef BADVPN_USE_WINAPI - #include <windows.h> - #include <winioctl.h> - #include <objbase.h> - #include <wtypes.h> - #include "wintap-common.h" - #include <tuntap/tapwin32-funcs.h> -#else - #include <fcntl.h> - #include <unistd.h> - #include <errno.h> - #include <sys/ioctl.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <sys/socket.h> - #include <net/if.h> - #include <net/if_arp.h> - #ifdef BADVPN_LINUX - #include <linux/if_tun.h> - #endif - #ifdef BADVPN_FREEBSD - #include <net/if_tun.h> - #include <net/if_tap.h> - #endif -#endif - -#include <base/BLog.h> - -#include <tuntap/BTap.h> - -#include <generated/blog_channel_BTap.h> - -static void report_error (BTap *o); -static void output_handler_recv (BTap *o, uint8_t *data); - -#ifdef BADVPN_USE_WINAPI - -static void recv_olap_handler (BTap *o, int event, DWORD bytes) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->output_packet) - ASSERT(event == BREACTOR_IOCP_EVENT_SUCCEEDED || event == BREACTOR_IOCP_EVENT_FAILED) - - // set no output packet - o->output_packet = NULL; - - if (event == BREACTOR_IOCP_EVENT_FAILED) { - BLog(BLOG_ERROR, "read operation failed"); - report_error(o); - return; - } - - ASSERT(bytes >= 0) - ASSERT(bytes <= o->frame_mtu) - - // done - PacketRecvInterface_Done(&o->output, bytes); -} - -#else - -static void fd_handler (BTap *o, int events) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - if (events&(BREACTOR_ERROR|BREACTOR_HUP)) { - BLog(BLOG_WARNING, "device fd reports error?"); - } - - if (events&BREACTOR_READ) do { - ASSERT(o->output_packet) - - // try reading into the buffer - int bytes = read(o->fd, o->output_packet, o->frame_mtu); - if (bytes < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // retry later - break; - } - // report fatal error - report_error(o); - return; - } - - ASSERT_FORCE(bytes <= o->frame_mtu) - - // set no output packet - o->output_packet = NULL; - - // update events - o->poll_events &= ~BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->poll_events); - - // inform receiver we finished the packet - PacketRecvInterface_Done(&o->output, bytes); - } while (0); -} - -#endif - -void report_error (BTap *o) -{ - DEBUGERROR(&o->d_err, o->handler_error(o->handler_error_user)); -} - -void output_handler_recv (BTap *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(data) - ASSERT(!o->output_packet) - -#ifdef BADVPN_USE_WINAPI - - memset(&o->recv_olap.olap, 0, sizeof(o->recv_olap.olap)); - - // read - BOOL res = ReadFile(o->device, data, o->frame_mtu, NULL, &o->recv_olap.olap); - if (res == FALSE && GetLastError() != ERROR_IO_PENDING) { - BLog(BLOG_ERROR, "ReadFile failed (%u)", GetLastError()); - report_error(o); - return; - } - - o->output_packet = data; - -#else - - // attempt read - int bytes = read(o->fd, data, o->frame_mtu); - if (bytes < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // retry later in fd_handler - // remember packet - o->output_packet = data; - // update events - o->poll_events |= BREACTOR_READ; - BReactor_SetFileDescriptorEvents(o->reactor, &o->bfd, o->poll_events); - return; - } - // report fatal error - report_error(o); - return; - } - - ASSERT_FORCE(bytes <= o->frame_mtu) - - PacketRecvInterface_Done(&o->output, bytes); - -#endif -} - -int BTap_Init (BTap *o, BReactor *reactor, char *devname, BTap_handler_error handler_error, void *handler_error_user, int tun) -{ - ASSERT(tun == 0 || tun == 1) - - struct BTap_init_data init_data; - init_data.dev_type = tun ? BTAP_DEV_TUN : BTAP_DEV_TAP; - init_data.init_type = BTAP_INIT_STRING; - init_data.init.string = devname; - - return BTap_Init2(o, reactor, init_data, handler_error, handler_error_user); -} - -int BTap_Init2 (BTap *o, BReactor *reactor, struct BTap_init_data init_data, BTap_handler_error handler_error, void *handler_error_user) -{ - ASSERT(init_data.dev_type == BTAP_DEV_TUN || init_data.dev_type == BTAP_DEV_TAP) - - // init arguments - o->reactor = reactor; - o->handler_error = handler_error; - o->handler_error_user = handler_error_user; - - #ifdef BADVPN_USE_WINAPI - - ASSERT(init_data.init_type == BTAP_INIT_STRING) - - // parse device specification - - if (!init_data.init.string) { - BLog(BLOG_ERROR, "no device specification provided"); - goto fail0; - } - - char *device_component_id; - char *device_name; - uint32_t tun_addrs[3]; - - if (init_data.dev_type == BTAP_DEV_TUN) { - if (!tapwin32_parse_tun_spec(init_data.init.string, &device_component_id, &device_name, tun_addrs)) { - BLog(BLOG_ERROR, "failed to parse TUN device specification"); - goto fail0; - } - } else { - if (!tapwin32_parse_tap_spec(init_data.init.string, &device_component_id, &device_name)) { - BLog(BLOG_ERROR, "failed to parse TAP device specification"); - goto fail0; - } - } - - // locate device path - - char device_path[TAPWIN32_MAX_REG_SIZE]; - - BLog(BLOG_INFO, "Looking for TAP-Win32 with component ID %s, name %s", device_component_id, device_name); - - if (!tapwin32_find_device(device_component_id, device_name, &device_path)) { - BLog(BLOG_ERROR, "Could not find device"); - goto fail1; - } - - // open device - - BLog(BLOG_INFO, "Opening device %s", device_path); - - o->device = CreateFile(device_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED, 0); - if (o->device == INVALID_HANDLE_VALUE) { - BLog(BLOG_ERROR, "CreateFile failed"); - goto fail1; - } - - // set TUN if needed - - DWORD len; - - if (init_data.dev_type == BTAP_DEV_TUN) { - if (!DeviceIoControl(o->device, TAP_IOCTL_CONFIG_TUN, tun_addrs, sizeof(tun_addrs), tun_addrs, sizeof(tun_addrs), &len, NULL)) { - BLog(BLOG_ERROR, "DeviceIoControl(TAP_IOCTL_CONFIG_TUN) failed"); - goto fail2; - } - } - - // get MTU - - ULONG umtu; - - if (!DeviceIoControl(o->device, TAP_IOCTL_GET_MTU, NULL, 0, &umtu, sizeof(umtu), &len, NULL)) { - BLog(BLOG_ERROR, "DeviceIoControl(TAP_IOCTL_GET_MTU) failed"); - goto fail2; - } - - if (init_data.dev_type == BTAP_DEV_TUN) { - o->frame_mtu = umtu; - } else { - o->frame_mtu = umtu + BTAP_ETHERNET_HEADER_LENGTH; - } - - // set connected - - ULONG upstatus = TRUE; - if (!DeviceIoControl(o->device, TAP_IOCTL_SET_MEDIA_STATUS, &upstatus, sizeof(upstatus), &upstatus, sizeof(upstatus), &len, NULL)) { - BLog(BLOG_ERROR, "DeviceIoControl(TAP_IOCTL_SET_MEDIA_STATUS) failed"); - goto fail2; - } - - BLog(BLOG_INFO, "Device opened"); - - // associate device with IOCP - - if (!CreateIoCompletionPort(o->device, BReactor_GetIOCPHandle(o->reactor), 0, 0)) { - BLog(BLOG_ERROR, "CreateIoCompletionPort failed"); - goto fail2; - } - - // init send olap - BReactorIOCPOverlapped_Init(&o->send_olap, o->reactor, o, NULL); - - // init recv olap - BReactorIOCPOverlapped_Init(&o->recv_olap, o->reactor, o, (BReactorIOCPOverlapped_handler)recv_olap_handler); - - free(device_name); - free(device_component_id); - - goto success; - -fail2: - ASSERT_FORCE(CloseHandle(o->device)) -fail1: - free(device_name); - free(device_component_id); -fail0: - return 0; - - #endif - - #if defined(BADVPN_LINUX) || defined(BADVPN_FREEBSD) - - o->close_fd = (init_data.init_type != BTAP_INIT_FD); - - switch (init_data.init_type) { - case BTAP_INIT_FD: { - ASSERT(init_data.init.fd.fd >= 0) - ASSERT(init_data.init.fd.mtu >= 0) - ASSERT(init_data.dev_type != BTAP_DEV_TAP || init_data.init.fd.mtu >= BTAP_ETHERNET_HEADER_LENGTH) - - o->fd = init_data.init.fd.fd; - o->frame_mtu = init_data.init.fd.mtu; - } break; - - case BTAP_INIT_STRING: { - char devname_real[IFNAMSIZ]; - - #ifdef BADVPN_LINUX - - // open device - - if ((o->fd = open("/dev/net/tun", O_RDWR)) < 0) { - BLog(BLOG_ERROR, "error opening device"); - goto fail0; - } - - // configure device - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags |= IFF_NO_PI; - if (init_data.dev_type == BTAP_DEV_TUN) { - ifr.ifr_flags |= IFF_TUN; - } else { - ifr.ifr_flags |= IFF_TAP; - } - if (init_data.init.string) { - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", init_data.init.string); - } - - if (ioctl(o->fd, TUNSETIFF, (void *)&ifr) < 0) { - BLog(BLOG_ERROR, "error configuring device"); - goto fail1; - } - - strcpy(devname_real, ifr.ifr_name); - - #endif - - #ifdef BADVPN_FREEBSD - - if (init_data.dev_type == BTAP_DEV_TUN) { - BLog(BLOG_ERROR, "TUN not supported on FreeBSD"); - goto fail0; - } - - if (!init_data.init.string) { - BLog(BLOG_ERROR, "no device specified"); - goto fail0; - } - - // open device - - char devnode[10 + IFNAMSIZ]; - snprintf(devnode, sizeof(devnode), "/dev/%s", init_data.init.string); - - if ((o->fd = open(devnode, O_RDWR)) < 0) { - BLog(BLOG_ERROR, "error opening device"); - goto fail0; - } - - // get name - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - if (ioctl(o->fd, TAPGIFNAME, (void *)&ifr) < 0) { - BLog(BLOG_ERROR, "error configuring device"); - goto fail1; - } - - strcpy(devname_real, ifr.ifr_name); - - #endif - - // get MTU - - // open dummy socket for ioctls - int sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - BLog(BLOG_ERROR, "socket failed"); - goto fail1; - } - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname_real); - - if (ioctl(sock, SIOCGIFMTU, (void *)&ifr) < 0) { - BLog(BLOG_ERROR, "error getting MTU"); - close(sock); - goto fail1; - } - - if (init_data.dev_type == BTAP_DEV_TUN) { - o->frame_mtu = ifr.ifr_mtu; - } else { - o->frame_mtu = ifr.ifr_mtu + BTAP_ETHERNET_HEADER_LENGTH; - } - - close(sock); - } break; - - default: ASSERT(0); - } - - // set non-blocking - if (fcntl(o->fd, F_SETFL, O_NONBLOCK) < 0) { - BLog(BLOG_ERROR, "cannot set non-blocking"); - goto fail1; - } - - // init file descriptor object - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - o->poll_events = 0; - - goto success; - -fail1: - if (o->close_fd) { - ASSERT_FORCE(close(o->fd) == 0) - } -fail0: - return 0; - - #endif - -success: - // init output - PacketRecvInterface_Init(&o->output, o->frame_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // set no output packet - o->output_packet = NULL; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; -} - -// ==== PSIPHON ==== - -int BTap_InitWithFD (BTap *o, BReactor *reactor, int fd, int mtu, BTap_handler_error handler_error, void *handler_error_user, int tun) -{ - ASSERT(tun == 0 || tun == 1) - - #ifndef BADVPN_LINUX - - return 0; - - #endif - - o->reactor = reactor; - o->handler_error = handler_error; - o->handler_error_user = handler_error_user; - o->frame_mtu = mtu; - o->fd = fd; - o->close_fd = 1; - - // TODO: use BTap_Init2? Still some different behavior (we don't want the fcntl block; we do want close to be called) - - // The following is identical to BTap_Init... - - // init file descriptor object - BFileDescriptor_Init(&o->bfd, o->fd, (BFileDescriptor_handler)fd_handler, o); - if (!BReactor_AddFileDescriptor(o->reactor, &o->bfd)) { - BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed"); - goto fail1; - } - o->poll_events = 0; - - goto success; - -fail1: - if (o->close_fd) { - ASSERT_FORCE(close(o->fd) == 0) - } -fail0: - return 0; - -success: - // init output - PacketRecvInterface_Init(&o->output, o->frame_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, BReactor_PendingGroup(o->reactor)); - - // set no output packet - o->output_packet = NULL; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; -} - -// ==== PSIPHON ==== - -void BTap_Free (BTap *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free output - PacketRecvInterface_Free(&o->output); - -#ifdef BADVPN_USE_WINAPI - - // cancel I/O - ASSERT_FORCE(CancelIo(o->device)) - - // wait receiving to finish - if (o->output_packet) { - BLog(BLOG_DEBUG, "waiting for receiving to finish"); - BReactorIOCPOverlapped_Wait(&o->recv_olap, NULL, NULL); - } - - // free recv olap - BReactorIOCPOverlapped_Free(&o->recv_olap); - - // free send olap - BReactorIOCPOverlapped_Free(&o->send_olap); - - // close device - ASSERT_FORCE(CloseHandle(o->device)) - -#else - - // free BFileDescriptor - BReactor_RemoveFileDescriptor(o->reactor, &o->bfd); - - if (o->close_fd) { - // close file descriptor - ASSERT_FORCE(close(o->fd) == 0) - } - -#endif -} - -int BTap_GetMTU (BTap *o) -{ - DebugObject_Access(&o->d_obj); - - return o->frame_mtu; -} - -void BTap_Send (BTap *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(data_len >= 0) - ASSERT(data_len <= o->frame_mtu) - -#ifdef BADVPN_USE_WINAPI - - // ignore frames without an Ethernet header, or we get errors in WriteFile - if (data_len < 14) { - return; - } - - memset(&o->send_olap.olap, 0, sizeof(o->send_olap.olap)); - - // write - BOOL res = WriteFile(o->device, data, data_len, NULL, &o->send_olap.olap); - if (res == FALSE && GetLastError() != ERROR_IO_PENDING) { - BLog(BLOG_ERROR, "WriteFile failed (%u)", GetLastError()); - return; - } - - // wait - int succeeded; - DWORD bytes; - BReactorIOCPOverlapped_Wait(&o->send_olap, &succeeded, &bytes); - - if (!succeeded) { - BLog(BLOG_ERROR, "write operation failed"); - } else { - ASSERT(bytes >= 0) - ASSERT(bytes <= data_len) - - if (bytes < data_len) { - BLog(BLOG_ERROR, "write operation didn't write everything"); - } - } - -#else - - int bytes = write(o->fd, data, data_len); - if (bytes < 0) { - // malformed packets will cause errors, ignore them and act like - // the packet was accepeted - } else { - if (bytes != data_len) { - BLog(BLOG_WARNING, "written %d expected %d", bytes, data_len); - } - } - -#endif -} - -PacketRecvInterface * BTap_GetOutput (BTap *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/external/badvpn_dns/tuntap/BTap.h b/external/badvpn_dns/tuntap/BTap.h deleted file mode 100644 index d9fa524..0000000 --- a/external/badvpn_dns/tuntap/BTap.h +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @file BTap.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * TAP device abstraction. - */ - -#ifndef BADVPN_TUNTAP_BTAP_H -#define BADVPN_TUNTAP_BTAP_H - -#if (defined(BADVPN_USE_WINAPI) + defined(BADVPN_LINUX) + defined(BADVPN_FREEBSD)) != 1 -#error Unknown TAP backend or too many TAP backends -#endif - -#include <stdint.h> - -#ifdef BADVPN_USE_WINAPI -#else -#include <net/if.h> -#endif - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <base/DebugObject.h> -#include <system/BReactor.h> -#include <flow/PacketRecvInterface.h> - -#define BTAP_ETHERNET_HEADER_LENGTH 14 - -/** - * Handler called when an error occurs on the device. - * The object must be destroyed from the job context of this - * handler, and no further I/O may occur. - * - * @param user as in {@link BTap_Init} - */ -typedef void (*BTap_handler_error) (void *used); - -typedef struct { - BReactor *reactor; - BTap_handler_error handler_error; - void *handler_error_user; - int frame_mtu; - PacketRecvInterface output; - uint8_t *output_packet; - -#ifdef BADVPN_USE_WINAPI - HANDLE device; - BReactorIOCPOverlapped send_olap; - BReactorIOCPOverlapped recv_olap; -#else - int close_fd; - int fd; - BFileDescriptor bfd; - int poll_events; -#endif - - DebugError d_err; - DebugObject d_obj; -} BTap; - -/** - * Initializes the TAP device. - * - * @param o the object - * @param BReactor {@link BReactor} we live in - * @param devname name of the devece to open. - * On Linux: a network interface name. If it is NULL, no - * specific device will be requested, and the operating system - * may create a new device. - * On Windows: a string "component_id:device_name", where - * component_id is a string identifying the driver, and device_name - * is the name of the network interface. If component_id is empty, - * a hardcoded default will be used instead. If device_name is empty, - * the first device found with a matching component_id will be used. - * Specifying a NULL devname is equivalent to specifying ":". - * @param handler_error error handler function - * @param handler_error_user value passed to error handler - * @param tun whether to create a TUN (IP) device or a TAP (Ethernet) device. Must be 0 or 1. - * @return 1 on success, 0 on failure - */ -int BTap_Init (BTap *o, BReactor *bsys, char *devname, BTap_handler_error handler_error, void *handler_error_user, int tun) WARN_UNUSED; - -// PSIPHON -int BTap_InitWithFD (BTap *o, BReactor *bsys, int fd, int mtu, BTap_handler_error handler_error, void *handler_error_user, int tun) WARN_UNUSED; - -enum BTap_dev_type {BTAP_DEV_TUN, BTAP_DEV_TAP}; - -enum BTap_init_type { - BTAP_INIT_STRING, -#ifndef BADVPN_USE_WINAPI - BTAP_INIT_FD, -#endif -}; - -struct BTap_init_data { - enum BTap_dev_type dev_type; - enum BTap_init_type init_type; - union { - char *string; - struct { - int fd; - int mtu; - } fd; - } init; -}; - -/** - * Initializes the TAP device. - * - * @param o the object - * @param BReactor {@link BReactor} we live in - * @param init_data struct containing initialization parameters (to allow transparent passing). - * init.data.dev_type must be either BTAP_DEV_TUN for an IP device, or - * BTAP_DEV_TAP for an Ethernet device. - * init_data.init_type must be either BTAP_INIT_STRING or BTAP_INIT_FD. - * For BTAP_INIT_STRING, init_data.init.string specifies the TUN or TAP - * device, as described next. - * On Linux: a network interface name. If it is NULL, no - * specific device will be requested, and the operating system - * may create a new device. - * On Windows: a string "component_id:device_name", where - * component_id is a string identifying the driver, and device_name - * is the name of the network interface. If component_id is empty, - * a hardcoded default will be used instead. If device_name is empty, - * the first device found with a matching component_id will be used. - * Specifying NULL is equivalent to specifying ":". - * For BTAP_INIT_FD, the device is initialized using a file descriptor. - * In this case, init_data.init.fd.fd must be set to the file descriptor, - * and init_data.init.fd.mtu must be set to the largest IP packet or - * Ethernet frame supported, for a TUN or TAP device, respectively. - * File descriptor initialization is not supported on Windows. - * @param handler_error error handler function - * @param handler_error_user value passed to error handler - * @return 1 on success, 0 on failure - */ -int BTap_Init2 (BTap *o, BReactor *reactor, struct BTap_init_data init_data, BTap_handler_error handler_error, void *handler_error_user) WARN_UNUSED; - -/** - * Frees the TAP device. - * - * @param o the object - */ -void BTap_Free (BTap *o); - -/** - * Returns the device's maximum transmission unit (including any protocol headers). - * - * @param o the object - * @return device's MTU - */ -int BTap_GetMTU (BTap *o); - -/** - * Sends a packet to the device. - * Any errors will be reported via a job. - * - * @param o the object - * @param data packet to send - * @param data_len length of packet. Must be >=0 and <=MTU, as reported by {@link BTap_GetMTU}. - */ -void BTap_Send (BTap *o, uint8_t *data, int data_len); - -/** - * Returns a {@link PacketRecvInterface} for reading packets from the device. - * The MTU of the interface will be {@link BTap_GetMTU}. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * BTap_GetOutput (BTap *o); - -#endif diff --git a/external/badvpn_dns/tuntap/CMakeLists.txt b/external/badvpn_dns/tuntap/CMakeLists.txt deleted file mode 100644 index fd451c1..0000000 --- a/external/badvpn_dns/tuntap/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(TUNTAP_ADDITIONAL_SOURCES) -if (WIN32) - list(APPEND TUNTAP_ADDITIONAL_SOURCES tapwin32-funcs.c) -endif () - -set(TUNTAP_SOURCES - BTap.c - ${TUNTAP_ADDITIONAL_SOURCES} -) -badvpn_add_library(tuntap "system;flow" "" "${TUNTAP_SOURCES}") diff --git a/external/badvpn_dns/tuntap/tapwin32-funcs.c b/external/badvpn_dns/tuntap/tapwin32-funcs.c deleted file mode 100644 index 37ce05d..0000000 --- a/external/badvpn_dns/tuntap/tapwin32-funcs.c +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @file tapwin32-funcs.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#include <misc/debug.h> -#include <misc/ipaddr.h> -#include <misc/maxalign.h> -#include <misc/strdup.h> - -#include "wintap-common.h" - -#include <tuntap/tapwin32-funcs.h> - -static int split_spec (char *name, char *sep, char **out_fields[], int num_fields) -{ - ASSERT(num_fields > 0) - ASSERT(strlen(sep) > 0) - - size_t seplen = strlen(sep); - - int i = 0; - while (i < num_fields - 1) { - char *s = strstr(name, sep); - if (!s) { - DEBUG("missing separator number %d", (i + 1)); - goto fail; - } - - if (!(*out_fields[i] = b_strdup_bin(name, s - name))) { - DEBUG("b_strdup_bin failed"); - goto fail; - } - - name = s + seplen; - i++; - } - - if (!(*out_fields[i] = b_strdup(name))) { - DEBUG("b_strdup_bin failed"); - goto fail; - } - - return 1; - -fail: - while (i-- > 0) { - free(*out_fields[i]); - } - return 0; -} - -int tapwin32_parse_tap_spec (char *name, char **out_component_id, char **out_human_name) -{ - char **out_fields[2]; - out_fields[0] = out_component_id; - out_fields[1] = out_human_name; - - return split_spec(name, ":", out_fields, 2); -} - -int tapwin32_parse_tun_spec (char *name, char **out_component_id, char **out_human_name, uint32_t out_addrs[3]) -{ - char *addr_strs[3]; - - char **out_fields[5]; - out_fields[0] = out_component_id; - out_fields[1] = out_human_name; - out_fields[2] = &addr_strs[0]; - out_fields[3] = &addr_strs[1]; - out_fields[4] = &addr_strs[2]; - - if (!split_spec(name, ":", out_fields, 5)) { - goto fail0; - } - - for (int i = 0; i < 3; i++) { - if (!ipaddr_parse_ipv4_addr(addr_strs[i], &out_addrs[i])) { - goto fail1; - } - } - - free(addr_strs[0]); - free(addr_strs[1]); - free(addr_strs[2]); - - return 1; - -fail1: - free(*out_component_id); - free(*out_human_name); - free(addr_strs[0]); - free(addr_strs[1]); - free(addr_strs[2]); -fail0: - return 0; -} - -int tapwin32_find_device (char *device_component_id, char *device_name, char (*device_path)[TAPWIN32_MAX_REG_SIZE]) -{ - // open adapter key - // used to find all devices with the given ComponentId - HKEY adapter_key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key) != ERROR_SUCCESS) { - DEBUG("Error opening adapter key"); - return 0; - } - - char net_cfg_instance_id[TAPWIN32_MAX_REG_SIZE]; - int found = 0; - int pres; - - DWORD i; - for (i = 0;; i++) { - DWORD len; - DWORD type; - - char key_name[TAPWIN32_MAX_REG_SIZE]; - len = sizeof(key_name); - if (RegEnumKeyEx(adapter_key, i, key_name, &len, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { - break; - } - - char unit_string[TAPWIN32_MAX_REG_SIZE]; - pres = _snprintf(unit_string, sizeof(unit_string), "%s\%s", ADAPTER_KEY, key_name); - if (pres < 0 || pres == sizeof(unit_string)) { - continue; - } - HKEY unit_key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key) != ERROR_SUCCESS) { - continue; - } - - char component_id[TAPWIN32_MAX_REG_SIZE]; - len = sizeof(component_id); - if (RegQueryValueEx(unit_key, "ComponentId", NULL, &type, (LPBYTE)component_id, &len) != ERROR_SUCCESS || type != REG_SZ) { - ASSERT_FORCE(RegCloseKey(unit_key) == ERROR_SUCCESS) - continue; - } - - len = sizeof(net_cfg_instance_id); - if (RegQueryValueEx(unit_key, "NetCfgInstanceId", NULL, &type, (LPBYTE)net_cfg_instance_id, &len) != ERROR_SUCCESS || type != REG_SZ) { - ASSERT_FORCE(RegCloseKey(unit_key) == ERROR_SUCCESS) - continue; - } - - RegCloseKey(unit_key); - - // check if ComponentId matches - if (!strcmp(component_id, device_component_id)) { - // if no name was given, use the first device with the given ComponentId - if (!device_name) { - found = 1; - break; - } - - // open connection key - char conn_string[TAPWIN32_MAX_REG_SIZE]; - pres = _snprintf(conn_string, sizeof(conn_string), "%s\%s\Connection", NETWORK_CONNECTIONS_KEY, net_cfg_instance_id); - if (pres < 0 || pres == sizeof(conn_string)) { - continue; - } - HKEY conn_key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, conn_string, 0, KEY_READ, &conn_key) != ERROR_SUCCESS) { - continue; - } - - // read name - char name[TAPWIN32_MAX_REG_SIZE]; - len = sizeof(name); - if (RegQueryValueEx(conn_key, "Name", NULL, &type, (LPBYTE)name, &len) != ERROR_SUCCESS || type != REG_SZ) { - ASSERT_FORCE(RegCloseKey(conn_key) == ERROR_SUCCESS) - continue; - } - - ASSERT_FORCE(RegCloseKey(conn_key) == ERROR_SUCCESS) - - // check name - if (!strcmp(name, device_name)) { - found = 1; - break; - } - } - } - - ASSERT_FORCE(RegCloseKey(adapter_key) == ERROR_SUCCESS) - - if (!found) { - return 0; - } - - pres = _snprintf(*device_path, sizeof(*device_path), "\\.\Global\%s.tap", net_cfg_instance_id); - if (pres < 0 || pres == sizeof(*device_path)) { - return 0; - } - - return 1; -} diff --git a/external/badvpn_dns/tuntap/tapwin32-funcs.h b/external/badvpn_dns/tuntap/tapwin32-funcs.h deleted file mode 100644 index fed66de..0000000 --- a/external/badvpn_dns/tuntap/tapwin32-funcs.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tapwin32-funcs.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_TUNTAP_TAPWIN32_FUNCS_H -#define BADVPN_TUNTAP_TAPWIN32_FUNCS_H - -#include <stdint.h> -#include <windows.h> - -#define TAPWIN32_MAX_REG_SIZE 256 - -int tapwin32_parse_tap_spec (char *name, char **out_component_id, char **out_human_name); -int tapwin32_parse_tun_spec (char *name, char **out_component_id, char **out_human_name, uint32_t out_addrs[3]); -int tapwin32_find_device (char *device_component_id, char *device_name, char (*device_path)[TAPWIN32_MAX_REG_SIZE]); - -#endif diff --git a/external/badvpn_dns/tuntap/wintap-common.h b/external/badvpn_dns/tuntap/wintap-common.h deleted file mode 100644 index 922c851..0000000 --- a/external/badvpn_dns/tuntap/wintap-common.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file wintap-common.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * API definitions for TAP-Win32. - */ - -#define TAP_IOCTL_CONFIG_TUN CTL_CODE(FILE_DEVICE_UNKNOWN, 10, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define TAP_IOCTL_GET_MTU CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define TAP_IOCTL_SET_MEDIA_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define ADAPTER_KEY "SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}" -#define NETWORK_CONNECTIONS_KEY "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}" diff --git a/external/badvpn_dns/udevmonitor/CMakeLists.txt b/external/badvpn_dns/udevmonitor/CMakeLists.txt deleted file mode 100644 index a95f605..0000000 --- a/external/badvpn_dns/udevmonitor/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(UDEVMONITOR_SOURCES - NCDUdevMonitorParser.c - NCDUdevMonitor.c - NCDUdevCache.c - NCDUdevManager.c -) -badvpn_add_library(udevmonitor "system;flow;stringmap" "" "${UDEVMONITOR_SOURCES}") diff --git a/external/badvpn_dns/udevmonitor/NCDUdevCache.c b/external/badvpn_dns/udevmonitor/NCDUdevCache.c deleted file mode 100644 index cb88821..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevCache.c +++ /dev/null @@ -1,417 +0,0 @@ -/** - * @file NCDUdevCache.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/string_begins_with.h> -#include <misc/concat_strings.h> -#include <misc/compare.h> -#include <base/BLog.h> - -#include <udevmonitor/NCDUdevCache.h> - -#include <generated/blog_channel_NCDUdevCache.h> - -static int string_comparator (void *unused, const char **str1, const char **str2) -{ - int c = strcmp(*str1, *str2); - return B_COMPARE(c, 0); -} - -static void free_device (NCDUdevCache *o, struct NCDUdevCache_device *device) -{ - if (device->is_cleaned) { - // remove from cleaned devices list - LinkedList1_Remove(&o->cleaned_devices_list, &device->cleaned_devices_list_node); - } else { - // remove from devices tree - BAVL_Remove(&o->devices_tree, &device->devices_tree_node); - } - - // free map - BStringMap_Free(&device->map); - - // free structure - free(device); -} - -static struct NCDUdevCache_device * lookup_device (NCDUdevCache *o, const char *devpath) -{ - BAVLNode *tree_node = BAVL_LookupExact(&o->devices_tree, &devpath); - if (!tree_node) { - return NULL; - } - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - return device; -} - -static void rename_devices (NCDUdevCache *o, const char *prefix, const char *new_prefix) -{ - ASSERT(strlen(prefix) > 0) - - size_t prefix_len = strlen(prefix); - - // lookup prefix - BAVLNode *tree_node = BAVL_Lookup(&o->devices_tree, &prefix); - if (!tree_node) { - return; - } - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - // if the result does not begin with prefix, we might gave gotten the device before all - // devices beginning with prefix, so skip it - if (!string_begins_with(device->devpath, prefix)) { - tree_node = BAVL_GetNext(&o->devices_tree, tree_node); - } - - while (tree_node) { - // get next node (must be here because we rename this device) - BAVLNode *next_tree_node = BAVL_GetNext(&o->devices_tree, tree_node); - - // get device - device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - // if it doesn't begin with prefix, we're done - if (!string_begins_with(device->devpath, prefix)) { - break; - } - - // build new devpath - char *new_devpath = concat_strings(2, new_prefix, device->devpath + prefix_len); - if (!new_devpath) { - BLog(BLOG_ERROR, "concat_strings failed"); - goto fail_loop0; - } - - // make sure the new name does not exist - if (BAVL_LookupExact(&o->devices_tree, &new_devpath)) { - BLog(BLOG_ERROR, "rename destination already exists"); - goto fail_loop1; - } - - BLog(BLOG_DEBUG, "rename %s -> %s", device->devpath, new_devpath); - - // remove from tree - BAVL_Remove(&o->devices_tree, &device->devices_tree_node); - - // update devpath in map - if (!BStringMap_Set(&device->map, "DEVPATH", new_devpath)) { - BLog(BLOG_ERROR, "BStringMap_Set failed"); - ASSERT_EXECUTE(BAVL_Insert(&o->devices_tree, &device->devices_tree_node, NULL)) - goto fail_loop1; - } - - // update devpath pointer - device->devpath = BStringMap_Get(&device->map, "DEVPATH"); - ASSERT(device->devpath) - - // insert to tree - ASSERT_EXECUTE(BAVL_Insert(&o->devices_tree, &device->devices_tree_node, NULL)) - - fail_loop1: - free(new_devpath); - fail_loop0: - tree_node = next_tree_node; - } -} - -static int add_device (NCDUdevCache *o, BStringMap map) -{ - ASSERT(BStringMap_Get(&map, "DEVPATH")) - - // alloc structure - struct NCDUdevCache_device *device = malloc(sizeof(*device)); - if (!device) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init map - device->map = map; - - // set device path - device->devpath = BStringMap_Get(&device->map, "DEVPATH"); - - // insert to devices tree - BAVLNode *ex_node; - if (!BAVL_Insert(&o->devices_tree, &device->devices_tree_node, &ex_node)) { - BLog(BLOG_DEBUG, "update %s", device->devpath); - - // get existing device - struct NCDUdevCache_device *ex_device = UPPER_OBJECT(ex_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!ex_device->is_cleaned) - - // remove exiting device - free_device(o, ex_device); - - // insert - ASSERT_EXECUTE(BAVL_Insert(&o->devices_tree, &device->devices_tree_node, NULL)) - } else { - BLog(BLOG_DEBUG, "add %s", device->devpath); - } - - // set not cleaned - device->is_cleaned = 0; - - // set refreshed - device->is_refreshed = 1; - - return 1; - -fail0: - return 0; -} - -void NCDUdevCache_Init (NCDUdevCache *o) -{ - // init devices tree - BAVL_Init(&o->devices_tree, OFFSET_DIFF(struct NCDUdevCache_device, devpath, devices_tree_node), (BAVL_comparator)string_comparator, NULL); - - // init cleaned devices list - LinkedList1_Init(&o->cleaned_devices_list); - - DebugObject_Init(&o->d_obj); -} - -void NCDUdevCache_Free (NCDUdevCache *o) -{ - DebugObject_Free(&o->d_obj); - - // free cleaned devices - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&o->cleaned_devices_list)) { - struct NCDUdevCache_device *device = UPPER_OBJECT(list_node, struct NCDUdevCache_device, cleaned_devices_list_node); - ASSERT(device->is_cleaned) - free_device(o, device); - } - - // free devices - BAVLNode *tree_node; - while (tree_node = BAVL_GetFirst(&o->devices_tree)) { - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - free_device(o, device); - } -} - -const BStringMap * NCDUdevCache_Query (NCDUdevCache *o, const char *devpath) -{ - DebugObject_Access(&o->d_obj); - - // lookup device - struct NCDUdevCache_device *device = lookup_device(o, devpath); - if (!device) { - return NULL; - } - - // return map - return &device->map; -} - -int NCDUdevCache_Event (NCDUdevCache *o, BStringMap map) -{ - DebugObject_Access(&o->d_obj); - - // get device path - const char *devpath = BStringMap_Get(&map, "DEVPATH"); - if (!devpath) { - BLog(BLOG_ERROR, "missing DEVPATH"); - goto fail; - } - - // get action - const char *action = BStringMap_Get(&map, "ACTION"); - - // if this is a remove event, remove device if we have it - if (action && !strcmp(action, "remove")) { - // remove existing device - struct NCDUdevCache_device *device = lookup_device(o, devpath); - if (device) { - BLog(BLOG_DEBUG, "remove %s", devpath); - free_device(o, device); - } else { - BLog(BLOG_DEBUG, "remove unknown %s", devpath); - } - - // eat map - BStringMap_Free(&map); - - return 1; - } - - // if this is a move event, remove old device and contaned devices - if (action && !strcmp(action, "move")) { - const char *devpath_old = BStringMap_Get(&map, "DEVPATH_OLD"); - if (!devpath_old) { - goto fail_rename0; - } - - // remove old device - struct NCDUdevCache_device *old_device = lookup_device(o, devpath_old); - if (old_device) { - BLog(BLOG_DEBUG, "remove moved %s", old_device->devpath); - free_device(o, old_device); - } - - // construct prefix "<devpath_old>/" and new prefix "<devpath>/" - char *prefix = concat_strings(2, devpath_old, "/"); - if (!prefix) { - BLog(BLOG_ERROR, "concat_strings failed"); - goto fail_rename0;; - } - char *new_prefix = concat_strings(2, devpath, "/"); - if (!new_prefix) { - BLog(BLOG_ERROR, "concat_strings failed"); - goto fail_rename1; - } - - // rename devices with paths starting with prefix - rename_devices(o, prefix, new_prefix); - - free(new_prefix); - fail_rename1: - free(prefix); - fail_rename0:; - } - - // add device - if (!add_device(o, map)) { - BLog(BLOG_DEBUG, "failed to add device %s", devpath); - goto fail; - } - - return 1; - -fail: - return 0; -} - -void NCDUdevCache_StartClean (NCDUdevCache *o) -{ - DebugObject_Access(&o->d_obj); - - // mark all devices not refreshed - BAVLNode *tree_node = BAVL_GetFirst(&o->devices_tree); - while (tree_node) { - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - // set device not refreshed - device->is_refreshed = 0; - - tree_node = BAVL_GetNext(&o->devices_tree, tree_node); - } -} - -void NCDUdevCache_FinishClean (NCDUdevCache *o) -{ - DebugObject_Access(&o->d_obj); - - // move all devices not marked refreshed to the cleaned devices list - BAVLNode *tree_node = BAVL_GetFirst(&o->devices_tree); - while (tree_node) { - BAVLNode *next_tree_node = BAVL_GetNext(&o->devices_tree, tree_node); - - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - if (!device->is_refreshed) { - BLog(BLOG_DEBUG, "clean %s", device->devpath); - - // remove from devices tree - BAVL_Remove(&o->devices_tree, &device->devices_tree_node); - - // insert to cleaned devices list - LinkedList1_Append(&o->cleaned_devices_list, &device->cleaned_devices_list_node); - - // set device cleaned - device->is_cleaned = 1; - } - - tree_node = next_tree_node; - } -} - -int NCDUdevCache_GetCleanedDevice (NCDUdevCache *o, BStringMap *out_map) -{ - DebugObject_Access(&o->d_obj); - - // get cleaned device - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->cleaned_devices_list); - if (!list_node) { - return 0; - } - struct NCDUdevCache_device *device = UPPER_OBJECT(list_node, struct NCDUdevCache_device, cleaned_devices_list_node); - ASSERT(device->is_cleaned) - - // remove from cleaned devices list - LinkedList1_Remove(&o->cleaned_devices_list, &device->cleaned_devices_list_node); - - // give away map - *out_map = device->map; - - // free structure - free(device); - - return 1; -} - -const char * NCDUdevCache_First (NCDUdevCache *o) -{ - DebugObject_Access(&o->d_obj); - - BAVLNode *tree_node = BAVL_GetFirst(&o->devices_tree); - if (!tree_node) { - return NULL; - } - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - return device->devpath; -} - -const char * NCDUdevCache_Next (NCDUdevCache *o, const char *key) -{ - ASSERT(BAVL_LookupExact(&o->devices_tree, &key)) - - BAVLNode *tree_node = BAVL_GetNext(&o->devices_tree, BAVL_LookupExact(&o->devices_tree, &key)); - if (!tree_node) { - return NULL; - } - struct NCDUdevCache_device *device = UPPER_OBJECT(tree_node, struct NCDUdevCache_device, devices_tree_node); - ASSERT(!device->is_cleaned) - - return device->devpath; -} diff --git a/external/badvpn_dns/udevmonitor/NCDUdevCache.h b/external/badvpn_dns/udevmonitor/NCDUdevCache.h deleted file mode 100644 index 2d9e8d8..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevCache.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file NCDUdevCache.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UDEVMONITOR_NCDUDEVCACHE_H -#define BADVPN_UDEVMONITOR_NCDUDEVCACHE_H - -#include <misc/debug.h> -#include <structure/BAVL.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <stringmap/BStringMap.h> - -struct NCDUdevCache_device { - BStringMap map; - const char *devpath; - int is_cleaned; - union { - BAVLNode devices_tree_node; - LinkedList1Node cleaned_devices_list_node; - }; - int is_refreshed; -}; - -typedef struct { - BAVL devices_tree; - LinkedList1 cleaned_devices_list; - DebugObject d_obj; -} NCDUdevCache; - -void NCDUdevCache_Init (NCDUdevCache *o); -void NCDUdevCache_Free (NCDUdevCache *o); -const BStringMap * NCDUdevCache_Query (NCDUdevCache *o, const char *devpath); -int NCDUdevCache_Event (NCDUdevCache *o, BStringMap map) WARN_UNUSED; -void NCDUdevCache_StartClean (NCDUdevCache *o); -void NCDUdevCache_FinishClean (NCDUdevCache *o); -int NCDUdevCache_GetCleanedDevice (NCDUdevCache *o, BStringMap *out_map); -const char * NCDUdevCache_First (NCDUdevCache *o); -const char * NCDUdevCache_Next (NCDUdevCache *o, const char *key); - -#endif diff --git a/external/badvpn_dns/udevmonitor/NCDUdevManager.c b/external/badvpn_dns/udevmonitor/NCDUdevManager.c deleted file mode 100644 index 4a44fb7..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevManager.c +++ /dev/null @@ -1,547 +0,0 @@ -/** - * @file NCDUdevManager.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <base/BLog.h> - -#include <udevmonitor/NCDUdevManager.h> - -#include <generated/blog_channel_NCDUdevManager.h> - -#define RESTART_TIMER_TIME 5000 - -static int event_to_map (NCDUdevMonitor *monitor, BStringMap *out_map); -static void free_event (NCDUdevClient *o, struct NCDUdevClient_event *e); -static void queue_event (NCDUdevManager *o, NCDUdevMonitor *monitor, NCDUdevClient *client); -static void queue_mapless_event (NCDUdevManager *o, const char *devpath, NCDUdevClient *client); -static void process_event (NCDUdevManager *o, NCDUdevMonitor *monitor); -static void try_monitor (NCDUdevManager *o); -static void reset_monitor (NCDUdevManager *o); -static void timer_handler (NCDUdevManager *o); -static void monitor_handler_event (NCDUdevManager *o); -static void monitor_handler_error (NCDUdevManager *o, int is_error); -static void info_monitor_handler_event (NCDUdevManager *o); -static void info_monitor_handler_error (NCDUdevManager *o, int is_error); -static void next_job_handler (NCDUdevClient *o); - -static int event_to_map (NCDUdevMonitor *monitor, BStringMap *out_map) -{ - NCDUdevMonitor_AssertReady(monitor); - - // init map - BStringMap_Init(out_map); - - // insert properties to map - int num_properties = NCDUdevMonitor_GetNumProperties(monitor); - for (int i = 0; i < num_properties; i++) { - const char *name; - const char *value; - NCDUdevMonitor_GetProperty(monitor, i, &name, &value); - - if (!BStringMap_Set(out_map, name, value)) { - BLog(BLOG_ERROR, "BStringMap_Set failed"); - goto fail1; - } - } - - return 1; - -fail1: - BStringMap_Free(out_map); - return 0; -} - -static void free_event (NCDUdevClient *o, struct NCDUdevClient_event *e) -{ - // remove from events list - LinkedList1_Remove(&o->events_list, &e->events_list_node); - - // free map - if (e->have_map) { - BStringMap_Free(&e->map); - } - - // free devpath - free(e->devpath); - - // free structure - free(e); -} - -static void queue_event (NCDUdevManager *o, NCDUdevMonitor *monitor, NCDUdevClient *client) -{ - NCDUdevMonitor_AssertReady(monitor); - - // alloc event - struct NCDUdevClient_event *e = malloc(sizeof(*e)); - if (!e) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // build map - if (!event_to_map(monitor, &e->map)) { - goto fail1; - } - - // set have map - e->have_map = 1; - - // get devpath - const char *devpath = BStringMap_Get(&e->map, "DEVPATH"); - if (!devpath) { - BLog(BLOG_ERROR, "DEVPATH missing"); - goto fail2; - } - - // copy devpath - if (!(e->devpath = strdup(devpath))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail2; - } - - // insert to client's events list - LinkedList1_Append(&client->events_list, &e->events_list_node); - - // if client is running, set next job - if (client->running) { - BPending_Set(&client->next_job); - } - - return; - -fail2: - BStringMap_Free(&e->map); -fail1: - free(e); -fail0: - return; -} - -static void queue_mapless_event (NCDUdevManager *o, const char *devpath, NCDUdevClient *client) -{ - // alloc event - struct NCDUdevClient_event *e = malloc(sizeof(*e)); - if (!e) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set have no map - e->have_map = 0; - - // copy devpath - if (!(e->devpath = strdup(devpath))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail1; - } - - // insert to client's events list - LinkedList1_Append(&client->events_list, &e->events_list_node); - - // if client is running, set next job - if (client->running) { - BPending_Set(&client->next_job); - } - - return; - -fail1: - free(e); -fail0: - return; -} - -static void process_event (NCDUdevManager *o, NCDUdevMonitor *monitor) -{ - NCDUdevMonitor_AssertReady(monitor); - - // build map from event - BStringMap map; - if (!event_to_map(monitor, &map)) { - BLog(BLOG_ERROR, "failed to build map"); - return; - } - - // pass event to cache - if (!NCDUdevCache_Event(&o->cache, map)) { - BLog(BLOG_ERROR, "failed to cache"); - BStringMap_Free(&map); - return; - } - - // queue event to clients - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->clients_list); - while (list_node) { - NCDUdevClient *client = UPPER_OBJECT(list_node, NCDUdevClient, clients_list_node); - queue_event(o, monitor, client); - list_node = LinkedList1Node_Next(list_node); - } -} - -static void try_monitor (NCDUdevManager *o) -{ - ASSERT(!o->have_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - int mode = (o->no_udev ? NCDUDEVMONITOR_MODE_MONITOR_KERNEL : NCDUDEVMONITOR_MODE_MONITOR_UDEV); - - // init monitor - if (!NCDUdevMonitor_Init(&o->monitor, o->reactor, o->manager, mode, o, - (NCDUdevMonitor_handler_event)monitor_handler_event, - (NCDUdevMonitor_handler_error)monitor_handler_error - )) { - BLog(BLOG_ERROR, "NCDUdevMonitor_Init failed"); - - // set restart timer - BReactor_SetTimer(o->reactor, &o->restart_timer); - return; - } - - // set have monitor - o->have_monitor = 1; - - // set not have info monitor - o->have_info_monitor = 0; -} - -static void reset_monitor (NCDUdevManager *o) -{ - ASSERT(o->have_monitor) - ASSERT(!o->have_info_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - // free monitor - NCDUdevMonitor_Free(&o->monitor); - - // set have no monitor - o->have_monitor = 0; - - // set restart timer - BReactor_SetTimer(o->reactor, &o->restart_timer); -} - -static void timer_handler (NCDUdevManager *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_monitor) - - // try again - try_monitor(o); -} - -static void monitor_handler_event (NCDUdevManager *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_monitor) - ASSERT(!o->have_info_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - if (NCDUdevMonitor_IsReadyEvent(&o->monitor)) { - BLog(BLOG_INFO, "monitor ready"); - - // init info monitor - if (!NCDUdevMonitor_Init(&o->info_monitor, o->reactor, o->manager, NCDUDEVMONITOR_MODE_INFO, o, - (NCDUdevMonitor_handler_event)info_monitor_handler_event, - (NCDUdevMonitor_handler_error)info_monitor_handler_error - )) { - BLog(BLOG_ERROR, "NCDUdevMonitor_Init failed"); - reset_monitor(o); - return; - } - - // set have info monitor - o->have_info_monitor = 1; - - // start cache cleanup - NCDUdevCache_StartClean(&o->cache); - - // hold processing monitor events until info monitor is done - return; - } - - // accept event - NCDUdevMonitor_Done(&o->monitor); - - // process event - process_event(o, &o->monitor); -} - -static void monitor_handler_error (NCDUdevManager *o, int is_error) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - BLog(BLOG_ERROR, "monitor error"); - - if (o->have_info_monitor) { - // free info monitor - NCDUdevMonitor_Free(&o->info_monitor); - - // set have no info monitor - o->have_info_monitor = 0; - } - - // reset monitor - reset_monitor(o); -} - -static void info_monitor_handler_event (NCDUdevManager *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_monitor) - ASSERT(o->have_info_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - // accept event - NCDUdevMonitor_Done(&o->info_monitor); - - // process event - process_event(o, &o->info_monitor); -} - -static void info_monitor_handler_error (NCDUdevManager *o, int is_error) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_monitor) - ASSERT(o->have_info_monitor) - ASSERT(!BTimer_IsRunning(&o->restart_timer)) - - if (is_error) { - BLog(BLOG_ERROR, "info monitor error"); - } else { - BLog(BLOG_INFO, "info monitor finished"); - } - - // free info monitor - NCDUdevMonitor_Free(&o->info_monitor); - - // set have no info monitor - o->have_info_monitor = 0; - - if (is_error) { - // reset monitor - reset_monitor(o); - } else { - // continue processing monitor events - NCDUdevMonitor_Done(&o->monitor); - - // finish cache cleanup - NCDUdevCache_FinishClean(&o->cache); - - // collect cleaned devices - BStringMap map; - while (NCDUdevCache_GetCleanedDevice(&o->cache, &map)) { - // get devpath - const char *devpath = BStringMap_Get(&map, "DEVPATH"); - ASSERT(devpath) - - // queue mapless event to clients - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->clients_list); - while (list_node) { - NCDUdevClient *client = UPPER_OBJECT(list_node, NCDUdevClient, clients_list_node); - queue_mapless_event(o, devpath, client); - list_node = LinkedList1Node_Next(list_node); - } - - BStringMap_Free(&map); - } - } -} - -static void next_job_handler (NCDUdevClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!LinkedList1_IsEmpty(&o->events_list)) - ASSERT(o->running) - - // get event - struct NCDUdevClient_event *e = UPPER_OBJECT(LinkedList1_GetFirst(&o->events_list), struct NCDUdevClient_event, events_list_node); - - // grab map from event - int have_map = e->have_map; - BStringMap map = e->map; - - // grab devpath from event - char *devpath = e->devpath; - - // remove from events list - LinkedList1_Remove(&o->events_list, &e->events_list_node); - - // free structure - free(e); - - // schedule next event if needed - if (!LinkedList1_IsEmpty(&o->events_list)) { - BPending_Set(&o->next_job); - } - - // give map to handler - o->handler(o->user, devpath, have_map, map); - return; -} - -void NCDUdevManager_Init (NCDUdevManager *o, int no_udev, BReactor *reactor, BProcessManager *manager) -{ - ASSERT(no_udev == 0 || no_udev == 1) - - // init arguments - o->no_udev = no_udev; - o->reactor = reactor; - o->manager = manager; - - // init clients list - LinkedList1_Init(&o->clients_list); - - // init cache - NCDUdevCache_Init(&o->cache); - - // init restart timer - BTimer_Init(&o->restart_timer, RESTART_TIMER_TIME, (BTimer_handler)timer_handler, o); - - // set have no monitor - o->have_monitor = 0; - - DebugObject_Init(&o->d_obj); -} - -void NCDUdevManager_Free (NCDUdevManager *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(LinkedList1_IsEmpty(&o->clients_list)) - - if (o->have_monitor) { - // free info monitor - if (o->have_info_monitor) { - NCDUdevMonitor_Free(&o->info_monitor); - } - - // free monitor - NCDUdevMonitor_Free(&o->monitor); - } - - // free restart timer - BReactor_RemoveTimer(o->reactor, &o->restart_timer); - - // free cache - NCDUdevCache_Free(&o->cache); -} - -const BStringMap * NCDUdevManager_Query (NCDUdevManager *o, const char *devpath) -{ - DebugObject_Access(&o->d_obj); - - return NCDUdevCache_Query(&o->cache, devpath); -} - -void NCDUdevClient_Init (NCDUdevClient *o, NCDUdevManager *m, void *user, - NCDUdevClient_handler handler) -{ - DebugObject_Access(&m->d_obj); - - // init arguments - o->m = m; - o->user = user; - o->handler = handler; - - // insert to manager's list - LinkedList1_Append(&m->clients_list, &o->clients_list_node); - - // init events list - LinkedList1_Init(&o->events_list); - - // init next job - BPending_Init(&o->next_job, BReactor_PendingGroup(m->reactor), (BPending_handler)next_job_handler, o); - - // set running - o->running = 1; - - // queue all devices from cache - const char *devpath = NCDUdevCache_First(&m->cache); - while (devpath) { - queue_mapless_event(m, devpath, o); - devpath = NCDUdevCache_Next(&m->cache, devpath); - } - - // if this is the first client, init monitor - if (!m->have_monitor && !BTimer_IsRunning(&m->restart_timer)) { - try_monitor(m); - } - - DebugObject_Init(&o->d_obj); -} - -void NCDUdevClient_Free (NCDUdevClient *o) -{ - DebugObject_Free(&o->d_obj); - NCDUdevManager *m = o->m; - - // free events - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&o->events_list)) { - struct NCDUdevClient_event *e = UPPER_OBJECT(list_node, struct NCDUdevClient_event, events_list_node); - free_event(o, e); - } - - // free next job - BPending_Free(&o->next_job); - - // remove from manager's list - LinkedList1_Remove(&m->clients_list, &o->clients_list_node); -} - -void NCDUdevClient_Pause (NCDUdevClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->running) - - // set not running - o->running = 0; - - // unset next job to avoid reporting queued events - BPending_Unset(&o->next_job); -} - -void NCDUdevClient_Continue (NCDUdevClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->running) - - // set running - o->running = 1; - - // set next job if we have events queued - if (!LinkedList1_IsEmpty(&o->events_list)) { - BPending_Set(&o->next_job); - } -} diff --git a/external/badvpn_dns/udevmonitor/NCDUdevManager.h b/external/badvpn_dns/udevmonitor/NCDUdevManager.h deleted file mode 100644 index 26ecfc6..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevManager.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file NCDUdevManager.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UDEVMONITOR_NCDUDEVMANAGER_H -#define BADVPN_UDEVMONITOR_NCDUDEVMANAGER_H - -#include <misc/debug.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <udevmonitor/NCDUdevMonitor.h> -#include <udevmonitor/NCDUdevCache.h> -#include <stringmap/BStringMap.h> - -typedef void (*NCDUdevClient_handler) (void *user, char *devpath, int have_map, BStringMap map); - -typedef struct { - int no_udev; - BReactor *reactor; - BProcessManager *manager; - LinkedList1 clients_list; - NCDUdevCache cache; - BTimer restart_timer; - int have_monitor; - NCDUdevMonitor monitor; - int have_info_monitor; - NCDUdevMonitor info_monitor; - DebugObject d_obj; -} NCDUdevManager; - -typedef struct { - NCDUdevManager *m; - void *user; - NCDUdevClient_handler handler; - LinkedList1Node clients_list_node; - LinkedList1 events_list; - BPending next_job; - int running; - DebugObject d_obj; -} NCDUdevClient; - -struct NCDUdevClient_event { - char *devpath; - int have_map; - BStringMap map; - LinkedList1Node events_list_node; -}; - -void NCDUdevManager_Init (NCDUdevManager *o, int no_udev, BReactor *reactor, BProcessManager *manager); -void NCDUdevManager_Free (NCDUdevManager *o); -const BStringMap * NCDUdevManager_Query (NCDUdevManager *o, const char *devpath); - -void NCDUdevClient_Init (NCDUdevClient *o, NCDUdevManager *m, void *user, - NCDUdevClient_handler handler); -void NCDUdevClient_Free (NCDUdevClient *o); -void NCDUdevClient_Pause (NCDUdevClient *o); -void NCDUdevClient_Continue (NCDUdevClient *o); - -#endif diff --git a/external/badvpn_dns/udevmonitor/NCDUdevMonitor.c b/external/badvpn_dns/udevmonitor/NCDUdevMonitor.c deleted file mode 100644 index 56970cd..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevMonitor.c +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file NCDUdevMonitor.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stddef.h> - -#include <base/BLog.h> -#include <misc/find_program.h> - -#include <udevmonitor/NCDUdevMonitor.h> - -#include <generated/blog_channel_NCDUdevMonitor.h> - -#define PARSER_BUF_SIZE 16384 -#define PARSER_MAX_PROPERTIES 256 - -static void report_error (NCDUdevMonitor *o) -{ - ASSERT(!o->process_running) - ASSERT(!o->input_running) - - DEBUGERROR(&o->d_err, o->handler_error(o->user, (o->process_was_error || o->input_was_error))); -} - -static void process_handler_terminated (NCDUdevMonitor *o, int normally, uint8_t normally_exit_status) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->process_running) - - BLog(BLOG_INFO, "process terminated"); - - // set process not running (so we don't try to kill it) - o->process_running = 0; - - // remember process error - o->process_was_error = !(normally && normally_exit_status == 0); - - if (!o->input_running) { - report_error(o); - return; - } -} - -static void process_handler_closed (NCDUdevMonitor *o, int is_error) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->input_running) - - if (is_error) { - BLog(BLOG_ERROR, "pipe error"); - } else { - BLog(BLOG_INFO, "pipe closed"); - } - - // disconnect connector - StreamRecvConnector_DisconnectInput(&o->connector); - - // set input not running - o->input_running = 0; - - // remember input error - o->input_was_error = is_error; - - if (!o->process_running) { - report_error(o); - return; - } -} - -static void parser_handler (NCDUdevMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - o->handler_event(o->user); - return; -} - -int NCDUdevMonitor_Init (NCDUdevMonitor *o, BReactor *reactor, BProcessManager *manager, int mode, void *user, - NCDUdevMonitor_handler_event handler_event, - NCDUdevMonitor_handler_error handler_error) -{ - ASSERT(mode == NCDUDEVMONITOR_MODE_MONITOR_UDEV || mode == NCDUDEVMONITOR_MODE_INFO || mode == NCDUDEVMONITOR_MODE_MONITOR_KERNEL) - - // init arguments - o->user = user; - o->handler_event = handler_event; - o->handler_error = handler_error; - - // find programs - char *stdbuf_exec = badvpn_find_program("stdbuf"); - char *udevadm_exec = badvpn_find_program("udevadm"); - if (!stdbuf_exec) { - BLog(BLOG_ERROR, "failed to find stdbuf program"); - goto fail0; - } - if (!udevadm_exec) { - BLog(BLOG_ERROR, "failed to find udevadm program"); - goto fail0; - } - - // construct arguments - const char *argv_monitor_udev[] = {stdbuf_exec, "-o", "L", udevadm_exec, "monitor", "--udev", "--environment", NULL}; - const char *argv_monitor_kernel[] = {stdbuf_exec, "-o", "L", udevadm_exec, "monitor", "--kernel", "--environment", NULL}; - const char *argv_info[] = {stdbuf_exec, "-o", "L", udevadm_exec, "info", "--query", "all", "--export-db", NULL}; - - // choose arguments based on mode - const char **argv = NULL; // to remove warning - switch (mode) { - case NCDUDEVMONITOR_MODE_MONITOR_UDEV: argv = argv_monitor_udev; break; - case NCDUDEVMONITOR_MODE_INFO: argv = argv_info; break; - case NCDUDEVMONITOR_MODE_MONITOR_KERNEL: argv = argv_monitor_kernel; break; - default: ASSERT(0); - } - - // init process - if (!BInputProcess_Init(&o->process, reactor, manager, o, - (BInputProcess_handler_terminated)process_handler_terminated, - (BInputProcess_handler_closed)process_handler_closed - )) { - BLog(BLOG_ERROR, "BInputProcess_Init failed"); - goto fail0; - } - - // init connector - StreamRecvConnector_Init(&o->connector, BReactor_PendingGroup(reactor)); - StreamRecvConnector_ConnectInput(&o->connector, BInputProcess_GetInput(&o->process)); - - // init parser - if (!NCDUdevMonitorParser_Init(&o->parser, StreamRecvConnector_GetOutput(&o->connector), PARSER_BUF_SIZE, PARSER_MAX_PROPERTIES, - (mode == NCDUDEVMONITOR_MODE_INFO), BReactor_PendingGroup(reactor), o, - (NCDUdevMonitorParser_handler)parser_handler - )) { - BLog(BLOG_ERROR, "NCDUdevMonitorParser_Init failed"); - goto fail1; - } - - // start process - if (!BInputProcess_Start(&o->process, stdbuf_exec, (char **)argv, NULL)) { - BLog(BLOG_ERROR, "BInputProcess_Start failed"); - goto fail2; - } - - // set process running, input running - o->process_running = 1; - o->input_running = 1; - - free(udevadm_exec); - free(stdbuf_exec); - - DebugError_Init(&o->d_err, BReactor_PendingGroup(reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - NCDUdevMonitorParser_Free(&o->parser); -fail1: - StreamRecvConnector_Free(&o->connector); - BInputProcess_Free(&o->process); -fail0: - free(udevadm_exec); - free(stdbuf_exec); - return 0; -} - -void NCDUdevMonitor_Free (NCDUdevMonitor *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free parser - NCDUdevMonitorParser_Free(&o->parser); - - // free connector - StreamRecvConnector_Free(&o->connector); - - // kill process it it's running - if (o->process_running) { - BInputProcess_Kill(&o->process); - } - - // free process - BInputProcess_Free(&o->process); -} - -void NCDUdevMonitor_Done (NCDUdevMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - NCDUdevMonitorParser_AssertReady(&o->parser); - - NCDUdevMonitorParser_Done(&o->parser); -} - -int NCDUdevMonitor_IsReadyEvent (NCDUdevMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - NCDUdevMonitorParser_AssertReady(&o->parser); - - return NCDUdevMonitorParser_IsReadyEvent(&o->parser); -} -void NCDUdevMonitor_AssertReady (NCDUdevMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - NCDUdevMonitorParser_AssertReady(&o->parser); -} - -int NCDUdevMonitor_GetNumProperties (NCDUdevMonitor *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - NCDUdevMonitorParser_AssertReady(&o->parser); - - return NCDUdevMonitorParser_GetNumProperties(&o->parser); -} - -void NCDUdevMonitor_GetProperty (NCDUdevMonitor *o, int index, const char **name, const char **value) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - NCDUdevMonitorParser_AssertReady(&o->parser); - - NCDUdevMonitorParser_GetProperty(&o->parser, index, name, value); -} diff --git a/external/badvpn_dns/udevmonitor/NCDUdevMonitor.h b/external/badvpn_dns/udevmonitor/NCDUdevMonitor.h deleted file mode 100644 index eae5747..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevMonitor.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file NCDUdevMonitor.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UDEVMONITOR_NCDUDEVMONITOR_H -#define BADVPN_UDEVMONITOR_NCDUDEVMONITOR_H - -#include <misc/debug.h> -#include <misc/debugerror.h> -#include <flow/StreamRecvConnector.h> -#include <system/BInputProcess.h> -#include <udevmonitor/NCDUdevMonitorParser.h> - -#define NCDUDEVMONITOR_MODE_MONITOR_UDEV 0 -#define NCDUDEVMONITOR_MODE_INFO 1 -#define NCDUDEVMONITOR_MODE_MONITOR_KERNEL 2 - -typedef void (*NCDUdevMonitor_handler_event) (void *user); -typedef void (*NCDUdevMonitor_handler_error) (void *user, int is_error); - -typedef struct { - void *user; - NCDUdevMonitor_handler_event handler_event; - NCDUdevMonitor_handler_error handler_error; - BInputProcess process; - int process_running; - int process_was_error; - int input_running; - int input_was_error; - StreamRecvConnector connector; - NCDUdevMonitorParser parser; - DebugObject d_obj; - DebugError d_err; -} NCDUdevMonitor; - -int NCDUdevMonitor_Init (NCDUdevMonitor *o, BReactor *reactor, BProcessManager *manager, int mode, void *user, - NCDUdevMonitor_handler_event handler_event, - NCDUdevMonitor_handler_error handler_error) WARN_UNUSED; -void NCDUdevMonitor_Free (NCDUdevMonitor *o); -void NCDUdevMonitor_Done (NCDUdevMonitor *o); -void NCDUdevMonitor_AssertReady (NCDUdevMonitor *o); -int NCDUdevMonitor_IsReadyEvent (NCDUdevMonitor *o); -int NCDUdevMonitor_GetNumProperties (NCDUdevMonitor *o); -void NCDUdevMonitor_GetProperty (NCDUdevMonitor *o, int index, const char **name, const char **value); - -#endif diff --git a/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.c b/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.c deleted file mode 100644 index 9ec0ef1..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.c +++ /dev/null @@ -1,358 +0,0 @@ -/** - * @file NCDUdevMonitorParser.c - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/string_begins_with.h> -#include <misc/balloc.h> -#include <base/BLog.h> - -#include <udevmonitor/NCDUdevMonitorParser.h> - -#include <generated/blog_channel_NCDUdevMonitorParser.h> - -#define PROPERTY_REGEX "^([^=]+)=(.*)$" - -static uint8_t * find_end (uint8_t *buf, size_t len) -{ - while (len >= 2) { - if (buf[0] == '\n' && buf[1] == '\n') { - return (buf + 2); - } - buf++; - len--; - } - - return NULL; -} - -static int parse_property (NCDUdevMonitorParser *o, char *data) -{ - ASSERT(o->ready_num_properties >= 0) - ASSERT(o->ready_num_properties <= o->max_properties) - - if (o->ready_num_properties == o->max_properties) { - BLog(BLOG_ERROR, "too many properties"); - return 0; - } - struct NCDUdevMonitorParser_property *prop = &o->ready_properties[o->ready_num_properties]; - - // execute property regex - regmatch_t matches[3]; - if (regexec(&o->property_regex, data, 3, matches, 0) != 0) { - BLog(BLOG_ERROR, "failed to parse property"); - return 0; - } - - // extract components - prop->name = data + matches[1].rm_so; - *(data + matches[1].rm_eo) = '\0'; - prop->value = data + matches[2].rm_so; - *(data + matches[2].rm_eo) = '\0'; - - // register property - o->ready_num_properties++; - - return 1; -} - -static int parse_message (NCDUdevMonitorParser *o) -{ - ASSERT(!o->is_ready) - ASSERT(o->ready_len >= 2) - ASSERT(o->buf[o->ready_len - 2] == '\n') - ASSERT(o->buf[o->ready_len - 1] == '\n') - - // zero terminate message (replacing the second newline) - o->buf[o->ready_len - 1] = '\0'; - - // start parsing - char *line = (char *)o->buf; - int first_line = 1; - - // set is not ready event - o->ready_is_ready_event = 0; - - // init properties - o->ready_num_properties = 0; - - do { - // find end of line - char *line_end = strchr(line, '\n'); - ASSERT(line_end) - - // zero terminate line - *line_end = '\0'; - - if (o->is_info_mode) { - // ignore W: entries with missing space - if (string_begins_with(line, "W:")) { - goto nextline; - } - - // parse prefix - if (strlen(line) < 3 || line[1] != ':' || line[2] != ' ') { - BLog(BLOG_ERROR, "failed to parse head"); - return 0; - } - char line_type = line[0]; - char *line_value = line + 3; - - if (first_line) { - if (line_type != 'P') { - BLog(BLOG_ERROR, "wrong first line type"); - return 0; - } - } else { - if (line_type == 'E') { - if (!parse_property(o, line_value)) { - return 0; - } - } - } - } else { - if (first_line) { - // is this the initial informational message? - if (string_begins_with(line, "monitor")) { - o->ready_is_ready_event = 1; - break; - } - - // check first line - if (!string_begins_with(line, "UDEV ") && !string_begins_with(line, "KERNEL")) { - BLog(BLOG_ERROR, "failed to parse head"); - return 0; - } - } else { - if (!parse_property(o, line)) { - return 0; - } - } - } - nextline: - - first_line = 0; - line = line_end + 1; - } while (*line); - - // set ready - o->is_ready = 1; - - return 1; -} - -static void process_data (NCDUdevMonitorParser *o) -{ - ASSERT(!o->is_ready) - - while (1) { - // look for end of event - uint8_t *c = find_end(o->buf, o->buf_used); - if (!c) { - // check for out of buffer condition - if (o->buf_used == o->buf_size) { - BLog(BLOG_ERROR, "out of buffer"); - o->buf_used = 0; - } - - // receive more data - StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used); - return; - } - - // remember message length - o->ready_len = c - o->buf; - - // parse message - if (parse_message(o)) { - break; - } - - // shift buffer - memmove(o->buf, o->buf + o->ready_len, o->buf_used - o->ready_len); - o->buf_used -= o->ready_len; - } - - // call handler - o->handler(o->user); - return; -} - -static void input_handler_done (NCDUdevMonitorParser *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->is_ready) - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_size - o->buf_used) - - // increment buffer position - o->buf_used += data_len; - - // process data - process_data(o); - return; -} - -static void done_job_handler (NCDUdevMonitorParser *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) - - // shift buffer - memmove(o->buf, o->buf + o->ready_len, o->buf_used - o->ready_len); - o->buf_used -= o->ready_len; - - // set not ready - o->is_ready = 0; - - // process data - process_data(o); - return; -} - -int NCDUdevMonitorParser_Init (NCDUdevMonitorParser *o, StreamRecvInterface *input, int buf_size, int max_properties, - int is_info_mode, BPendingGroup *pg, void *user, - NCDUdevMonitorParser_handler handler) -{ - ASSERT(buf_size > 0) - ASSERT(max_properties >= 0) - ASSERT(is_info_mode == 0 || is_info_mode == 1) - - // init arguments - o->input = input; - o->buf_size = buf_size; - o->max_properties = max_properties; - o->is_info_mode = is_info_mode; - o->user = user; - o->handler = handler; - - // init input - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // init property regex - if (regcomp(&o->property_regex, PROPERTY_REGEX, REG_EXTENDED) != 0) { - BLog(BLOG_ERROR, "regcomp failed"); - goto fail1; - } - - // init done job - BPending_Init(&o->done_job, pg, (BPending_handler)done_job_handler, o); - - // allocate buffer - if (!(o->buf = malloc(o->buf_size))) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail2; - } - - // set buffer position - o->buf_used = 0; - - // set not ready - o->is_ready = 0; - - // allocate properties - if (!(o->ready_properties = BAllocArray(o->max_properties, sizeof(o->ready_properties[0])))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail3; - } - - // start receiving - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size); - - DebugObject_Init(&o->d_obj); - return 1; - -fail3: - free(o->buf); -fail2: - BPending_Free(&o->done_job); - regfree(&o->property_regex); -fail1: - return 0; -} - -void NCDUdevMonitorParser_Free (NCDUdevMonitorParser *o) -{ - DebugObject_Free(&o->d_obj); - - // free properties - BFree(o->ready_properties); - - // free buffer - free(o->buf); - - // free done job - BPending_Free(&o->done_job); - - // free property regex - regfree(&o->property_regex); -} - -void NCDUdevMonitorParser_AssertReady (NCDUdevMonitorParser *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) -} - -void NCDUdevMonitorParser_Done (NCDUdevMonitorParser *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) - - // schedule done job - BPending_Set(&o->done_job); -} - -int NCDUdevMonitorParser_IsReadyEvent (NCDUdevMonitorParser *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) - - return o->ready_is_ready_event; -} - -int NCDUdevMonitorParser_GetNumProperties (NCDUdevMonitorParser *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) - - return o->ready_num_properties; -} - -void NCDUdevMonitorParser_GetProperty (NCDUdevMonitorParser *o, int index, const char **name, const char **value) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->is_ready) - ASSERT(index >= 0) - ASSERT(index < o->ready_num_properties) - - *name = o->ready_properties[index].name; - *value = o->ready_properties[index].value; -} diff --git a/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.h b/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.h deleted file mode 100644 index 910bbe0..0000000 --- a/external/badvpn_dns/udevmonitor/NCDUdevMonitorParser.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file NCDUdevMonitorParser.h - * @author Ambroz Bizjak ambrop7@gmail.com - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UDEVMONITOR_NCDUDEVMONITORPARSER_H -#define BADVPN_UDEVMONITOR_NCDUDEVMONITORPARSER_H - -#include <stdint.h> -#include <regex.h> - -#include <misc/debug.h> -#include <base/DebugObject.h> -#include <flow/StreamRecvInterface.h> - -typedef void (*NCDUdevMonitorParser_handler) (void *user); - -struct NCDUdevMonitorParser_property { - char *name; - char *value; -}; - -typedef struct { - StreamRecvInterface *input; - int buf_size; - int max_properties; - int is_info_mode; - void *user; - NCDUdevMonitorParser_handler handler; - regex_t property_regex; - BPending done_job; - uint8_t *buf; - int buf_used; - int is_ready; - int ready_len; - int ready_is_ready_event; - struct NCDUdevMonitorParser_property *ready_properties; - int ready_num_properties; - DebugObject d_obj; -} NCDUdevMonitorParser; - -int NCDUdevMonitorParser_Init (NCDUdevMonitorParser *o, StreamRecvInterface *input, int buf_size, int max_properties, - int is_info_mode, BPendingGroup *pg, void *user, - NCDUdevMonitorParser_handler handler) WARN_UNUSED; -void NCDUdevMonitorParser_Free (NCDUdevMonitorParser *o); -void NCDUdevMonitorParser_AssertReady (NCDUdevMonitorParser *o); -void NCDUdevMonitorParser_Done (NCDUdevMonitorParser *o); -int NCDUdevMonitorParser_IsReadyEvent (NCDUdevMonitorParser *o); -int NCDUdevMonitorParser_GetNumProperties (NCDUdevMonitorParser *o); -void NCDUdevMonitorParser_GetProperty (NCDUdevMonitorParser *o, int index, const char **name, const char **value); - -#endif diff --git a/external/badvpn_dns/udpgw/CMakeLists.txt b/external/badvpn_dns/udpgw/CMakeLists.txt deleted file mode 100644 index c8c798c..0000000 --- a/external/badvpn_dns/udpgw/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_executable(badvpn-udpgw - udpgw.c -) -target_link_libraries(badvpn-udpgw system flow flowextra) - -install( - TARGETS badvpn-udpgw - RUNTIME DESTINATION bin -) diff --git a/external/badvpn_dns/udpgw/udpgw.c b/external/badvpn_dns/udpgw/udpgw.c deleted file mode 100644 index 9c6a341..0000000 --- a/external/badvpn_dns/udpgw/udpgw.c +++ /dev/null @@ -1,1473 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <limits.h> - -#include <protocol/udpgw_proto.h> -#include <misc/debug.h> -#include <misc/version.h> -#include <misc/loggers_string.h> -#include <misc/loglevel.h> -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <misc/bsize.h> -#include <misc/open_standard_streams.h> -#include <misc/balloc.h> -#include <misc/compare.h> -#include <misc/print_macros.h> -#include <structure/LinkedList1.h> -#include <structure/BAVL.h> -#include <base/BLog.h> -#include <system/BReactor.h> -#include <system/BNetwork.h> -#include <system/BConnection.h> -#include <system/BDatagram.h> -#include <system/BSignal.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketPassFairQueue.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketProtoFlow.h> -#include <flow/SinglePacketBuffer.h> - -#ifndef BADVPN_USE_WINAPI -#include <base/BLog_syslog.h> -#include <arpa/nameser.h> -#include <resolv.h> -#endif - -#include <udpgw/udpgw.h> - -#include <generated/blog_channel_udpgw.h> - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -#define DNS_UPDATE_TIME 2000 - -struct client { - BConnection con; - BAddr addr; - BTimer disconnect_timer; - PacketProtoDecoder recv_decoder; - PacketPassInterface recv_if; - PacketPassFairQueue send_queue; - PacketStreamSender send_sender; - BAVL connections_tree; - LinkedList1 connections_list; - int num_connections; - LinkedList1 closing_connections_list; - LinkedList1Node clients_list_node; -}; - -struct connection { - struct client *client; - uint16_t conid; - BAddr addr; - BAddr orig_addr; - const uint8_t *first_data; - int first_data_len; - btime_t last_use_time; - int closing; - BPending first_job; - BufferWriter *send_if; - PacketProtoFlow send_ppflow; - PacketPassFairQueueFlow send_qflow; - union { - struct { - BDatagram udp_dgram; - int local_port_index; - BufferWriter udp_send_writer; - PacketBuffer udp_send_buffer; - SinglePacketBuffer udp_recv_buffer; - PacketPassInterface udp_recv_if; - BAVLNode connections_tree_node; - LinkedList1Node connections_list_node; - }; - struct { - LinkedList1Node closing_connections_list_node; - }; - }; -}; - -// command-line options -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - char *listen_addrs[MAX_LISTEN_ADDRS]; - int num_listen_addrs; - int udp_mtu; - int max_clients; - int max_connections_for_client; - int client_socket_sndbuf; - int local_udp_num_ports; - char *local_udp_addr; - int local_udp_ip6_num_ports; - char *local_udp_ip6_addr; - int unique_local_ports; -} options; - -// MTUs -int udpgw_mtu; -int pp_mtu; - -// listen addresses -BAddr listen_addrs[MAX_LISTEN_ADDRS]; -int num_listen_addrs; - -// local UDP port range, if options.local_udp_num_ports>=0 -BAddr local_udp_addr; - -// local UDP/IPv6 port range, if options.local_udp_ip6_num_ports>=0 -BAddr local_udp_ip6_addr; - -// DNS forwarding -BAddr dns_addr; -btime_t last_dns_update_time; - -// reactor -BReactor ss; - -// listeners -BListener listeners[MAX_LISTEN_ADDRS]; -int num_listeners; - -// clients -LinkedList1 clients_list; -int num_clients; - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static void listener_handler (BListener *listener); -static void client_free (struct client *client); -static void client_logfunc (struct client *client); -static void client_log (struct client *client, int level, const char *fmt, ...); -static void client_disconnect_timer_handler (struct client *client); -static void client_connection_handler (struct client *client, int event); -static void client_decoder_handler_error (struct client *client); -static void client_recv_if_handler_send (struct client *client, uint8_t *data, int data_len); -static int get_local_num_ports (int addr_type); -static BAddr get_local_addr (int addr_type); -static uint8_t * build_port_usage_array_and_find_least_used_connection (BAddr remote_addr, struct connection **out_con); -static void connection_init (struct client *client, uint16_t conid, BAddr addr, BAddr orig_addr, const uint8_t *data, int data_len); -static void connection_free (struct connection *con); -static void connection_logfunc (struct connection *con); -static void connection_log (struct connection *con, int level, const char *fmt, ...); -static void connection_free_udp (struct connection *con); -static void connection_first_job_handler (struct connection *con); -static void connection_send_to_client (struct connection *con, uint8_t flags, const uint8_t *data, int data_len); -static int connection_send_to_udp (struct connection *con, const uint8_t *data, int data_len); -static void connection_close (struct connection *con); -static void connection_send_qflow_busy_handler (struct connection *con); -static void connection_dgram_handler_event (struct connection *con, int event); -static void connection_udp_recv_if_handler_send (struct connection *con, uint8_t *data, int data_len); -static struct connection * find_connection (struct client *client, uint16_t conid); -static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2); -static void maybe_update_dns (void); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // compute MTUs - udpgw_mtu = udpgw_compute_mtu(options.udp_mtu); - if (udpgw_mtu < 0 || udpgw_mtu > PACKETPROTO_MAXPAYLOAD) { - udpgw_mtu = PACKETPROTO_MAXPAYLOAD; - } - pp_mtu = udpgw_mtu + sizeof(struct packetproto_header); - - // init time - BTime_Init(); - - // init DNS forwarding - BAddr_InitNone(&dns_addr); - last_dns_update_time = INT64_MIN; - maybe_update_dns(); - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // initialize listeners - num_listeners = 0; - while (num_listeners < num_listen_addrs) { - if (!BListener_Init(&listeners[num_listeners], listen_addrs[num_listeners], &ss, &listeners[num_listeners], (BListener_handler)listener_handler)) { - BLog(BLOG_ERROR, "Listener_Init failed"); - goto fail3; - } - num_listeners++; - } - - // init clients list - LinkedList1_Init(&clients_list); - num_clients = 0; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - // free clients - while (!LinkedList1_IsEmpty(&clients_list)) { - struct client *client = UPPER_OBJECT(LinkedList1_GetFirst(&clients_list), struct client, clients_list_node); - client_free(client); - } -fail3: - // free listeners - while (num_listeners > 0) { - num_listeners--; - BListener_Free(&listeners[num_listeners]); - } - // finish signal handling - BSignal_Finish(); -fail2: - // free reactor - BReactor_Free(&ss); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish debug objects - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility <string>]\n" - " [--syslog-ident <string>]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--listen-addr <addr>] ...\n" - " [--udp-mtu <bytes>]\n" - " [--max-clients <number>]\n" - " [--max-connections-for-client <number>]\n" - " [--client-socket-sndbuf <bytes / 0>]\n" - " [--local-udp-addrs <addr> <num_ports>]\n" - " [--local-udp-ip6-addrs <addr> <num_ports>]\n" - " [--unique-local-ports]\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.num_listen_addrs = 0; - options.udp_mtu = DEFAULT_UDP_MTU; - options.max_clients = DEFAULT_MAX_CLIENTS; - options.max_connections_for_client = DEFAULT_MAX_CONNECTIONS_FOR_CLIENT; - options.client_socket_sndbuf = CLIENT_DEFAULT_SOCKET_SEND_BUFFER; - options.local_udp_num_ports = -1; - options.local_udp_ip6_num_ports = -1; - options.unique_local_ports = 0; - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--listen-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_listen_addrs == MAX_LISTEN_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.listen_addrs[options.num_listen_addrs] = argv[i + 1]; - options.num_listen_addrs++; - i++; - } - else if (!strcmp(arg, "--udp-mtu")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.udp_mtu = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-connections-for-client")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_connections_for_client = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--client-socket-sndbuf")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.client_socket_sndbuf = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--local-udp-addrs")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - options.local_udp_addr = argv[i + 1]; - if ((options.local_udp_num_ports = atoi(argv[i + 2])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i += 2; - } - else if (!strcmp(arg, "--local-udp-ip6-addrs")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - options.local_udp_ip6_addr = argv[i + 1]; - if ((options.local_udp_ip6_num_ports = atoi(argv[i + 2])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i += 2; - } - else if (!strcmp(arg, "--unique-local-ports")) { - options.unique_local_ports = 1; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen addresses - num_listen_addrs = 0; - while (num_listen_addrs < options.num_listen_addrs) { - if (!BAddr_Parse(&listen_addrs[num_listen_addrs], options.listen_addrs[num_listen_addrs], NULL, 0)) { - BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed"); - return 0; - } - num_listen_addrs++; - } - - // resolve local UDP address - if (options.local_udp_num_ports >= 0) { - if (!BAddr_Parse(&local_udp_addr, options.local_udp_addr, NULL, 0)) { - BLog(BLOG_ERROR, "local udp addr: BAddr_Parse failed"); - return 0; - } - if (local_udp_addr.type != BADDR_TYPE_IPV4) { - BLog(BLOG_ERROR, "local udp addr: must be an IPv4 address"); - return 0; - } - } - - // resolve local UDP/IPv6 address - if (options.local_udp_ip6_num_ports >= 0) { - if (!BAddr_Parse(&local_udp_ip6_addr, options.local_udp_ip6_addr, NULL, 0)) { - BLog(BLOG_ERROR, "local udp ip6 addr: BAddr_Parse failed"); - return 0; - } - if (local_udp_ip6_addr.type != BADDR_TYPE_IPV6) { - BLog(BLOG_ERROR, "local udp ip6 addr: must be an IPv6 address"); - return 0; - } - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&ss, 1); -} - -void listener_handler (BListener *listener) -{ - if (num_clients == options.max_clients) { - BLog(BLOG_ERROR, "maximum number of clients reached"); - goto fail0; - } - - // allocate structure - struct client *client = (struct client *)malloc(sizeof(*client)); - if (!client) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // accept client - if (!BConnection_Init(&client->con, BConnection_source_listener(listener, &client->addr), &ss, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // limit socket send buffer, else our scheduling is pointless - if (options.client_socket_sndbuf > 0) { - if (!BConnection_SetSendBuffer(&client->con, options.client_socket_sndbuf)) { - BLog(BLOG_WARNING, "BConnection_SetSendBuffer failed"); - } - } - - // init connection interfaces - BConnection_SendAsync_Init(&client->con); - BConnection_RecvAsync_Init(&client->con); - - // init disconnect timer - BTimer_Init(&client->disconnect_timer, CLIENT_DISCONNECT_TIMEOUT, (BTimer_handler)client_disconnect_timer_handler, client); - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // init recv interface - PacketPassInterface_Init(&client->recv_if, udpgw_mtu, (PacketPassInterface_handler_send)client_recv_if_handler_send, client, BReactor_PendingGroup(&ss)); - - // init recv decoder - if (!PacketProtoDecoder_Init(&client->recv_decoder, BConnection_RecvAsync_GetIf(&client->con), &client->recv_if, BReactor_PendingGroup(&ss), client, - (PacketProtoDecoder_handler_error)client_decoder_handler_error - )) { - BLog(BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail2; - } - - // init send sender - PacketStreamSender_Init(&client->send_sender, BConnection_SendAsync_GetIf(&client->con), pp_mtu, BReactor_PendingGroup(&ss)); - - // init send queue - if (!PacketPassFairQueue_Init(&client->send_queue, PacketStreamSender_GetInput(&client->send_sender), BReactor_PendingGroup(&ss), 0, 1)) { - BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed"); - goto fail3; - } - - // init connections tree - BAVL_Init(&client->connections_tree, OFFSET_DIFF(struct connection, conid, connections_tree_node), (BAVL_comparator)uint16_comparator, NULL); - - // init connections list - LinkedList1_Init(&client->connections_list); - - // set zero connections - client->num_connections = 0; - - // init closing connections list - LinkedList1_Init(&client->closing_connections_list); - - // insert to clients list - LinkedList1_Append(&clients_list, &client->clients_list_node); - num_clients++; - - client_log(client, BLOG_INFO, "connected"); - - return; - -fail3: - PacketStreamSender_Free(&client->send_sender); - PacketProtoDecoder_Free(&client->recv_decoder); -fail2: - PacketPassInterface_Free(&client->recv_if); - BReactor_RemoveTimer(&ss, &client->disconnect_timer); - BConnection_RecvAsync_Free(&client->con); - BConnection_SendAsync_Free(&client->con); - BConnection_Free(&client->con); -fail1: - free(client); -fail0: - return; -} - -void client_free (struct client *client) -{ - // allow freeing send queue flows - PacketPassFairQueue_PrepareFree(&client->send_queue); - - // free connections - while (!LinkedList1_IsEmpty(&client->connections_list)) { - struct connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&client->connections_list), struct connection, connections_list_node); - connection_free(con); - } - - // free closing connections - while (!LinkedList1_IsEmpty(&client->closing_connections_list)) { - struct connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&client->closing_connections_list), struct connection, closing_connections_list_node); - connection_free(con); - } - - // remove from clients list - LinkedList1_Remove(&clients_list, &client->clients_list_node); - num_clients--; - - // free send queue - PacketPassFairQueue_Free(&client->send_queue); - - // free send sender - PacketStreamSender_Free(&client->send_sender); - - // free recv decoder - PacketProtoDecoder_Free(&client->recv_decoder); - - // free recv interface - PacketPassInterface_Free(&client->recv_if); - - // free disconnect timer - BReactor_RemoveTimer(&ss, &client->disconnect_timer); - - // free connection interfaces - BConnection_RecvAsync_Free(&client->con); - BConnection_SendAsync_Free(&client->con); - - // free connection - BConnection_Free(&client->con); - - // free structure - free(client); -} - -void client_logfunc (struct client *client) -{ - char addr[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->addr, addr); - - BLog_Append("client (%s): ", addr); -} - -void client_log (struct client *client, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void client_disconnect_timer_handler (struct client *client) -{ - client_log(client, BLOG_INFO, "timed out, disconnecting"); - - // free client - client_free(client); -} - -void client_connection_handler (struct client *client, int event) -{ - if (event == BCONNECTION_EVENT_RECVCLOSED) { - client_log(client, BLOG_INFO, "client closed"); - } else { - client_log(client, BLOG_INFO, "client error"); - } - - // free client - client_free(client); -} - -void client_decoder_handler_error (struct client *client) -{ - client_log(client, BLOG_ERROR, "decoder error"); - - // free client - client_free(client); -} - -void client_recv_if_handler_send (struct client *client, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= udpgw_mtu) - - // accept packet - PacketPassInterface_Done(&client->recv_if); - - // parse header - if (data_len < sizeof(struct udpgw_header)) { - client_log(client, BLOG_ERROR, "missing header"); - return; - } - struct udpgw_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t flags = ltoh8(header.flags); - uint16_t conid = ltoh16(header.conid); - - // reset disconnect timer - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // if this is keepalive, ignore any payload - if ((flags & UDPGW_CLIENT_FLAG_KEEPALIVE)) { - client_log(client, BLOG_DEBUG, "received keepalive"); - return; - } - - // parse address - BAddr orig_addr; - if ((flags & UDPGW_CLIENT_FLAG_IPV6)) { - if (data_len < sizeof(struct udpgw_addr_ipv6)) { - client_log(client, BLOG_ERROR, "missing ipv6 address"); - return; - } - struct udpgw_addr_ipv6 addr_ipv6; - memcpy(&addr_ipv6, data, sizeof(addr_ipv6)); - data += sizeof(addr_ipv6); - data_len -= sizeof(addr_ipv6); - BAddr_InitIPv6(&orig_addr, addr_ipv6.addr_ip, addr_ipv6.addr_port); - } else { - if (data_len < sizeof(struct udpgw_addr_ipv4)) { - client_log(client, BLOG_ERROR, "missing ipv4 address"); - return; - } - struct udpgw_addr_ipv4 addr_ipv4; - memcpy(&addr_ipv4, data, sizeof(addr_ipv4)); - data += sizeof(addr_ipv4); - data_len -= sizeof(addr_ipv4); - BAddr_InitIPv4(&orig_addr, addr_ipv4.addr_ip, addr_ipv4.addr_port); - } - - // check payload length - if (data_len > options.udp_mtu) { - client_log(client, BLOG_ERROR, "too much data"); - return; - } - - // find connection - struct connection *con = find_connection(client, conid); - ASSERT(!con || !con->closing) - - // if connection exists, close it if needed - if (con && ((flags & UDPGW_CLIENT_FLAG_REBIND) || !BAddr_Compare(&con->orig_addr, &orig_addr))) { - connection_log(con, BLOG_DEBUG, "close old"); - connection_close(con); - con = NULL; - } - - // if connection doesn't exists, create it - if (!con) { - // check number of connections - if (client->num_connections == options.max_connections_for_client) { - // close least recently used connection - con = UPPER_OBJECT(LinkedList1_GetFirst(&client->connections_list), struct connection, connections_list_node); - connection_close(con); - } - - // if this is DNS, replace actual address, but keep still remember the orig_addr - BAddr addr = orig_addr; - if ((flags & UDPGW_CLIENT_FLAG_DNS)) { - maybe_update_dns(); - if (dns_addr.type == BADDR_TYPE_NONE) { - client_log(client, BLOG_WARNING, "received DNS packet, but no DNS server available"); - } else { - client_log(client, BLOG_DEBUG, "received DNS"); - addr = dns_addr; - } - } - - // create new connection - connection_init(client, conid, addr, orig_addr, data, data_len); - } else { - // submit packet to existing connection - connection_send_to_udp(con, data, data_len); - } -} - -int get_local_num_ports (int addr_type) -{ - switch (addr_type) { - case BADDR_TYPE_IPV4: return options.local_udp_num_ports; - case BADDR_TYPE_IPV6: return options.local_udp_ip6_num_ports; - default: ASSERT(0); return 0; - } -} - -BAddr get_local_addr (int addr_type) -{ - ASSERT(get_local_num_ports(addr_type) >= 0) - - switch (addr_type) { - case BADDR_TYPE_IPV4: return local_udp_addr; - case BADDR_TYPE_IPV6: return local_udp_ip6_addr; - default: ASSERT(0); return BAddr_MakeNone(); - } -} - -uint8_t * build_port_usage_array_and_find_least_used_connection (BAddr remote_addr, struct connection **out_con) -{ - ASSERT(remote_addr.type == BADDR_TYPE_IPV4 || remote_addr.type == BADDR_TYPE_IPV6) - ASSERT(get_local_num_ports(remote_addr.type) >= 0) - - int local_num_ports = get_local_num_ports(remote_addr.type); - - // allocate port usage array - uint8_t *port_usage = (uint8_t *)BAllocSize(bsize_fromint(local_num_ports)); - if (!port_usage) { - return NULL; - } - - // zero array - memset(port_usage, 0, local_num_ports); - - struct connection *least_con = NULL; - - // flag inappropriate ports (those with the same remote address) - for (LinkedList1Node *ln = LinkedList1_GetFirst(&clients_list); ln; ln = LinkedList1Node_Next(ln)) { - struct client *client = UPPER_OBJECT(ln, struct client, clients_list_node); - - for (LinkedList1Node *ln2 = LinkedList1_GetFirst(&client->connections_list); ln2; ln2 = LinkedList1Node_Next(ln2)) { - struct connection *con = UPPER_OBJECT(ln2, struct connection, connections_list_node); - ASSERT(con->client == client) - ASSERT(!con->closing) - - if (con->addr.type != remote_addr.type || con->local_port_index < 0) { - continue; - } - ASSERT(con->local_port_index < local_num_ports) - - if (options.unique_local_ports) { - BIPAddr ip1; - BIPAddr ip2; - BAddr_GetIPAddr(&con->addr, &ip1); - BAddr_GetIPAddr(&remote_addr, &ip2); - if (!BIPAddr_Compare(&ip1, &ip2)) { - continue; - } - } else { - if (!BAddr_Compare(&con->addr, &remote_addr)) { - continue; - } - } - - port_usage[con->local_port_index] = 1; - - if (!PacketPassFairQueueFlow_IsBusy(&con->send_qflow)) { - if (!least_con || con->last_use_time < least_con->last_use_time) { - least_con = con; - } - } - } - } - - *out_con = least_con; - return port_usage; -} - -void connection_init (struct client *client, uint16_t conid, BAddr addr, BAddr orig_addr, const uint8_t *data, int data_len) -{ - ASSERT(client->num_connections < options.max_connections_for_client) - ASSERT(!find_connection(client, conid)) - BAddr_Assert(&addr); - ASSERT(addr.type == BADDR_TYPE_IPV4 || addr.type == BADDR_TYPE_IPV6) - ASSERT(orig_addr.type == BADDR_TYPE_IPV4 || orig_addr.type == BADDR_TYPE_IPV6) - ASSERT(data_len >= 0) - ASSERT(data_len <= options.udp_mtu) - - // allocate structure - struct connection *con = (struct connection *)malloc(sizeof(*con)); - if (!con) { - client_log(client, BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init arguments - con->client = client; - con->conid = conid; - con->addr = addr; - con->orig_addr = orig_addr; - con->first_data = data; - con->first_data_len = data_len; - - // set last use time - con->last_use_time = btime_gettime(); - - // set not closing - con->closing = 0; - - // init first job - BPending_Init(&con->first_job, BReactor_PendingGroup(&ss), (BPending_handler)connection_first_job_handler, con); - BPending_Set(&con->first_job); - - // init send queue flow - PacketPassFairQueueFlow_Init(&con->send_qflow, &client->send_queue); - - // init send PacketProtoFlow - if (!PacketProtoFlow_Init(&con->send_ppflow, udpgw_mtu, CONNECTION_CLIENT_BUFFER_SIZE, PacketPassFairQueueFlow_GetInput(&con->send_qflow), BReactor_PendingGroup(&ss))) { - client_log(client, BLOG_ERROR, "PacketProtoFlow_Init failed"); - goto fail1; - } - con->send_if = PacketProtoFlow_GetInput(&con->send_ppflow); - - // init UDP dgram - if (!BDatagram_Init(&con->udp_dgram, addr.type, &ss, con, (BDatagram_handler)connection_dgram_handler_event)) { - client_log(client, BLOG_ERROR, "BDatagram_Init failed"); - goto fail2; - } - - con->local_port_index = -1; - - int local_num_ports = get_local_num_ports(addr.type); - - if (local_num_ports >= 0) { - // build port usage array, find least used connection - struct connection *least_con; - uint8_t *port_usage = build_port_usage_array_and_find_least_used_connection(addr, &least_con); - if (!port_usage) { - client_log(client, BLOG_ERROR, "build_port_usage_array failed"); - goto failed; - } - - // set SO_REUSEADDR - if (!BDatagram_SetReuseAddr(&con->udp_dgram, 1)) { - client_log(client, BLOG_ERROR, "set SO_REUSEADDR failed"); - goto failed; - } - - // get starting local address - BAddr local_addr = get_local_addr(addr.type); - - // try different ports - for (int i = 0; i < local_num_ports; i++) { - // skip inappropriate ports - if (port_usage[i]) { - continue; - } - - BAddr bind_addr = local_addr; - BAddr_SetPort(&bind_addr, hton16(ntoh16(BAddr_GetPort(&bind_addr)) + (uint16_t)i)); - if (BDatagram_Bind(&con->udp_dgram, bind_addr)) { - // remember which port we're using - con->local_port_index = i; - goto cont; - } - } - - // try closing an unused connection with the same remote addr - if (!least_con) { - goto failed; - } - - ASSERT(least_con->addr.type == addr.type) - ASSERT(least_con->local_port_index >= 0) - ASSERT(least_con->local_port_index < local_num_ports) - ASSERT(!PacketPassFairQueueFlow_IsBusy(&least_con->send_qflow)) - - int i = least_con->local_port_index; - - BLog(BLOG_INFO, "closing connection for its remote address"); - - // close the offending connection - connection_close(least_con); - - // try binding to its port - BAddr bind_addr = local_addr; - BAddr_SetPort(&bind_addr, hton16(ntoh16(BAddr_GetPort(&bind_addr)) + (uint16_t)i)); - if (BDatagram_Bind(&con->udp_dgram, bind_addr)) { - // remember which port we're using - con->local_port_index = i; - goto cont; - } - - failed: - client_log(client, BLOG_WARNING, "failed to bind to any local address; proceeding regardless"); - cont:; - BFree(port_usage); - } - - // set UDP dgram send address - BIPAddr ipaddr; - BIPAddr_InitInvalid(&ipaddr); - BDatagram_SetSendAddrs(&con->udp_dgram, addr, ipaddr); - - // init UDP dgram interfaces - BDatagram_SendAsync_Init(&con->udp_dgram, options.udp_mtu); - BDatagram_RecvAsync_Init(&con->udp_dgram, options.udp_mtu); - - // init UDP writer - BufferWriter_Init(&con->udp_send_writer, options.udp_mtu, BReactor_PendingGroup(&ss)); - - // init UDP buffer - if (!PacketBuffer_Init(&con->udp_send_buffer, BufferWriter_GetOutput(&con->udp_send_writer), BDatagram_SendAsync_GetIf(&con->udp_dgram), CONNECTION_UDP_BUFFER_SIZE, BReactor_PendingGroup(&ss))) { - client_log(client, BLOG_ERROR, "PacketBuffer_Init failed"); - goto fail4; - } - - // init UDP recv interface - PacketPassInterface_Init(&con->udp_recv_if, options.udp_mtu, (PacketPassInterface_handler_send)connection_udp_recv_if_handler_send, con, BReactor_PendingGroup(&ss)); - - // init UDP recv buffer - if (!SinglePacketBuffer_Init(&con->udp_recv_buffer, BDatagram_RecvAsync_GetIf(&con->udp_dgram), &con->udp_recv_if, BReactor_PendingGroup(&ss))) { - client_log(client, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail5; - } - - // insert to client's connections tree - ASSERT_EXECUTE(BAVL_Insert(&client->connections_tree, &con->connections_tree_node, NULL)) - - // insert to client's connections list - LinkedList1_Append(&client->connections_list, &con->connections_list_node); - - // increment number of connections - client->num_connections++; - - connection_log(con, BLOG_DEBUG, "initialized"); - - return; - -fail5: - PacketPassInterface_Free(&con->udp_recv_if); - PacketBuffer_Free(&con->udp_send_buffer); -fail4: - BufferWriter_Free(&con->udp_send_writer); - BDatagram_RecvAsync_Free(&con->udp_dgram); - BDatagram_SendAsync_Free(&con->udp_dgram); - BDatagram_Free(&con->udp_dgram); -fail2: - PacketProtoFlow_Free(&con->send_ppflow); -fail1: - PacketPassFairQueueFlow_Free(&con->send_qflow); - BPending_Free(&con->first_job); - free(con); -fail0: - return; -} - -void connection_free (struct connection *con) -{ - struct client *client = con->client; - PacketPassFairQueueFlow_AssertFree(&con->send_qflow); - - if (con->closing) { - // remove from client's closing connections list - LinkedList1_Remove(&client->closing_connections_list, &con->closing_connections_list_node); - } else { - // decrement number of connections - client->num_connections--; - - // remove from client's connections list - LinkedList1_Remove(&client->connections_list, &con->connections_list_node); - - // remove from client's connections tree - BAVL_Remove(&client->connections_tree, &con->connections_tree_node); - - // free UDP - connection_free_udp(con); - } - - // free send PacketProtoFlow - PacketProtoFlow_Free(&con->send_ppflow); - - // free send queue flow - PacketPassFairQueueFlow_Free(&con->send_qflow); - - // free first job - BPending_Free(&con->first_job); - - // free structure - free(con); -} - -void connection_logfunc (struct connection *con) -{ - client_logfunc(con->client); - - if (con->closing) { - BLog_Append("old connection %"PRIu16": ", con->conid); - } else { - BLog_Append("connection %"PRIu16": ", con->conid); - } -} - -void connection_log (struct connection *con, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)connection_logfunc, con, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void connection_free_udp (struct connection *con) -{ - // free UDP receive buffer - SinglePacketBuffer_Free(&con->udp_recv_buffer); - - // free UDP receive interface - PacketPassInterface_Free(&con->udp_recv_if); - - // free UDP buffer - PacketBuffer_Free(&con->udp_send_buffer); - - // free UDP writer - BufferWriter_Free(&con->udp_send_writer); - - // free UDP dgram interfaces - BDatagram_RecvAsync_Free(&con->udp_dgram); - BDatagram_SendAsync_Free(&con->udp_dgram); - - // free UDP dgram - BDatagram_Free(&con->udp_dgram); -} - -void connection_first_job_handler (struct connection *con) -{ - ASSERT(!con->closing) - - connection_send_to_udp(con, con->first_data, con->first_data_len); -} - -void connection_send_to_client (struct connection *con, uint8_t flags, const uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= options.udp_mtu) - - size_t addr_len = (con->orig_addr.type == BADDR_TYPE_IPV6) ? sizeof(struct udpgw_addr_ipv6) : - (con->orig_addr.type == BADDR_TYPE_IPV4) ? sizeof(struct udpgw_addr_ipv4) : 0; - if (data_len > udpgw_mtu - (int)(sizeof(struct udpgw_header) + addr_len)) { - connection_log(con, BLOG_WARNING, "packet is too large, cannot send to client"); - return; - } - - // get buffer location - uint8_t *out; - if (!BufferWriter_StartPacket(con->send_if, &out)) { - connection_log(con, BLOG_ERROR, "out of client buffer"); - return; - } - int out_pos = 0; - - if (con->orig_addr.type == BADDR_TYPE_IPV6) { - flags |= UDPGW_CLIENT_FLAG_IPV6; - } - - // write header - struct udpgw_header header; - header.flags = htol8(flags); - header.conid = htol16(con->conid); - memcpy(out + out_pos, &header, sizeof(header)); - out_pos += sizeof(header); - - // write address - switch (con->orig_addr.type) { - case BADDR_TYPE_IPV4: { - struct udpgw_addr_ipv4 addr_ipv4; - addr_ipv4.addr_ip = con->orig_addr.ipv4.ip; - addr_ipv4.addr_port = con->orig_addr.ipv4.port; - memcpy(out + out_pos, &addr_ipv4, sizeof(addr_ipv4)); - out_pos += sizeof(addr_ipv4); - } break; - case BADDR_TYPE_IPV6: { - struct udpgw_addr_ipv6 addr_ipv6; - memcpy(addr_ipv6.addr_ip, con->orig_addr.ipv6.ip, sizeof(addr_ipv6.addr_ip)); - addr_ipv6.addr_port = con->orig_addr.ipv6.port; - memcpy(out + out_pos, &addr_ipv6, sizeof(addr_ipv6)); - out_pos += sizeof(addr_ipv6); - } break; - } - - // write message - memcpy(out + out_pos, data, data_len); - out_pos += data_len; - - // submit written message - ASSERT(out_pos <= udpgw_mtu) - BufferWriter_EndPacket(con->send_if, out_pos); -} - -int connection_send_to_udp (struct connection *con, const uint8_t *data, int data_len) -{ - struct client *client = con->client; - ASSERT(!con->closing) - ASSERT(data_len >= 0) - ASSERT(data_len <= options.udp_mtu) - - connection_log(con, BLOG_DEBUG, "from client %d bytes", data_len); - - // set last use time - con->last_use_time = btime_gettime(); - - // move connection to front - LinkedList1_Remove(&client->connections_list, &con->connections_list_node); - LinkedList1_Append(&client->connections_list, &con->connections_list_node); - - // get buffer location - uint8_t *out; - if (!BufferWriter_StartPacket(&con->udp_send_writer, &out)) { - connection_log(con, BLOG_ERROR, "out of UDP buffer"); - return 0; - } - - // write message - memcpy(out, data, data_len); - - // submit written message - BufferWriter_EndPacket(&con->udp_send_writer, data_len); - - return 1; -} - -void connection_close (struct connection *con) -{ - struct client *client = con->client; - ASSERT(!con->closing) - - // if possible, free connection immediately - if (!PacketPassFairQueueFlow_IsBusy(&con->send_qflow)) { - connection_free(con); - return; - } - - connection_log(con, BLOG_DEBUG, "closing later"); - - // decrement number of connections - client->num_connections--; - - // remove from client's connections list - LinkedList1_Remove(&client->connections_list, &con->connections_list_node); - - // remove from client's connections tree - BAVL_Remove(&client->connections_tree, &con->connections_tree_node); - - // free UDP - connection_free_udp(con); - - // insert to client's closing connections list - LinkedList1_Append(&client->closing_connections_list, &con->closing_connections_list_node); - - // set busy handler - PacketPassFairQueueFlow_SetBusyHandler(&con->send_qflow, (PacketPassFairQueue_handler_busy)connection_send_qflow_busy_handler, con); - - // unset first job - BPending_Unset(&con->first_job); - - // set closing - con->closing = 1; -} - -void connection_send_qflow_busy_handler (struct connection *con) -{ - ASSERT(con->closing) - PacketPassFairQueueFlow_AssertFree(&con->send_qflow); - - connection_log(con, BLOG_DEBUG, "closing finally"); - - // free connection - connection_free(con); -} - -void connection_dgram_handler_event (struct connection *con, int event) -{ - ASSERT(!con->closing) - - connection_log(con, BLOG_INFO, "UDP error"); - - // close connection - connection_close(con); -} - -void connection_udp_recv_if_handler_send (struct connection *con, uint8_t *data, int data_len) -{ - struct client *client = con->client; - ASSERT(!con->closing) - ASSERT(data_len >= 0) - ASSERT(data_len <= options.udp_mtu) - - connection_log(con, BLOG_DEBUG, "from UDP %d bytes", data_len); - - // set last use time - con->last_use_time = btime_gettime(); - - // move connection to front - LinkedList1_Remove(&client->connections_list, &con->connections_list_node); - LinkedList1_Append(&client->connections_list, &con->connections_list_node); - - // accept packet - PacketPassInterface_Done(&con->udp_recv_if); - - // send packet to client - connection_send_to_client(con, 0, data, data_len); -} - -struct connection * find_connection (struct client *client, uint16_t conid) -{ - BAVLNode *tree_node = BAVL_LookupExact(&client->connections_tree, &conid); - if (!tree_node) { - return NULL; - } - struct connection *con = UPPER_OBJECT(tree_node, struct connection, connections_tree_node); - ASSERT(con->conid == conid) - ASSERT(!con->closing) - - return con; -} - -int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2) -{ - return B_COMPARE(*v1, *v2); -} - -void maybe_update_dns (void) -{ -#ifndef BADVPN_USE_WINAPI - btime_t now = btime_gettime(); - if (now < btime_add(last_dns_update_time, DNS_UPDATE_TIME)) { - return; - } - last_dns_update_time = now; - BLog(BLOG_DEBUG, "update dns"); - - if (res_init() != 0) { - BLog(BLOG_ERROR, "res_init failed"); - goto fail; - } - - if (_res.nscount == 0) { - BLog(BLOG_ERROR, "no name servers available"); - goto fail; - } - - BAddr addr; - BAddr_InitIPv4(&addr, _res.nsaddr_list[0].sin_addr.s_addr, hton16(53)); - - if (!BAddr_Compare(&addr, &dns_addr)) { - char str[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&addr, str); - BLog(BLOG_INFO, "using DNS server %s", str); - } - - dns_addr = addr; - return; - -fail: - BAddr_InitNone(&dns_addr); -#endif -} diff --git a/external/badvpn_dns/udpgw/udpgw.h b/external/badvpn_dns/udpgw/udpgw.h deleted file mode 100644 index f63f857..0000000 --- a/external/badvpn_dns/udpgw/udpgw.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// name of the program -#define PROGRAM_NAME "udpgw" - -// maxiumum listen addresses -#define MAX_LISTEN_ADDRS 16 - -// maximum datagram size -#define DEFAULT_UDP_MTU 65520 - -// connection buffer size for sending to client, in packets -#define CONNECTION_CLIENT_BUFFER_SIZE 1 - -// connection buffer size for sending to UDP, in packets -#define CONNECTION_UDP_BUFFER_SIZE 1 - -// maximum number of clients -#define DEFAULT_MAX_CLIENTS 3 - -// maximum connections for client -#define DEFAULT_MAX_CONNECTIONS_FOR_CLIENT 256 - -// how long after nothing has been received to disconnect a client -#define CLIENT_DISCONNECT_TIMEOUT 20000 - -// SO_SNDBFUF socket option for clients, 0 to not set -#define CLIENT_DEFAULT_SOCKET_SEND_BUFFER 1048576 diff --git a/external/badvpn_dns/udpgw_client/CMakeLists.txt b/external/badvpn_dns/udpgw_client/CMakeLists.txt deleted file mode 100644 index 59ac636..0000000 --- a/external/badvpn_dns/udpgw_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(udpgw_client "system;flow;flowextra" "" UdpGwClient.c) diff --git a/external/badvpn_dns/udpgw_client/UdpGwClient.c b/external/badvpn_dns/udpgw_client/UdpGwClient.c deleted file mode 100644 index 85d069a..0000000 --- a/external/badvpn_dns/udpgw_client/UdpGwClient.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> - -#include <misc/offset.h> -#include <misc/byteorder.h> -#include <misc/compare.h> -#include <base/BLog.h> - -#include <udpgw_client/UdpGwClient.h> - -#include <generated/blog_channel_UdpGwClient.h> - -static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2); -static int conaddr_comparator (void *unused, struct UdpGwClient_conaddr *v1, struct UdpGwClient_conaddr *v2); -static void free_server (UdpGwClient *o); -static void decoder_handler_error (UdpGwClient *o); -static void recv_interface_handler_send (UdpGwClient *o, uint8_t *data, int data_len); -static void send_monitor_handler (UdpGwClient *o); -static void keepalive_if_handler_done (UdpGwClient *o); -static struct UdpGwClient_connection * find_connection_by_conaddr (UdpGwClient *o, struct UdpGwClient_conaddr conaddr); -static struct UdpGwClient_connection * find_connection_by_conid (UdpGwClient *o, uint16_t conid); -static uint16_t find_unused_conid (UdpGwClient *o); -static void connection_init (UdpGwClient *o, struct UdpGwClient_conaddr conaddr, uint8_t flags, const uint8_t *data, int data_len); -static void connection_free (struct UdpGwClient_connection *con); -static void connection_first_job_handler (struct UdpGwClient_connection *con); -static void connection_send (struct UdpGwClient_connection *con, uint8_t flags, const uint8_t *data, int data_len); -static struct UdpGwClient_connection * reuse_connection (UdpGwClient *o, struct UdpGwClient_conaddr conaddr); - -static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2) -{ - return B_COMPARE(*v1, *v2); -} - -static int conaddr_comparator (void *unused, struct UdpGwClient_conaddr *v1, struct UdpGwClient_conaddr *v2) -{ - int r = BAddr_CompareOrder(&v1->remote_addr, &v2->remote_addr); - if (r) { - return r; - } - return BAddr_CompareOrder(&v1->local_addr, &v2->local_addr); -} - -static void free_server (UdpGwClient *o) -{ - // disconnect send connector - PacketPassConnector_DisconnectOutput(&o->send_connector); - - // free send sender - PacketStreamSender_Free(&o->send_sender); - - // free receive decoder - PacketProtoDecoder_Free(&o->recv_decoder); - - // free receive interface - PacketPassInterface_Free(&o->recv_if); -} - -static void decoder_handler_error (UdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_server) - - BLog(BLOG_ERROR, "decoder error"); - - // report error - o->handler_servererror(o->user); - return; -} - -static void recv_interface_handler_send (UdpGwClient *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_server) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->udpgw_mtu) - - // accept packet - PacketPassInterface_Done(&o->recv_if); - - // check header - if (data_len < sizeof(struct udpgw_header)) { - BLog(BLOG_ERROR, "missing header"); - return; - } - struct udpgw_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t flags = ltoh8(header.flags); - uint16_t conid = ltoh16(header.conid); - - // parse address - BAddr remote_addr; - if ((flags & UDPGW_CLIENT_FLAG_IPV6)) { - if (data_len < sizeof(struct udpgw_addr_ipv6)) { - BLog(BLOG_ERROR, "missing ipv6 address"); - return; - } - struct udpgw_addr_ipv6 addr_ipv6; - memcpy(&addr_ipv6, data, sizeof(addr_ipv6)); - data += sizeof(addr_ipv6); - data_len -= sizeof(addr_ipv6); - BAddr_InitIPv6(&remote_addr, addr_ipv6.addr_ip, addr_ipv6.addr_port); - } else { - if (data_len < sizeof(struct udpgw_addr_ipv4)) { - BLog(BLOG_ERROR, "missing ipv4 address"); - return; - } - struct udpgw_addr_ipv4 addr_ipv4; - memcpy(&addr_ipv4, data, sizeof(addr_ipv4)); - data += sizeof(addr_ipv4); - data_len -= sizeof(addr_ipv4); - BAddr_InitIPv4(&remote_addr, addr_ipv4.addr_ip, addr_ipv4.addr_port); - } - - // check remaining data - if (data_len > o->udp_mtu) { - BLog(BLOG_ERROR, "too much data"); - return; - } - - // find connection - struct UdpGwClient_connection *con = find_connection_by_conid(o, conid); - if (!con) { - BLog(BLOG_ERROR, "unknown conid"); - return; - } - - // check remote address - if (BAddr_CompareOrder(&con->conaddr.remote_addr, &remote_addr) != 0) { - BLog(BLOG_ERROR, "wrong remote address"); - return; - } - - // move connection to front of the list - LinkedList1_Remove(&o->connections_list, &con->connections_list_node); - LinkedList1_Append(&o->connections_list, &con->connections_list_node); - - // pass packet to user - o->handler_received(o->user, con->conaddr.local_addr, con->conaddr.remote_addr, data, data_len); - return; -} - -static void send_monitor_handler (UdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - - if (o->keepalive_sending) { - return; - } - - BLog(BLOG_INFO, "keepalive"); - - // send keepalive - PacketPassInterface_Sender_Send(o->keepalive_if, (uint8_t *)&o->keepalive_packet, sizeof(o->keepalive_packet)); - - // set sending keep-alive - o->keepalive_sending = 1; -} - -static void keepalive_if_handler_done (UdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->keepalive_sending) - - // set not sending keepalive - o->keepalive_sending = 0; -} - -static struct UdpGwClient_connection * find_connection_by_conaddr (UdpGwClient *o, struct UdpGwClient_conaddr conaddr) -{ - BAVLNode *tree_node = BAVL_LookupExact(&o->connections_tree_by_conaddr, &conaddr); - if (!tree_node) { - return NULL; - } - - return UPPER_OBJECT(tree_node, struct UdpGwClient_connection, connections_tree_by_conaddr_node); -} - -static struct UdpGwClient_connection * find_connection_by_conid (UdpGwClient *o, uint16_t conid) -{ - BAVLNode *tree_node = BAVL_LookupExact(&o->connections_tree_by_conid, &conid); - if (!tree_node) { - return NULL; - } - - return UPPER_OBJECT(tree_node, struct UdpGwClient_connection, connections_tree_by_conid_node); -} - -static uint16_t find_unused_conid (UdpGwClient *o) -{ - ASSERT(o->num_connections < o->max_connections) - - while (1) { - if (!find_connection_by_conid(o, o->next_conid)) { - return o->next_conid; - } - - if (o->next_conid == o->max_connections - 1) { - o->next_conid = 0; - } else { - o->next_conid++; - } - } -} - -static void connection_init (UdpGwClient *o, struct UdpGwClient_conaddr conaddr, uint8_t flags, const uint8_t *data, int data_len) -{ - ASSERT(o->num_connections < o->max_connections) - ASSERT(!find_connection_by_conaddr(o, conaddr)) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->udp_mtu) - - // allocate structure - struct UdpGwClient_connection *con = (struct UdpGwClient_connection *)malloc(sizeof(*con)); - if (!con) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init arguments - con->client = o; - con->conaddr = conaddr; - con->first_flags = flags; - con->first_data = data; - con->first_data_len = data_len; - - // allocate conid - con->conid = find_unused_conid(o); - - // init first job - BPending_Init(&con->first_job, BReactor_PendingGroup(o->reactor), (BPending_handler)connection_first_job_handler, con); - BPending_Set(&con->first_job); - - // init queue flow - PacketPassFairQueueFlow_Init(&con->send_qflow, &o->send_queue); - - // init PacketProtoFlow - if (!PacketProtoFlow_Init(&con->send_ppflow, o->udpgw_mtu, o->send_buffer_size, PacketPassFairQueueFlow_GetInput(&con->send_qflow), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "PacketProtoFlow_Init failed"); - goto fail1; - } - con->send_if = PacketProtoFlow_GetInput(&con->send_ppflow); - - // insert to connections tree by conaddr - ASSERT_EXECUTE(BAVL_Insert(&o->connections_tree_by_conaddr, &con->connections_tree_by_conaddr_node, NULL)) - - // insert to connections tree by conid - ASSERT_EXECUTE(BAVL_Insert(&o->connections_tree_by_conid, &con->connections_tree_by_conid_node, NULL)) - - // insert to connections list - LinkedList1_Append(&o->connections_list, &con->connections_list_node); - - // increment number of connections - o->num_connections++; - - return; - -fail1: - PacketPassFairQueueFlow_Free(&con->send_qflow); - BPending_Free(&con->first_job); - free(con); -fail0: - return; -} - -static void connection_free (struct UdpGwClient_connection *con) -{ - UdpGwClient *o = con->client; - PacketPassFairQueueFlow_AssertFree(&con->send_qflow); - - // decrement number of connections - o->num_connections--; - - // remove from connections list - LinkedList1_Remove(&o->connections_list, &con->connections_list_node); - - // remove from connections tree by conid - BAVL_Remove(&o->connections_tree_by_conid, &con->connections_tree_by_conid_node); - - // remove from connections tree by conaddr - BAVL_Remove(&o->connections_tree_by_conaddr, &con->connections_tree_by_conaddr_node); - - // free PacketProtoFlow - PacketProtoFlow_Free(&con->send_ppflow); - - // free queue flow - PacketPassFairQueueFlow_Free(&con->send_qflow); - - // free first job - BPending_Free(&con->first_job); - - // free structure - free(con); -} - -static void connection_first_job_handler (struct UdpGwClient_connection *con) -{ - connection_send(con, UDPGW_CLIENT_FLAG_REBIND|con->first_flags, con->first_data, con->first_data_len); -} - -static void connection_send (struct UdpGwClient_connection *con, uint8_t flags, const uint8_t *data, int data_len) -{ - UdpGwClient *o = con->client; - B_USE(o) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->udp_mtu) - - // get buffer location - uint8_t *out; - if (!BufferWriter_StartPacket(con->send_if, &out)) { - BLog(BLOG_ERROR, "out of buffer"); - return; - } - int out_pos = 0; - - if (con->conaddr.remote_addr.type == BADDR_TYPE_IPV6) { - flags |= UDPGW_CLIENT_FLAG_IPV6; - } - - // write header - struct udpgw_header header; - header.flags = ltoh8(flags); - header.conid = ltoh16(con->conid); - memcpy(out + out_pos, &header, sizeof(header)); - out_pos += sizeof(header); - - // write address - switch (con->conaddr.remote_addr.type) { - case BADDR_TYPE_IPV4: { - struct udpgw_addr_ipv4 addr_ipv4; - addr_ipv4.addr_ip = con->conaddr.remote_addr.ipv4.ip; - addr_ipv4.addr_port = con->conaddr.remote_addr.ipv4.port; - memcpy(out + out_pos, &addr_ipv4, sizeof(addr_ipv4)); - out_pos += sizeof(addr_ipv4); - } break; - case BADDR_TYPE_IPV6: { - struct udpgw_addr_ipv6 addr_ipv6; - memcpy(addr_ipv6.addr_ip, con->conaddr.remote_addr.ipv6.ip, sizeof(addr_ipv6.addr_ip)); - addr_ipv6.addr_port = con->conaddr.remote_addr.ipv6.port; - memcpy(out + out_pos, &addr_ipv6, sizeof(addr_ipv6)); - out_pos += sizeof(addr_ipv6); - } break; - } - - // write packet to buffer - memcpy(out + out_pos, data, data_len); - out_pos += data_len; - - // submit packet to buffer - BufferWriter_EndPacket(con->send_if, out_pos); -} - -static struct UdpGwClient_connection * reuse_connection (UdpGwClient *o, struct UdpGwClient_conaddr conaddr) -{ - ASSERT(!find_connection_by_conaddr(o, conaddr)) - ASSERT(o->num_connections > 0) - - // get least recently used connection - struct UdpGwClient_connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&o->connections_list), struct UdpGwClient_connection, connections_list_node); - - // remove from connections tree by conaddr - BAVL_Remove(&o->connections_tree_by_conaddr, &con->connections_tree_by_conaddr_node); - - // set new conaddr - con->conaddr = conaddr; - - // insert to connections tree by conaddr - ASSERT_EXECUTE(BAVL_Insert(&o->connections_tree_by_conaddr, &con->connections_tree_by_conaddr_node, NULL)) - - return con; -} - -int UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user, - UdpGwClient_handler_servererror handler_servererror, - UdpGwClient_handler_received handler_received) -{ - ASSERT(udp_mtu >= 0) - ASSERT(udpgw_compute_mtu(udp_mtu) >= 0) - ASSERT(udpgw_compute_mtu(udp_mtu) <= PACKETPROTO_MAXPAYLOAD) - ASSERT(max_connections > 0) - ASSERT(send_buffer_size > 0) - - // init arguments - o->udp_mtu = udp_mtu; - o->max_connections = max_connections; - o->send_buffer_size = send_buffer_size; - o->keepalive_time = keepalive_time; - o->reactor = reactor; - o->user = user; - o->handler_servererror = handler_servererror; - o->handler_received = handler_received; - - // limit max connections to number of conid's - if (o->max_connections > UINT16_MAX + 1) { - o->max_connections = UINT16_MAX + 1; - } - - // compute MTUs - o->udpgw_mtu = udpgw_compute_mtu(o->udp_mtu); - o->pp_mtu = o->udpgw_mtu + sizeof(struct packetproto_header); - - // init connections tree by conaddr - BAVL_Init(&o->connections_tree_by_conaddr, OFFSET_DIFF(struct UdpGwClient_connection, conaddr, connections_tree_by_conaddr_node), (BAVL_comparator)conaddr_comparator, NULL); - - // init connections tree by conid - BAVL_Init(&o->connections_tree_by_conid, OFFSET_DIFF(struct UdpGwClient_connection, conid, connections_tree_by_conid_node), (BAVL_comparator)uint16_comparator, NULL); - - // init connections list - LinkedList1_Init(&o->connections_list); - - // set zero connections - o->num_connections = 0; - - // set next conid - o->next_conid = 0; - - // init send connector - PacketPassConnector_Init(&o->send_connector, o->pp_mtu, BReactor_PendingGroup(o->reactor)); - - // init send monitor - PacketPassInactivityMonitor_Init(&o->send_monitor, PacketPassConnector_GetInput(&o->send_connector), o->reactor, o->keepalive_time, (PacketPassInactivityMonitor_handler)send_monitor_handler, o); - - // init send queue - if (!PacketPassFairQueue_Init(&o->send_queue, PacketPassInactivityMonitor_GetInput(&o->send_monitor), BReactor_PendingGroup(o->reactor), 0, 1)) { - goto fail0; - } - - // construct keepalive packet - o->keepalive_packet.pp.len = sizeof(o->keepalive_packet.udpgw); - memset(&o->keepalive_packet.udpgw, 0, sizeof(o->keepalive_packet.udpgw)); - o->keepalive_packet.udpgw.flags = UDPGW_CLIENT_FLAG_KEEPALIVE; - - // init keepalive queue flow - PacketPassFairQueueFlow_Init(&o->keepalive_qflow, &o->send_queue); - o->keepalive_if = PacketPassFairQueueFlow_GetInput(&o->keepalive_qflow); - - // init keepalive output - PacketPassInterface_Sender_Init(o->keepalive_if, (PacketPassInterface_handler_done)keepalive_if_handler_done, o); - - // set not sending keepalive - o->keepalive_sending = 0; - - // set have no server - o->have_server = 0; - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - PacketPassInactivityMonitor_Free(&o->send_monitor); - PacketPassConnector_Free(&o->send_connector); - return 0; -} - -void UdpGwClient_Free (UdpGwClient *o) -{ - DebugObject_Free(&o->d_obj); - - // allow freeing send queue flows - PacketPassFairQueue_PrepareFree(&o->send_queue); - - // free connections - while (!LinkedList1_IsEmpty(&o->connections_list)) { - struct UdpGwClient_connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&o->connections_list), struct UdpGwClient_connection, connections_list_node); - connection_free(con); - } - - // free server - if (o->have_server) { - free_server(o); - } - - // free keepalive queue flow - PacketPassFairQueueFlow_Free(&o->keepalive_qflow); - - // free send queue - PacketPassFairQueue_Free(&o->send_queue); - - // free send - PacketPassInactivityMonitor_Free(&o->send_monitor); - - // free send connector - PacketPassConnector_Free(&o->send_connector); -} - -void UdpGwClient_SubmitPacket (UdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(local_addr.type == BADDR_TYPE_IPV4 || local_addr.type == BADDR_TYPE_IPV6) - ASSERT(remote_addr.type == BADDR_TYPE_IPV4 || remote_addr.type == BADDR_TYPE_IPV6) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->udp_mtu) - - // build conaddr - struct UdpGwClient_conaddr conaddr; - conaddr.local_addr = local_addr; - conaddr.remote_addr = remote_addr; - - // lookup connection - struct UdpGwClient_connection *con = find_connection_by_conaddr(o, conaddr); - - uint8_t flags = 0; - - if (is_dns) { - // route to remote DNS server instead of provided address - flags |= UDPGW_CLIENT_FLAG_DNS; - } - - // if no connection and can't create a new one, reuse the least recently used une - if (!con && o->num_connections == o->max_connections) { - con = reuse_connection(o, conaddr); - flags |= UDPGW_CLIENT_FLAG_REBIND; - } - - if (!con) { - // create new connection - connection_init(o, conaddr, flags, data, data_len); - } else { - // move connection to front of the list - LinkedList1_Remove(&o->connections_list, &con->connections_list_node); - LinkedList1_Append(&o->connections_list, &con->connections_list_node); - - // send packet to existing connection - connection_send(con, flags, data, data_len); - } -} - -int UdpGwClient_ConnectServer (UdpGwClient *o, StreamPassInterface *send_if, StreamRecvInterface *recv_if) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->have_server) - - // init receive interface - PacketPassInterface_Init(&o->recv_if, o->udpgw_mtu, (PacketPassInterface_handler_send)recv_interface_handler_send, o, BReactor_PendingGroup(o->reactor)); - - // init receive decoder - if (!PacketProtoDecoder_Init(&o->recv_decoder, recv_if, &o->recv_if, BReactor_PendingGroup(o->reactor), o, (PacketProtoDecoder_handler_error)decoder_handler_error)) { - BLog(BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail1; - } - - // init send sender - PacketStreamSender_Init(&o->send_sender, send_if, o->pp_mtu, BReactor_PendingGroup(o->reactor)); - - // connect send connector - PacketPassConnector_ConnectOutput(&o->send_connector, PacketStreamSender_GetInput(&o->send_sender)); - - // set have server - o->have_server = 1; - - return 1; - -fail1: - PacketPassInterface_Free(&o->recv_if); - return 0; -} - -void UdpGwClient_DisconnectServer (UdpGwClient *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->have_server) - - // free server - free_server(o); - - // set have no server - o->have_server = 0; -} diff --git a/external/badvpn_dns/udpgw_client/UdpGwClient.h b/external/badvpn_dns/udpgw_client/UdpGwClient.h deleted file mode 100644 index 0a1086b..0000000 --- a/external/badvpn_dns/udpgw_client/UdpGwClient.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) Ambroz Bizjak ambrop7@gmail.com - * Contributions: - * Transparent DNS: Copyright (C) Kerem Hadimli kerem.hadimli@gmail.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_UDPGW_CLIENT_UDPGWCLIENT_H -#define BADVPN_UDPGW_CLIENT_UDPGWCLIENT_H - -#include <stdint.h> - -#include <protocol/udpgw_proto.h> -#include <misc/debug.h> -#include <misc/packed.h> -#include <structure/BAVL.h> -#include <structure/LinkedList1.h> -#include <base/DebugObject.h> -#include <system/BAddr.h> -#include <base/BPending.h> -#include <flow/PacketPassFairQueue.h> -#include <flow/PacketStreamSender.h> -#include <flow/PacketProtoFlow.h> -#include <flow/PacketProtoDecoder.h> -#include <flow/PacketPassConnector.h> -#include <flowextra/PacketPassInactivityMonitor.h> - -typedef void (*UdpGwClient_handler_servererror) (void *user); -typedef void (*UdpGwClient_handler_received) (void *user, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len); - -B_START_PACKED -struct UdpGwClient__keepalive_packet { - struct packetproto_header pp; - struct udpgw_header udpgw; -} B_PACKED; -B_END_PACKED - -typedef struct { - int udp_mtu; - int max_connections; - int send_buffer_size; - btime_t keepalive_time; - BReactor *reactor; - void *user; - UdpGwClient_handler_servererror handler_servererror; - UdpGwClient_handler_received handler_received; - int udpgw_mtu; - int pp_mtu; - BAVL connections_tree_by_conaddr; - BAVL connections_tree_by_conid; - LinkedList1 connections_list; - int num_connections; - int next_conid; - PacketPassFairQueue send_queue; - PacketPassInactivityMonitor send_monitor; - PacketPassConnector send_connector; - struct UdpGwClient__keepalive_packet keepalive_packet; - PacketPassInterface *keepalive_if; - PacketPassFairQueueFlow keepalive_qflow; - int keepalive_sending; - int have_server; - PacketStreamSender send_sender; - PacketProtoDecoder recv_decoder; - PacketPassInterface recv_if; - DebugObject d_obj; -} UdpGwClient; - -struct UdpGwClient_conaddr { - BAddr local_addr; - BAddr remote_addr; -}; - -struct UdpGwClient_connection { - UdpGwClient *client; - struct UdpGwClient_conaddr conaddr; - uint8_t first_flags; - const uint8_t *first_data; - int first_data_len; - uint16_t conid; - BPending first_job; - BufferWriter *send_if; - PacketProtoFlow send_ppflow; - PacketPassFairQueueFlow send_qflow; - BAVLNode connections_tree_by_conaddr_node; - BAVLNode connections_tree_by_conid_node; - LinkedList1Node connections_list_node; -}; - -int UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user, - UdpGwClient_handler_servererror handler_servererror, - UdpGwClient_handler_received handler_received) WARN_UNUSED; -void UdpGwClient_Free (UdpGwClient *o); -void UdpGwClient_SubmitPacket (UdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len); -int UdpGwClient_ConnectServer (UdpGwClient *o, StreamPassInterface *send_if, StreamRecvInterface *recv_if) WARN_UNUSED; -void UdpGwClient_DisconnectServer (UdpGwClient *o); - -#endif
tor-commits@lists.torproject.org