security #6
133
README.md
133
README.md
@ -4,11 +4,11 @@
|
||||
### Linux
|
||||
#### Policy Based Routing
|
||||
|
||||
ip route flush 10
|
||||
ip route flush table 10
|
||||
ip route add table 10 to 1.1.1.0/24 dev eth1
|
||||
ip rule add from 1.1.1.4 table 10 priority 10
|
||||
|
||||
ip route flush 11
|
||||
ip route flush table 11
|
||||
ip route add table 11 to 1.1.1.0/24 dev eth2
|
||||
ip rule add from 1.1.1.5 table 11 priority 11
|
||||
|
||||
@ -20,69 +20,114 @@
|
||||
See http://kb.linuxvirtualserver.org/wiki/Using_arp_announce/arp_ignore_to_disable_ARP
|
||||
|
||||
### Setup Scripts
|
||||
These are functional setup scripts that make the application run as intended on Linux. They should later be split into
|
||||
component parts, or incorporated into the main application.
|
||||
These are functional setup scripts that make the application run as intended on Linux.
|
||||
|
||||
#### Remote Portal
|
||||
### Remote Portal
|
||||
#### Pre-Start
|
||||
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# IPv4 Forwarding
|
||||
|
||||
## Set up variables
|
||||
REMOTE_PORTAL_ADDRESS=A.B.C.D
|
||||
|
||||
## IPv4 Forwarding
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
sysctl -w net.ipv4.conf.eth0.proxy_arp=1
|
||||
|
||||
# Tunnel addr/up
|
||||
## Transfer the local routing table to a much lower priority
|
||||
(ip rule show | grep '20:') > /dev/null || ip rule add from all table local priority 20
|
||||
ip rule del priority 0 2> /dev/null || true
|
||||
|
||||
## Ports to route locally
|
||||
|
||||
### MPBL3P
|
||||
ip rule del priority 1 2> /dev/null || true
|
||||
ip rule add to "$REMOTE_PORTAL_ADDRESS" dport 1234 table local priority 1
|
||||
|
||||
### SSH
|
||||
ip rule del priority 2 2> /dev/null || true
|
||||
ip rule add to "$REMOTE_PORTAL_ADDRESS" dport 22 table local priority 2
|
||||
|
||||
#### Post-Start
|
||||
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
## Set up variables
|
||||
REMOTE_PORTAL_ADDRESS=A.B.C.D
|
||||
|
||||
## Tunnel addr/up
|
||||
ip addr add 172.19.152.2/31 dev nc0
|
||||
ip link set up nc0
|
||||
|
||||
# Deliberately break local routing
|
||||
ip rule add from all table local priority 20
|
||||
ip rule del 0 || true
|
||||
|
||||
# Route packets to the interface but for nc to this host
|
||||
ip rule add to 1.1.1.3 dport 1234 table local priority 9
|
||||
|
||||
# Route packets to the interface but not for nc via the tunnel
|
||||
ip route flush 10
|
||||
ip route add table 10 to 1.1.1.3 via 172.19.152.3 dev nc0
|
||||
ip rule add to 1.1.1.3 table 10 priority 10
|
||||
ip route flush table 19
|
||||
ip route add table 19 to "$REMOTE_PORTAL_ADDRESS" via 172.19.152.3 dev nc0
|
||||
ip rule del priority 19 2> /dev/null || true
|
||||
ip rule add to "$REMOTE_PORTAL_ADDRESS" table 19 priority 19
|
||||
|
||||
#### Local Portal
|
||||
### Local Portal
|
||||
#### Pre-Start
|
||||
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
## Set up variables
|
||||
GATEWAY_INTERFACE=eth0
|
||||
GATEWAY_ADDRESS=10.36.12.1
|
||||
|
||||
## Fix ARP
|
||||
sysctl -w net.ipv4.conf.all.arp_announce=1
|
||||
sysctl -w net.ipv4.conf.all.arp_ignore=1
|
||||
|
||||
## IPv4 Forwarding
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
|
||||
## Gateway Interface Setup
|
||||
ip addr flush dev "$GATEWAY_INTERFACE"
|
||||
ip addr add "$GATEWAY_ADDRESS"/32 dev "$GATEWAY_INTERFACE"
|
||||
ip link set up "$GATEWAY_INTERFACE"
|
||||
|
||||
## Per-Interface Routing Tables
|
||||
|
||||
### 10.10.0.0/24
|
||||
ip route flush table 10
|
||||
ip route add table 10 default via 10.10.0.1
|
||||
ip rule del priority 10 2> /dev/null || true
|
||||
ip rule add from 10.10.0.0/24 table 10 priority 10
|
||||
|
||||
### 192.168.0.0/24
|
||||
ip route flush table 11
|
||||
ip route add table 11 default via 192.168.0.1
|
||||
ip rule del priority 11 2> /dev/null || true
|
||||
ip rule add from 192.168.0.0/24 table 11 priority 11
|
||||
|
||||
#### Post-Start
|
||||
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Fix ARP
|
||||
sysctl -w net.ipv4.conf.all.arp_announce=1
|
||||
sysctl -w net.ipv4.conf.all.arp_ignore=1
|
||||
## Set up variables
|
||||
REMOTE_PORTAL_ADDRESS=A.B.C.D
|
||||
GATEWAY_INTERFACE=eth0
|
||||
|
||||
# IPv4 Forwarding
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
|
||||
# Tunnel addr/up
|
||||
## Tunnel Address and Enable
|
||||
ip addr add 172.19.152.3/31 dev nc0
|
||||
ip link set up nc0
|
||||
|
||||
# Fix routing out of the correct interfaces
|
||||
ip route flush 10
|
||||
ip route add table 10 to 1.1.1.0/24 dev eth1
|
||||
ip rule add from 1.1.1.4 table 10 priority 10
|
||||
## Route Outbound Packets Correctly
|
||||
ip route flush table 20
|
||||
ip route add table 20 default via 172.19.152.2 dev nc0
|
||||
ip rule del priority 20 2> /dev/null || true
|
||||
ip rule add from "$REMOTE_PORTAL_ADDRESS" iif "$GATEWAY_INTERFACE" table 20 priority 20
|
||||
|
||||
ip route flush 11
|
||||
ip route add table 11 to 1.1.1.0/24 dev eth2
|
||||
ip rule add from 1.1.1.5 table 11 priority 11
|
||||
|
||||
# Route packets from the remote portal's address on the client interface via the tunnel
|
||||
ip route flush 12
|
||||
ip route add table 12 to 1.1.1.0/24 via 172.19.152.2 dev nc0
|
||||
ip rule add from 1.1.1.3 iif eth3 table 12 priority 12
|
||||
|
||||
# Route packets to the remote portal's address out of the client interface
|
||||
ip route flush 13
|
||||
ip route add table 13 to 1.1.1.3 dev eth3
|
||||
ip rule add to 1.1.1.3 table 13 priority 13
|
||||
## Route Inbound Packets Correctly
|
||||
ip route flush table 21
|
||||
ip route add table 21 to "$REMOTE_PORTAL_ADDRESS" dev "$GATEWAY_INTERFACE"
|
||||
ip rule del priority 21 2> /dev/null || true
|
||||
ip rule add to "$REMOTE_PORTAL_ADDRESS" table 21 priority 21
|
||||
|
||||
#### Client
|
||||
|
||||
No configuration needed. Simply set the IP to that of the remote server/32 with a gateway of 192.168.1.1.
|
||||
Connect to `GATEWAY_INTERFACE` and set the IP to `REMOTE_PORTAL_ADDRESS`/32 with a gateway of `GATEWAY_ADDRESS`.
|
||||
|
@ -1,7 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"mpbl3p/crypto"
|
||||
"mpbl3p/crypto/sharedkey"
|
||||
"mpbl3p/proxy"
|
||||
"mpbl3p/tcp"
|
||||
"mpbl3p/tun"
|
||||
@ -10,24 +13,33 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TODO: Delete this code as soon as an alternative is available
|
||||
type UselessMac struct{}
|
||||
|
||||
func (UselessMac) CodeLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (UselessMac) Generate([]byte) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u UselessMac) Verify([]byte, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Configuration) Build() (*proxy.Proxy, error) {
|
||||
p := proxy.NewProxy(0)
|
||||
p.Generator = UselessMac{}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if c.Host.InterfaceName == "" {
|
||||
c.Host.InterfaceName = "nc%d"
|
||||
@ -44,13 +56,11 @@ func (c Configuration) Build() (*proxy.Proxy, error) {
|
||||
for _, peer := range c.Peers {
|
||||
switch peer.Method {
|
||||
case "TCP":
|
||||
err := buildTcp(p, peer)
|
||||
if err != nil {
|
||||
if err := buildTcp(p, peer, g, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "UDP":
|
||||
err := buildUdp(p, peer)
|
||||
if err != nil {
|
||||
if err := buildUdp(p, peer, g, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -59,7 +69,7 @@ func (c Configuration) Build() (*proxy.Proxy, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func buildTcp(p *proxy.Proxy, peer Peer) error {
|
||||
func buildTcp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
|
||||
if peer.RemoteHost != "" {
|
||||
f, err := tcp.InitiateFlow(
|
||||
fmt.Sprintf("%s:", peer.LocalHost),
|
||||
@ -70,13 +80,13 @@ func buildTcp(p *proxy.Proxy, peer Peer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
p.AddConsumer(f)
|
||||
p.AddProducer(f, UselessMac{})
|
||||
p.AddConsumer(f, g())
|
||||
p.AddProducer(f, v())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
err := tcp.NewListener(p, fmt.Sprintf("%s:%d", peer.LocalHost, peer.LocalPort), UselessMac{})
|
||||
err := tcp.NewListener(p, fmt.Sprintf("%s:%d", peer.LocalHost, peer.LocalPort), v, g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -84,7 +94,7 @@ func buildTcp(p *proxy.Proxy, peer Peer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildUdp(p *proxy.Proxy, peer Peer) error {
|
||||
func buildUdp(p *proxy.Proxy, peer Peer, g func() proxy.MacGenerator, v func() proxy.MacVerifier) error {
|
||||
var c func() udp.Congestion
|
||||
switch peer.Congestion {
|
||||
case "None":
|
||||
@ -99,8 +109,8 @@ func buildUdp(p *proxy.Proxy, peer Peer) error {
|
||||
f, err := udp.InitiateFlow(
|
||||
fmt.Sprintf("%s:", peer.LocalHost),
|
||||
fmt.Sprintf("%s:%d", peer.RemoteHost, peer.RemotePort),
|
||||
UselessMac{},
|
||||
UselessMac{},
|
||||
v(),
|
||||
g(),
|
||||
c(),
|
||||
time.Duration(peer.KeepAlive)*time.Second,
|
||||
)
|
||||
@ -109,19 +119,13 @@ func buildUdp(p *proxy.Proxy, peer Peer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
p.AddConsumer(f)
|
||||
p.AddProducer(f, UselessMac{})
|
||||
p.AddConsumer(f, g())
|
||||
p.AddProducer(f, v())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
err := udp.NewListener(
|
||||
p,
|
||||
fmt.Sprintf("%s:%d", peer.LocalHost, peer.LocalPort),
|
||||
UselessMac{},
|
||||
UselessMac{},
|
||||
c,
|
||||
)
|
||||
err := udp.NewListener(p, fmt.Sprintf("%s:%d", peer.LocalHost, peer.LocalPort), v, g, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -10,13 +10,14 @@ type Configuration struct {
|
||||
}
|
||||
|
||||
type Host struct {
|
||||
PrivateKey string `validate:"required"`
|
||||
InterfaceName string
|
||||
|
||||
Crypto string `validate:"required,oneof=None Blake2s"`
|
||||
SharedKey string `validate:"required_if=Crypto Blake2s"`
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
PublicKey string `validate:"required"`
|
||||
Method string `validate:"oneof=TCP UDP"`
|
||||
Method string `validate:"oneof=TCP UDP"`
|
||||
|
||||
LocalHost string `validate:"omitempty,ip"`
|
||||
LocalPort uint `validate:"max=65535"`
|
||||
|
15
crypto/none.go
Normal file
15
crypto/none.go
Normal file
@ -0,0 +1,15 @@
|
||||
package crypto
|
||||
|
||||
type None struct{}
|
||||
|
||||
func (None) CodeLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (None) Generate([]byte) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (None) Verify([]byte, []byte) error {
|
||||
return nil
|
||||
}
|
40
crypto/sharedkey/blake2s.go
Normal file
40
crypto/sharedkey/blake2s.go
Normal file
@ -0,0 +1,40 @@
|
||||
package sharedkey
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"golang.org/x/crypto/blake2s"
|
||||
"mpbl3p/shared"
|
||||
)
|
||||
|
||||
type Blake2s struct {
|
||||
key []byte
|
||||
}
|
||||
|
||||
func NewBlake2s(key []byte) (*Blake2s, error) {
|
||||
_, err := blake2s.New128(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Blake2s{key: key}, nil
|
||||
}
|
||||
|
||||
func (b Blake2s) CodeLength() int {
|
||||
return blake2s.Size128
|
||||
}
|
||||
|
||||
func (b Blake2s) Generate(d []byte) []byte {
|
||||
h, _ := blake2s.New128(b.key)
|
||||
h.Write(d)
|
||||
return h.Sum([]byte{})
|
||||
}
|
||||
|
||||
func (b Blake2s) Verify(d []byte, s []byte) error {
|
||||
h, _ := blake2s.New128(b.key)
|
||||
h.Write(d)
|
||||
sum := h.Sum([]byte{})
|
||||
if !bytes.Equal(sum, s) {
|
||||
return shared.ErrBadChecksum
|
||||
}
|
||||
return nil
|
||||
}
|
1
go.mod
1
go.mod
@ -7,5 +7,6 @@ require (
|
||||
github.com/pkg/taptun v0.0.0-20160424131934-bbbd335672ab
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
gopkg.in/ini.v1 v1.62.0
|
||||
)
|
||||
|
@ -10,49 +10,26 @@ type Packet interface {
|
||||
Contents() []byte
|
||||
}
|
||||
|
||||
type SimplePacket struct {
|
||||
Data []byte
|
||||
timestamp time.Time
|
||||
}
|
||||
|
||||
// create a packet from the raw data of an IP packet
|
||||
func NewSimplePacket(data []byte) Packet {
|
||||
return SimplePacket{
|
||||
Data: data,
|
||||
timestamp: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild a packet from the wrapped format
|
||||
func UnmarshalSimplePacket(data []byte) (SimplePacket, error) {
|
||||
p := SimplePacket{
|
||||
Data: data[:len(data)-8],
|
||||
}
|
||||
|
||||
unixTime := int64(binary.LittleEndian.Uint64(data[len(data)-8:]))
|
||||
p.timestamp = time.Unix(unixTime, 0)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
type SimplePacket []byte
|
||||
|
||||
// get the raw data of the IP packet
|
||||
func (p SimplePacket) Marshal() []byte {
|
||||
footer := make([]byte, 8)
|
||||
|
||||
unixTime := uint64(p.timestamp.Unix())
|
||||
binary.LittleEndian.PutUint64(footer, unixTime)
|
||||
|
||||
return append(p.Data, footer...)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p SimplePacket) Contents() []byte {
|
||||
return p.Data
|
||||
return p
|
||||
}
|
||||
|
||||
func AppendMac(b []byte, g MacGenerator) []byte {
|
||||
footer := make([]byte, 8)
|
||||
unixTime := uint64(time.Now().Unix())
|
||||
binary.LittleEndian.PutUint64(footer, unixTime)
|
||||
|
||||
b = append(b, footer...)
|
||||
|
||||
mac := g.Generate(b)
|
||||
b = append(b, mac...)
|
||||
return b
|
||||
return append(b, mac...)
|
||||
}
|
||||
|
||||
func StripMac(b []byte, v MacVerifier) ([]byte, error) {
|
||||
@ -63,5 +40,7 @@ func StripMac(b []byte, v MacVerifier) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
// TODO: Verify timestamp
|
||||
|
||||
return data[:len(data)-8], nil
|
||||
}
|
||||
|
@ -8,51 +8,20 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPacket_Marshal(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testPacket := NewSimplePacket(testContent)
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
marshalled := testPacket.Marshal()
|
||||
|
||||
assert.Len(t, marshalled, len(testContent)+8)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnmarshalPacket(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testPacket := NewSimplePacket(testContent)
|
||||
testMarshalled := testPacket.Marshal()
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
p, err := UnmarshalSimplePacket(testMarshalled)
|
||||
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, p.Contents(), len(testContent))
|
||||
})
|
||||
|
||||
t.Run("Contents", func(t *testing.T) {
|
||||
p, err := UnmarshalSimplePacket(testMarshalled)
|
||||
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, p.Contents(), testContent)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAppendMac(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testMac := mocks.AlmostUselessMac{}
|
||||
testPacket := NewSimplePacket(testContent)
|
||||
testPacket := SimplePacket(testContent)
|
||||
testMarshalled := testPacket.Marshal()
|
||||
|
||||
appended := AppendMac(testMarshalled, testMac)
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
assert.Len(t, appended, len(testMarshalled)+4)
|
||||
assert.Len(t, appended, len(testMarshalled)+8+4)
|
||||
})
|
||||
|
||||
t.Run("Mac", func(t *testing.T) {
|
||||
assert.Equal(t, []byte{'a', 'b', 'c', 'd'}, appended[len(testMarshalled):])
|
||||
assert.Equal(t, []byte{'a', 'b', 'c', 'd'}, appended[len(testMarshalled)+8:])
|
||||
})
|
||||
|
||||
t.Run("Original", func(t *testing.T) {
|
||||
@ -63,7 +32,7 @@ func TestAppendMac(t *testing.T) {
|
||||
func TestStripMac(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testMac := mocks.AlmostUselessMac{}
|
||||
testPacket := NewSimplePacket(testContent)
|
||||
testPacket := SimplePacket(testContent)
|
||||
testMarshalled := testPacket.Marshal()
|
||||
|
||||
appended := AppendMac(testMarshalled, testMac)
|
||||
|
@ -31,8 +31,6 @@ type Proxy struct {
|
||||
Source Source
|
||||
Sink Sink
|
||||
|
||||
Generator MacGenerator
|
||||
|
||||
proxyChan chan Packet
|
||||
sinkChan chan Packet
|
||||
}
|
||||
@ -67,7 +65,7 @@ func (p Proxy) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (p Proxy) AddConsumer(c Consumer) {
|
||||
func (p Proxy) AddConsumer(c Consumer, g MacGenerator) {
|
||||
go func() {
|
||||
_, reconnectable := c.(Reconnectable)
|
||||
|
||||
@ -85,7 +83,7 @@ func (p Proxy) AddConsumer(c Consumer) {
|
||||
}
|
||||
|
||||
for c.IsAlive() {
|
||||
if err := c.Consume(<-p.proxyChan, p.Generator); err != nil {
|
||||
if err := c.Consume(<-p.proxyChan, g); err != nil {
|
||||
log.Println(err)
|
||||
break
|
||||
}
|
||||
|
@ -4,3 +4,4 @@ import "errors"
|
||||
|
||||
var ErrBadChecksum = errors.New("the packet had a bad checksum")
|
||||
var ErrDeadConnection = errors.New("the connection is dead")
|
||||
var ErrNotEnoughBytes = errors.New("not enough bytes")
|
||||
|
@ -2,7 +2,6 @@ package tcp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mpbl3p/proxy"
|
||||
@ -12,8 +11,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrNotEnoughBytes = errors.New("not enough bytes")
|
||||
|
||||
type Conn interface {
|
||||
Read(b []byte) (n int, err error)
|
||||
Write(b []byte) (n int, err error)
|
||||
@ -150,7 +147,7 @@ func (f *Flow) Produce(v proxy.MacVerifier) (proxy.Packet, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return proxy.UnmarshalSimplePacket(b)
|
||||
return proxy.SimplePacket(b), nil
|
||||
}
|
||||
|
||||
func (f *Flow) produceMarshalled() ([]byte, error) {
|
||||
@ -158,7 +155,7 @@ func (f *Flow) produceMarshalled() ([]byte, error) {
|
||||
if n, err := io.LimitReader(f.conn, 4).Read(lengthBytes); err != nil {
|
||||
return nil, err
|
||||
} else if n != 4 {
|
||||
return nil, ErrNotEnoughBytes
|
||||
return nil, shared.ErrNotEnoughBytes
|
||||
}
|
||||
|
||||
length := binary.LittleEndian.Uint32(lengthBytes)
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
func TestFlow_Consume(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testPacket := proxy.NewSimplePacket(testContent)
|
||||
testPacket := proxy.SimplePacket(testContent)
|
||||
testMac := mocks.AlmostUselessMac{}
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"net"
|
||||
)
|
||||
|
||||
func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier) error {
|
||||
func NewListener(p *proxy.Proxy, local string, v func() proxy.MacVerifier, g func() proxy.MacGenerator) error {
|
||||
laddr, err := net.ResolveTCPAddr("tcp", local)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -33,8 +33,8 @@ func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier) error {
|
||||
|
||||
log.Printf("received new tcp connection: %v\n", f)
|
||||
|
||||
p.AddConsumer(&f)
|
||||
p.AddProducer(&f, v)
|
||||
p.AddConsumer(&f, g())
|
||||
p.AddProducer(&f, v())
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -68,7 +68,7 @@ func (t *SourceSink) Source() (proxy.Packet, error) {
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
return proxy.NewSimplePacket(buf[:read]), nil
|
||||
return proxy.SimplePacket(buf[:read]), nil
|
||||
}
|
||||
|
||||
var good, bad float64
|
||||
|
@ -96,6 +96,9 @@ func (c *NewReno) ReceivedAck(ack uint32) {
|
||||
c.rtt = c.rtt*(1-RttExponentialFactor) + rtt*RttExponentialFactor
|
||||
|
||||
// Free Window
|
||||
// TODO: Check for freshness
|
||||
// TODO: Don't expect an ACK per packet
|
||||
|
||||
atomic.AddInt32(&c.inFlight, -1)
|
||||
select {
|
||||
case c.ackNotifier <- struct{}{}:
|
||||
@ -120,6 +123,8 @@ func (c *NewReno) ReceivedAck(ack uint32) {
|
||||
func (c *NewReno) ReceivedNack(nack uint32) {
|
||||
log.Printf("nack received for %d", nack)
|
||||
|
||||
// TODO : Check for freshness
|
||||
|
||||
// End slow start
|
||||
c.slowStart = false
|
||||
if s := c.windowSize; s > 1 {
|
||||
|
@ -115,7 +115,7 @@ func (f *InitiatedFlow) Reconnect() error {
|
||||
ack: 0,
|
||||
nack: 0,
|
||||
seq: seq,
|
||||
data: proxy.NewSimplePacket(nil),
|
||||
data: proxy.SimplePacket(nil),
|
||||
}
|
||||
|
||||
_ = f.sendPacket(p, f.g)
|
||||
@ -266,7 +266,7 @@ func (f *Flow) earlyUpdateLoop(g proxy.MacGenerator, keepalive time.Duration) {
|
||||
ack: f.congestion.NextAck(),
|
||||
nack: f.congestion.NextNack(),
|
||||
seq: seq,
|
||||
data: proxy.NewSimplePacket(nil),
|
||||
data: proxy.SimplePacket(nil),
|
||||
}
|
||||
|
||||
_ = f.sendPacket(p, g)
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
|
||||
func TestFlow_Consume(t *testing.T) {
|
||||
testContent := []byte("A test string is the content of this packet.")
|
||||
testPacket := proxy.NewSimplePacket(testContent)
|
||||
testPacket := proxy.SimplePacket(testContent)
|
||||
testMac := mocks.AlmostUselessMac{}
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
@ -42,7 +42,7 @@ func TestFlow_Produce(t *testing.T) {
|
||||
ack: 42,
|
||||
nack: 26,
|
||||
seq: 128,
|
||||
data: proxy.NewSimplePacket(testContent),
|
||||
data: proxy.SimplePacket(testContent),
|
||||
}
|
||||
testMac := mocks.AlmostUselessMac{}
|
||||
|
||||
|
@ -25,7 +25,7 @@ func fromUdpAddress(address net.UDPAddr) ComparableUdpAddress {
|
||||
}
|
||||
}
|
||||
|
||||
func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier, g proxy.MacGenerator, c func() Congestion) error {
|
||||
func NewListener(p *proxy.Proxy, local string, v func() proxy.MacVerifier, g func() proxy.MacGenerator, c func() Congestion) error {
|
||||
laddr, err := net.ResolveUDPAddr("udp", local)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -63,6 +63,9 @@ func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier, g proxy.MacG
|
||||
continue
|
||||
}
|
||||
|
||||
v := v()
|
||||
g := g()
|
||||
|
||||
f := newFlow(c(), v)
|
||||
|
||||
f.writer = pconn
|
||||
@ -75,7 +78,7 @@ func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier, g proxy.MacG
|
||||
|
||||
receivedConnections[raddr] = &f
|
||||
|
||||
p.AddConsumer(&f)
|
||||
p.AddConsumer(&f, g)
|
||||
p.AddProducer(&f, v)
|
||||
|
||||
log.Println("handling...")
|
||||
|
@ -3,6 +3,7 @@ package udp
|
||||
import (
|
||||
"encoding/binary"
|
||||
"mpbl3p/proxy"
|
||||
"mpbl3p/shared"
|
||||
)
|
||||
|
||||
type Packet struct {
|
||||
@ -14,14 +15,15 @@ type Packet struct {
|
||||
}
|
||||
|
||||
func UnmarshalPacket(b []byte) (p Packet, err error) {
|
||||
if len(b) < 12 {
|
||||
return Packet{}, shared.ErrNotEnoughBytes
|
||||
}
|
||||
|
||||
p.ack = binary.LittleEndian.Uint32(b[0:4])
|
||||
p.nack = binary.LittleEndian.Uint32(b[4:8])
|
||||
p.seq = binary.LittleEndian.Uint32(b[8:12])
|
||||
|
||||
p.data, err = proxy.UnmarshalSimplePacket(b[12:])
|
||||
if err != nil {
|
||||
return Packet{}, err
|
||||
}
|
||||
p.data = proxy.SimplePacket(b[12:])
|
||||
return p, nil
|
||||
}
|
||||
|
||||
|
@ -13,14 +13,14 @@ func TestPacket_Marshal(t *testing.T) {
|
||||
ack: 18,
|
||||
nack: 29,
|
||||
seq: 431,
|
||||
data: proxy.NewSimplePacket(testContent),
|
||||
data: proxy.SimplePacket(testContent),
|
||||
}
|
||||
|
||||
t.Run("Length", func(t *testing.T) {
|
||||
marshalled := testPacket.Marshal()
|
||||
|
||||
// 12 header + 8 timestamp
|
||||
assert.Len(t, marshalled, len(testContent)+12+8)
|
||||
assert.Len(t, marshalled, len(testContent)+12)
|
||||
})
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ func TestUnmarshalPacket(t *testing.T) {
|
||||
ack: 18,
|
||||
nack: 29,
|
||||
seq: 431,
|
||||
data: proxy.NewSimplePacket(testContent),
|
||||
data: proxy.SimplePacket(testContent),
|
||||
}
|
||||
testMarshalled := testPacket.Marshal()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user