Documentation
¶
Overview ¶
Package tlsfrag provides tools to split the TLS handshake record containing the Client Hello message into multiple TLS records. This technique, known as TLS record fragmentation, forces censors to maintain state and allocate memory for potential reassembly, making censorship more difficult and resource-intensive. For detailed explanation on how this technique works, refer to Circumventing the GFW with TLS Record Fragmentation.
This package offers convenient helper functions to create a TLS transport.StreamDialer that fragments the TLS handshake record:
- NewFixedLenStreamDialer creates a transport.StreamDialer that splits the Client Hello message into two records. One of the records will have the specified length of splitLen bytes.
- NewStreamDialerFunc offers a more flexible way to fragment Client Hello message. It accepts a callback function that determines the split point, enabling advanced splitting logic such as splitting based on the SNI extension.
Index ¶
- func NewFixedLenStreamDialer(base transport.StreamDialer, splitLen int) (transport.StreamDialer, error)
- func NewStreamDialerFunc(base transport.StreamDialer, frag FragFunc) (transport.StreamDialer, error)
- func WrapConnFunc(base transport.StreamConn, frag FragFunc) (transport.StreamConn, error)
- type FragFunc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewFixedLenStreamDialer ¶
func NewFixedLenStreamDialer(base transport.StreamDialer, splitLen int) (transport.StreamDialer, error)
NewFixedLenStreamDialer is a transport.StreamDialer that fragments the TLS handshake record. It splits the record into two records based on the given splitLen. If splitLen is positive, the first piece will contain the specified number of leading bytes from the original message. If it is negative, the second piece will contain the specified number of trailing bytes.
func NewStreamDialerFunc ¶
func NewStreamDialerFunc(base transport.StreamDialer, frag FragFunc) (transport.StreamDialer, error)
NewStreamDialerFunc creates a transport.StreamDialer that intercepts the initial TLS Client Hello handshake record and splits it into two separate records before sending them. The split point is determined by the callback function frag. The dialer then adds appropriate headers to each record and transmits them sequentially using the base dialer. Following the fragmented Client Hello, all subsequent data is passed through directly without modification.
func WrapConnFunc ¶
func WrapConnFunc(base transport.StreamConn, frag FragFunc) (transport.StreamConn, error)
WrapConnFunc wraps the base transport.StreamConn and splits the first TLS Client Hello packet into two records according to the frag function. Subsequent data is forwarded without modification. The Write to the base transport.StreamConn will be buffered until we have the full initial Client Hello record. If the first packet isn't a valid Client Hello, WrapConnFunc simply forwards all data through transparently.
Types ¶
type FragFunc ¶
FragFunc takes the content of the first handshake record in a TLS session as input, and returns an integer that represents the fragmentation point index. The input content excludes the 5-byte record header. The returned integer should be in range 0 to len(record)-1. The record will then be fragmented into two parts: record[:n] and record[n:]. If the returned index is either ≤ 0 or ≥ len(record), no fragmentation will occur.