Skip to content
Merged
143 changes: 77 additions & 66 deletions infra/conf/freedom.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package conf

import (
"encoding/base64"
"net"
"strconv"
"strings"
Expand All @@ -19,6 +20,7 @@ type FreedomConfig struct {
UserLevel uint32 `json:"userLevel"`
Fragment *Fragment `json:"fragment"`
Noise *Noise `json:"noise"`
Noises []*Noise `json:"noises"`
ProxyProtocol uint32 `json:"proxyProtocol"`
}

Expand All @@ -29,8 +31,9 @@ type Fragment struct {
}

type Noise struct {
Packet string `json:"packet"`
Delay string `json:"delay"`
Type string `json:"type"`
Packet string `json:"packet"`
Delay *Int32Range `json:"delay"`
}

// Build implements Buildable
Expand Down Expand Up @@ -149,74 +152,18 @@ func (c *FreedomConfig) Build() (proto.Message, error) {
}
}
}
if c.Noise != nil {
config.Noise = new(freedom.Noise)
var err, err2 error
p := strings.Split(strings.ToLower(c.Noise.Packet), ":")
if len(p) != 2 {
return nil, errors.New("invalid type for packet")
}
switch p[0] {
case "rand":
randValue := strings.Split(p[1], "-")
if len(randValue) > 2 {
return nil, errors.New("Only 2 values are allowed for rand")
}
if len(randValue) == 2 {
config.Noise.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
config.Noise.LengthMax, err2 = strconv.ParseUint(randValue[1], 10, 64)
}
if len(randValue) == 1 {
config.Noise.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
config.Noise.LengthMax = config.Noise.LengthMin
}
if err != nil {
return nil, errors.New("invalid value for rand LengthMin").Base(err)
}
if err2 != nil {
return nil, errors.New("invalid value for rand LengthMax").Base(err2)
}
if config.Noise.LengthMin > config.Noise.LengthMax {
config.Noise.LengthMin, config.Noise.LengthMax = config.Noise.LengthMax, config.Noise.LengthMin
}
if config.Noise.LengthMin == 0 {
return nil, errors.New("rand lengthMin or lengthMax cannot be 0")
}

case "str":
//user input string
config.Noise.StrNoise = strings.TrimSpace(p[1])

default:
return nil, errors.New("Invalid packet,only rand and str are supported")
}
if c.Noise.Delay != "" {
d := strings.Split(strings.ToLower(c.Noise.Delay), "-")
if len(d) > 2 {
return nil, errors.New("Invalid delay value")
}
if len(d) == 2 {
config.Noise.DelayMin, err = strconv.ParseUint(d[0], 10, 64)
config.Noise.DelayMax, err2 = strconv.ParseUint(d[1], 10, 64)
if c.Noise != nil {
return nil, errors.PrintRemovedFeatureError("noise = { ... }", "noises = [ { ... } ]")
}

} else {
config.Noise.DelayMin, err = strconv.ParseUint(d[0], 10, 64)
config.Noise.DelayMax = config.Noise.DelayMin
}
if c.Noises != nil {
for _, n := range c.Noises {
NConfig, err := ParseNoise(n)
if err != nil {
return nil, errors.New("Invalid value for DelayMin").Base(err)
}
if err2 != nil {
return nil, errors.New("Invalid value for DelayMax").Base(err2)
return nil, err
}
if config.Noise.DelayMin > config.Noise.DelayMax {
config.Noise.DelayMin, config.Noise.DelayMax = config.Noise.DelayMax, config.Noise.DelayMin
}
if config.Noise.DelayMin == 0 {
return nil, errors.New("DelayMin or DelayMax cannot be 0")
}
} else {
config.Noise.DelayMin = 0
config.Noises = append(config.Noises, NConfig)
}
}

Expand Down Expand Up @@ -248,3 +195,67 @@ func (c *FreedomConfig) Build() (proto.Message, error) {
}
return config, nil
}

func ParseNoise(noise *Noise) (*freedom.Noise, error) {
var err, err2 error
NConfig := new(freedom.Noise)

switch strings.ToLower(noise.Type) {
case "rand":
randValue := strings.Split(noise.Packet, "-")
if len(randValue) > 2 {
return nil, errors.New("Only 2 values are allowed for rand")
}
if len(randValue) == 2 {
NConfig.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
NConfig.LengthMax, err2 = strconv.ParseUint(randValue[1], 10, 64)
}
if len(randValue) == 1 {
NConfig.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
NConfig.LengthMax = NConfig.LengthMin
}
if err != nil {
return nil, errors.New("invalid value for rand LengthMin").Base(err)
}
if err2 != nil {
return nil, errors.New("invalid value for rand LengthMax").Base(err2)
}
if NConfig.LengthMin > NConfig.LengthMax {
NConfig.LengthMin, NConfig.LengthMax = NConfig.LengthMax, NConfig.LengthMin
}
if NConfig.LengthMin == 0 {
return nil, errors.New("rand lengthMin or lengthMax cannot be 0")
}

case "str":
//user input string
NConfig.StrNoise = []byte(strings.TrimSpace(noise.Packet))

case "base64":
//user input base64
NConfig.StrNoise, err = base64.StdEncoding.DecodeString(strings.TrimSpace(noise.Packet))
if err != nil {
return nil, errors.New("Invalid base64 string")
}

default:
return nil, errors.New("Invalid packet,only rand,str,base64 are supported")
}

if noise.Delay != nil {
if noise.Delay.From != 0 && noise.Delay.To != 0 {
NConfig.DelayMin = uint64(noise.Delay.From)
NConfig.DelayMax = uint64(noise.Delay.To)
if NConfig.DelayMin > NConfig.LengthMax {
NConfig.DelayMin, NConfig.DelayMax = NConfig.LengthMax, NConfig.DelayMin
}
} else {
return nil, errors.New("DelayMin or DelayMax cannot be zero")
}

} else {
NConfig.DelayMin = 0
NConfig.DelayMax = 0
}
return NConfig, nil
}
60 changes: 30 additions & 30 deletions proxy/freedom/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions proxy/freedom/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ message Noise {
uint64 length_max = 2;
uint64 delay_min = 3;
uint64 delay_max = 4;
string str_noise = 5;
bytes str_noise = 5;
}

message Config {
Expand All @@ -48,5 +48,5 @@ message Config {
uint32 user_level = 4;
Fragment fragment = 5;
uint32 proxy_protocol = 6;
Noise noise = 7;
repeated Noise noises = 7;
}
42 changes: 21 additions & 21 deletions proxy/freedom/freedom.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,11 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
}
} else {
writer = NewPacketWriter(conn, h, ctx, UDPOverride)
if h.config.Noise != nil {
errors.LogDebug(ctx, "NOISE", h.config.Noise.StrNoise, h.config.Noise.LengthMin, h.config.Noise.LengthMax,
h.config.Noise.DelayMin, h.config.Noise.DelayMax)
if h.config.Noises != nil {
errors.LogDebug(ctx, "NOISE", h.config.Noises)
writer = &NoisePacketWriter{
Writer: writer,
noise: h.config.Noise,
noises: h.config.Noises,
firstWrite: true,
UDPOverride: UDPOverride,
}
Expand Down Expand Up @@ -396,12 +395,12 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {

type NoisePacketWriter struct {
buf.Writer
noise *Noise
noises []*Noise
firstWrite bool
UDPOverride net.Destination
}

// MultiBuffer writer with Noise in first packet
// MultiBuffer writer with Noise before first packet
func (w *NoisePacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
if w.firstWrite {
w.firstWrite = false
Expand All @@ -411,22 +410,23 @@ func (w *NoisePacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
}
var noise []byte
var err error
//User input string
if w.noise.StrNoise != "" {
noise = []byte(w.noise.StrNoise)
} else {
//Random noise
noise, err = GenerateRandomBytes(randBetween(int64(w.noise.LengthMin),
int64(w.noise.LengthMax)))
}

if err != nil {
return err
}
w.Writer.WriteMultiBuffer(buf.MultiBuffer{buf.FromBytes(noise)})
for _, n := range w.noises {
//User input string or base64 encoded string
if n.StrNoise != nil {
noise = n.StrNoise
} else {
//Random noise
noise, err = GenerateRandomBytes(randBetween(int64(n.LengthMin),
int64(n.LengthMax)))
}
if err != nil {
return err
}
w.Writer.WriteMultiBuffer(buf.MultiBuffer{buf.FromBytes(noise)})

if w.noise.DelayMin != 0 {
time.Sleep(time.Duration(randBetween(int64(w.noise.DelayMin), int64(w.noise.DelayMax))) * time.Millisecond)
if n.DelayMin != 0 {
time.Sleep(time.Duration(randBetween(int64(n.DelayMin), int64(n.DelayMax))) * time.Millisecond)
}
}

}
Expand Down