dissertation-2-code/config/builder.go

136 lines
2.7 KiB
Go

package config
import (
"encoding/base64"
"fmt"
"mpbl3p/crypto"
"mpbl3p/crypto/sharedkey"
"mpbl3p/proxy"
"mpbl3p/tcp"
"mpbl3p/udp"
"mpbl3p/udp/congestion"
"time"
)
func (c Configuration) Build(source proxy.Source, sink proxy.Sink) (*proxy.Proxy, error) {
p := proxy.NewProxy(0)
var g func() proxy.MacGenerator
var v func() proxy.MacVerifier
switch c.Host.Crypto {
case "None":
g = func() proxy.MacGenerator { return crypto.None{} }
v = func() proxy.MacVerifier { return crypto.None{} }
case "Blake2s":
key, err := base64.StdEncoding.DecodeString(c.Host.SharedKey)
if err != nil {
return nil, err
}
if _, err := sharedkey.NewBlake2s(key); err != nil {
return nil, err
}
g = func() proxy.MacGenerator {
g, _ := sharedkey.NewBlake2s(key)
return g
}
v = func() proxy.MacVerifier {
v, _ := sharedkey.NewBlake2s(key)
return v
}
}
p.Source = source
p.Sink = sink
for _, peer := range c.Peers {
switch peer.Method {
case "TCP":
if err := buildTcp(p, peer, g, v); err != nil {
return nil, err
}
case "UDP":
if err := buildUdp(p, peer, g, v); err != nil {
return nil, err
}
}
}
return p, nil
}
func buildTcp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
var laddr func() string
if peer.LocalPort == 0 {
laddr = func() string { return fmt.Sprintf("%s:", peer.GetLocalHost()) }
} else {
laddr = func() string { return fmt.Sprintf("%s:%d", peer.GetLocalHost(), peer.LocalPort) }
}
if peer.RemoteHost != "" {
f, err := tcp.InitiateFlow(laddr, fmt.Sprintf("%s:%d", peer.RemoteHost, peer.RemotePort))
if err != nil {
return err
}
p.AddConsumer(f, g())
p.AddProducer(f, v())
return nil
}
err := tcp.NewListener(p, laddr(), v, g)
if err != nil {
return err
}
return nil
}
func buildUdp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
var laddr func() string
if peer.LocalPort == 0 {
laddr = func() string { return fmt.Sprintf("%s:", peer.GetLocalHost()) }
} else {
laddr = func() string { return fmt.Sprintf("%s:%d", peer.GetLocalHost(), peer.LocalPort) }
}
var c func() udp.Congestion
switch peer.Congestion {
case "None":
c = func() udp.Congestion { return congestion.NewNone() }
default:
fallthrough
case "NewReno":
c = func() udp.Congestion { return congestion.NewNewReno() }
}
if peer.RemoteHost != "" {
f, err := udp.InitiateFlow(
laddr,
fmt.Sprintf("%s:%d", peer.RemoteHost, peer.RemotePort),
v(),
g(),
c(),
time.Duration(peer.KeepAlive)*time.Second,
)
if err != nil {
return err
}
p.AddConsumer(f, g())
p.AddProducer(f, v())
return nil
}
err := udp.NewListener(p, laddr(), v, g, c)
if err != nil {
return err
}
return nil
}