Part 2: Networking Basics
WaterWall is easier to configure when you separate three ideas:
- where traffic enters WaterWall
- what WaterWall does to the traffic
- where WaterWall sends it next
Most examples use simple arrows:
TcpListener -> MuxClient -> VlessClient -> TlsClient -> TcpConnector
Traffic enters from the left, moves upstream through the chain, and responses come back downstream in the opposite direction.
IP Addresses
An IP address identifies a host or interface on a network.
Common examples:
127.0.0.1 local machine only
0.0.0.0 bind on all IPv4 interfaces
192.168.1.10 private LAN address
203.0.113.10 public IPv4 documentation address
::1 IPv6 loopback
:: bind on all IPv6 interfaces
For listener nodes, address is usually the local address to bind.
For connector nodes, address is usually the remote destination to connect to.
Ports
A port identifies a service on an IP address. For example:
22 SSH
53 DNS
80 HTTP
443 HTTPS
8080 common test HTTP port
Only one process can usually listen on the same address, protocol, and port at the same time. If WaterWall cannot bind a listener, another process may already be using that port.
On Linux, check listening TCP sockets with:
ss -ltnp
For UDP:
ss -lunp
TCP
TCP is connection-oriented. It creates a stream between two endpoints.
In WaterWall, TCP traffic usually starts with TcpListener and ends with
TcpConnector:
client -> TcpListener -> ... -> TcpConnector -> remote server
TcpListener accepts incoming TCP connections and creates one WaterWall line for
each accepted connection. TcpConnector opens the outbound TCP connection on the
other side of the chain.
Use TCP for protocols such as HTTP, HTTPS, SSH, SOCKS, and most proxy-style tunnel traffic.
UDP
UDP is message-oriented. It sends datagrams instead of a continuous stream.
WaterWall has UDP nodes for stateful and stateless cases:
UdpListener -> ... -> UdpConnector
UdpStatelessSocket -> packet-oriented chain
UDP is commonly used for DNS, QUIC, WireGuard, game traffic, and real-time media. Because UDP does not create a stream by itself, the surrounding WaterWall nodes must decide how peer identity and packet routing are handled.
Localhost, Private IP, and Public IP
127.0.0.1 only accepts connections from the same machine. Use it for local
testing.
Private addresses such as 10.0.0.0/8, 172.16.0.0/12, and
192.168.0.0/16 are used inside private networks. They are not directly
reachable from the public internet.
A public VPS address is reachable from the internet if the provider firewall and the server firewall allow the port.
For a public WaterWall listener on a VPS, a common bind address is:
{
"address": "0.0.0.0",
"port": 443
}
For a local-only test listener:
{
"address": "127.0.0.1",
"port": 8080
}
DNS and Domain Names
Connector nodes can use domain names:
{
"address": "example.com",
"port": 443
}
WaterWall resolves the domain through its shared DNS resolver. The default
selection policy is controlled by dns.domain-strategy in core.json.
If a domain returns both IPv4 and IPv6 records, domain-strategy decides which
one WaterWall should prefer.
NAT and Port Forwarding
Many machines are behind NAT. A private machine can usually connect outward, but outside clients cannot connect inward unless the router or cloud firewall forwards the port.
A simple TCP forward looks like this:
client -> VPS:8080 -> WaterWall -> example.com:80
WaterWall chain:
TcpListener(0.0.0.0:8080) -> TcpConnector(example.com:80)
This forwards TCP streams. It does not automatically change the HTTP Host
header or make the remote server behave as if the client connected directly.
Streams and Packets
WaterWall supports both stream-style and packet-style traffic.
Stream-style traffic behaves like a byte stream:
TcpListener -> EncryptionClient -> TcpConnector
Packet-style traffic carries IP packets or packet-like datagrams:
TunDevice -> WireGuardDevice -> UdpStatelessSocket
Some nodes bridge between the two worlds. For example, PacketsToStream wraps
packets into a stream format, and StreamToPackets unwraps that stream back into
packets on the other side.
Do not treat packet chains exactly like TCP chains. A packet chain may use worker-level packet lines that stay alive across many unrelated packets.
Reading Chain Arrows
This chain:
TcpListener -> MuxClient -> VlessClient -> TlsClient -> TcpConnector
means:
TcpListeneraccepts a TCP client.MuxClientmultiplexes logical connections over the transport path.VlessClientwraps the payload in VLESS client framing.TlsClientcarries the result inside a TLS connection.TcpConnectorconnects to the configured remote server.
The reverse traffic returns through the same nodes in the opposite direction.
When designing a chain, first write the plain arrow diagram. Then turn each arrow node into JSON in the config file.