- When app is started from command line,
config.jsonis loaded and values are read from it. PortsandTargetsare processed from the above file. Targets are processed in a way that a new structtargetServeris initialised which implements theTargetinterface.- The
Targetinterface has necessary methods needed for querying remote address information. - To listen into every port from the config file, a new goroutine is created to setup the proxy server.
Setupmethod basically resolves the local address i.e our port and starts listening to it while checking for any connections.- To check for new connections it is run in an infinite loop and the proxy server is ran in a different goroutine.
- Loadbalancing is done using a simple roundrobin algorithm. It checks for active host and if the host is not present, it moves on to a different host i.e remote address.
- After active remote address is found, a new TCP connection is made via proxy.
- Bidirectional copy of data is done, so that client and server can both see the response sent from the remote address.
- BPF kernel code resides in
bpf/bpf_proxy_dispatch.c - There are 2 maps defined
proxy_portsof typeBPF_MAP_TYPE_HASHandproxy_sockof typeBPF_MAP_TYPE_SOCKMAP. proxy_portsmap store information about the ports that are inside theconfig.jsonproxy_sockstore the information about thefdof theproxifie'slisterner socket.SECcontains that code that will be loaded into the memory.bpf_progis the program name that get's attached to the kernel.- port number is found by
ctx->local_portand if the port is not inside theproxy_portsmap the socket connection is passed forward. skcontains the information aboutproxy_sockmap's 0'th element which is ourfdofproxifie'slisterner socket.bpf_sk_assignassgns thectxto our socketsk- Package
tracerhas all the information how to load eBPF program. - Once the proxify application is run by
sudo ./proxify -b. Userspace side loads the bpf ELF filebpf_proxy_dispatch.o. The functionNewTracerinsidepkg/tracer/tracer.gohelps in achieving that. - After that userspace loads both the maps, initialise and populate them with respective values and creates a link between network ns and eBPF program. This is done by
RegisterIfacefunction.