2021-08-31 23:15:48 +00:00
|
|
|
#pragma once
|
|
|
|
#include <uv.h>
|
|
|
|
#include <NetworkExtension/NetworkExtension.h>
|
|
|
|
|
|
|
|
extern NSString* error_domain;
|
|
|
|
|
|
|
|
/**
|
2022-06-22 21:56:35 +00:00
|
|
|
* "Trampoline" class that listens for UDP DNS packets when we have exit mode enabled. These arrive
|
|
|
|
* on localhost:1053 coming from lokinet's embedded libunbound (when exit mode is enabled), wraps
|
|
|
|
* them via NetworkExtension's crappy UDP API, then sends responses back to libunbound to be
|
|
|
|
* parsed/etc. This class knows nothing about DNS, it is basically just a UDP packet forwarder, but
|
|
|
|
* using Apple magic reinvented wheel wrappers that are oh so wonderful like everything Apple.
|
2021-08-31 23:15:48 +00:00
|
|
|
*
|
|
|
|
* So for a lokinet configuration of "upstream=1.1.1.1", when exit mode is OFF:
|
2022-06-22 21:56:35 +00:00
|
|
|
* - DNS requests go unbound either to 127.0.0.1:53 directly (system extension) or bounced through
|
|
|
|
* TUNNELIP:53 (app extension), which forwards them (directly) to the upstream DNS server(s).
|
2021-08-31 23:15:48 +00:00
|
|
|
* With exit mode ON:
|
2022-06-22 21:56:35 +00:00
|
|
|
* - DNS requests go to unbound, as above, and unbound forwards them to 127.0.0.1:1053, which
|
|
|
|
* encapsulates them in Apple's god awful crap, then (on a response) sends them back to
|
|
|
|
* libunbound to be delivered back to the requestor.
|
2021-08-31 23:15:48 +00:00
|
|
|
* (This assumes a non-lokinet DNS; .loki and .snode get handled before either of these).
|
|
|
|
*/
|
|
|
|
@interface LLARPDNSTrampoline : NSObject
|
|
|
|
{
|
|
|
|
// The socket libunbound talks with:
|
|
|
|
uv_udp_t request_socket;
|
|
|
|
// The reply address. This is a bit hacky: we configure libunbound to just use single address
|
|
|
|
// (rather than a range) so that we don't have to worry about tracking different reply addresses.
|
2021-09-01 18:31:45 +00:00
|
|
|
@public
|
|
|
|
struct sockaddr reply_addr;
|
2021-08-31 23:15:48 +00:00
|
|
|
// UDP "session" aimed at the upstream DNS
|
2021-09-01 18:31:45 +00:00
|
|
|
@public
|
|
|
|
NWUDPSession* upstream;
|
2021-08-31 23:15:48 +00:00
|
|
|
// Apple docs say writes could take time *and* the crappy Apple datagram write methods aren't
|
|
|
|
// callable again until the previous write finishes. Deal with this garbage API by queuing
|
|
|
|
// everything than using a uv_async to process the queue.
|
2021-09-01 18:31:45 +00:00
|
|
|
@public
|
|
|
|
int write_ready;
|
|
|
|
@public
|
|
|
|
NSMutableArray<NSData*>* pending_writes;
|
2021-08-31 23:15:48 +00:00
|
|
|
uv_async_t write_trigger;
|
|
|
|
}
|
2021-09-01 18:31:45 +00:00
|
|
|
- (void)startWithUpstreamDns:(NWUDPSession*)dns
|
2022-06-22 21:56:35 +00:00
|
|
|
listenIp:(NSString*)listenIp
|
2021-09-01 18:31:45 +00:00
|
|
|
listenPort:(uint16_t)listenPort
|
|
|
|
uvLoop:(uv_loop_t*)loop
|
2021-08-31 23:15:48 +00:00
|
|
|
completionHandler:(void (^)(NSError* error))completionHandler;
|
|
|
|
|
|
|
|
- (void)flushWrites;
|
|
|
|
|
|
|
|
- (void)dealloc;
|
|
|
|
|
|
|
|
@end
|