Skip to content
This repository has been archived by the owner on Jun 14, 2018. It is now read-only.

Commit

Permalink
Add IPv6 support to forwards (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
reth- authored and calmh committed Mar 10, 2017
1 parent b77b626 commit 6f60fd1
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/mole/cmd/mole/forwarder.go
Expand Up @@ -34,7 +34,7 @@ func startForwarder(dialer Dialer) chan<- conf.ForwardLine {
fwdChan := make(chan conf.ForwardLine)
go func() {
for line := range fwdChan {
for i := 0; i <= line.Repeat; i++ {
for i := 0; i < len(line.Src.Ports); i++ {
src := line.SrcString(i)
dst := line.DstString(i)

Expand Down
8 changes: 7 additions & 1 deletion src/mole/cmd/mole/interfaces.go
Expand Up @@ -13,7 +13,7 @@ import (
)

var errNoLoopbackFound = errors.New("no loopback interface found")
var keepAddressRe = regexp.MustCompile(`^127\.0\.0\.([0-9]|[0-2][0-9]|3[0-1])$`)
var keepAddressRe = regexp.MustCompile(`^(127\.0\.0\.([0-9]|[0-2][0-9]|3[0-1])|::1)$`)

func loInterface() string {
intfs, err := net.Interfaces()
Expand Down Expand Up @@ -56,6 +56,9 @@ func missingAddresses(cfg *conf.Config) []string {

var missing []string
for _, ip := range wanted {
if ip[0] == '[' {
ip = ip[1 : len(ip)-1]
}
if !curMap[ip] {
missing = append(missing, ip)
}
Expand All @@ -69,6 +72,9 @@ func extraneousAddresses(cfg *conf.Config) []string {
added := cfg.SourceAddresses()
addedMap := make(map[string]bool)
for _, ip := range added {
if ip[0] == '[' {
ip = ip[1 : len(ip)-1]
}
addedMap[ip] = true
}

Expand Down
2 changes: 1 addition & 1 deletion src/mole/cmd/mole/platform_unix.go
Expand Up @@ -53,7 +53,7 @@ func addToHostsFile(tag string, domain string, cfg *conf.Config) {
if domain != "" {
name = name + "." + domain
}
ip := fwd.Lines[0].SrcIP
ip := fwd.Lines[0].Src.Addr.String()
entries = append(entries, hosts.Entry{IP: ip, Names: []string{name}})
}

Expand Down
25 changes: 16 additions & 9 deletions src/mole/cmd/mole/shell.go
Expand Up @@ -2,11 +2,12 @@ package main

import (
"fmt"
"github.com/sbinet/liner"
"io"
"mole/ansi"
"mole/conf"
"mole/table"
"github.com/sbinet/liner"
"io"
"net"
"os"
"os/signal"
"strconv"
Expand Down Expand Up @@ -148,11 +149,17 @@ func shell(fwdChan chan<- conf.ForwardLine, cfg *conf.Config, dialer Dialer) {
warnln(err)
break
}
srcpa := conf.Addrports{
Addr: net.ParseIP(src[0]),
Ports: []int{srcp},
}
dstpa := conf.Addrports{
Addr: net.ParseIP(dst[0]),
Ports: []int{dstp},
}
fwd := conf.ForwardLine{
SrcIP: src[0],
SrcPort: srcp,
DstIP: dst[0],
DstPort: dstp,
Src: srcpa,
Dst: dstpa,
}
okln("add", fwd)
fwdChan <- fwd
Expand Down Expand Up @@ -218,7 +225,7 @@ func testForwards(dialer Dialer, cfg *conf.Config) <-chan forwardTest {
go func(fwd conf.Forward) {
nlines := 0
for _, line := range fwd.Lines {
nlines += line.Repeat + 1
nlines += len(line.Src.Ports)
}

res := forwardTest{name: fwd.Name}
Expand All @@ -229,7 +236,7 @@ func testForwards(dialer Dialer, cfg *conf.Config) <-chan forwardTest {
j := 0

for _, line := range fwd.Lines {
for i := 0; i <= line.Repeat; i++ {
for i := 0; i < len(line.Src.Ports); i++ {
// Do each line in parallell
go func(line conf.ForwardLine, i, j int) {
outstanding <- true
Expand Down Expand Up @@ -267,7 +274,7 @@ func testLineIndex(dialer Dialer, line conf.ForwardLine, i int) <-chan error {
}()

go func() {
debugln("test", line.DstString(i))
debugln("test, Src:", line.SrcString(i), " Dst:", line.DstString(i))
conn, err := dialer.Dial("tcp", line.DstString(i))
if err == nil && conn != nil {
conn.Close()
Expand Down
53 changes: 34 additions & 19 deletions src/mole/conf/config.go
Expand Up @@ -3,6 +3,7 @@ package conf
import (
"fmt"
"io"
"net"
"sort"

"mole/ini"
Expand Down Expand Up @@ -66,42 +67,54 @@ type Forward struct {
Comments []string
}

// Addr is a composite type of IPAddr and TCP ports
type Addrports struct {
Addr net.IP
Ports []int
}

// ForwardLine is a specific port or range or ports to forward
type ForwardLine struct {
SrcIP string
SrcPort int
DstIP string
DstPort int
Repeat int
Src Addrports
Dst Addrports
}

// SrcString returns the source IP address and port as a string formatted for
// use with Dial() and similar.
func (line ForwardLine) SrcString(i int) string {
if i > line.Repeat {
if i >= len(line.Src.Ports) {
panic("index > repeat")
}
return fmt.Sprintf("%s:%d", line.SrcIP, line.SrcPort+i)
if line.Src.Addr.To4() != nil {
return fmt.Sprintf("%s:%d", line.Src.Addr.String(), line.Src.Ports[i])
} else {
return fmt.Sprintf("[%s]:%d", line.Src.Addr.String(), line.Src.Ports[i])
}
}

// DstString returns the destination IP address and port as a string formatted for
// use with Dial() and similar.
func (line ForwardLine) DstString(i int) string {
if i > line.Repeat {
//if i > line.Repeat {
if i >= len(line.Dst.Ports) {
panic("index > repeat")
}
return fmt.Sprintf("%s:%d", line.DstIP, line.DstPort+i)
if line.Dst.Addr.To4() != nil {
return fmt.Sprintf("%s:%d", line.Dst.Addr.String(), line.Dst.Ports[i])
} else {
return fmt.Sprintf("[%s]:%d", line.Dst.Addr.String(), line.Dst.Ports[i])
}
}

// String returns a human readable representation of the port forward.
func (line ForwardLine) String() string {
if line.Repeat == 0 {
src := fmt.Sprintf("%s:%d", line.SrcIP, line.SrcPort)
dst := fmt.Sprintf("%s:%d", line.DstIP, line.DstPort)
if len(line.Src.Ports) == 1 {
src := fmt.Sprintf("%s:%d", line.Src.Addr.String(), line.Src.Ports[0])
dst := fmt.Sprintf("%s:%d", line.Dst.Addr.String(), line.Dst.Ports[0])
return fmt.Sprintf("%s -> %s", src, dst)
}
src := fmt.Sprintf("%s:%d-%d", line.SrcIP, line.SrcPort, line.SrcPort+line.Repeat)
dst := fmt.Sprintf("%s:%d-%d", line.DstIP, line.DstPort, line.DstPort+line.Repeat)
src := fmt.Sprintf("%s:%d-%d", line.Src.Addr.String(), line.Src.Ports[0], line.Src.Ports[len(line.Src.Ports)-1])
dst := fmt.Sprintf("%s:%d-%d", line.Dst.Addr.String(), line.Dst.Ports[0], line.Dst.Ports[len(line.Src.Ports)-1])
return fmt.Sprintf("%s -> %s", src, dst)
}

Expand All @@ -117,7 +130,7 @@ func (c *Config) SourceAddresses() []string {
addrMap := make(map[string]bool)
for _, fwd := range c.Forwards {
for _, line := range fwd.Lines {
addrMap[line.SrcIP] = true
addrMap[line.Src.Addr.String()] = true
}
}

Expand All @@ -137,11 +150,13 @@ func (c *Config) Remap() {
port := 10000
for fi := range c.Forwards {
for li := range c.Forwards[fi].Lines {
if c.Forwards[fi].Lines[li].SrcIP != "127.0.0.1" {
if c.Forwards[fi].Lines[li].Src.Addr.String() != "127.0.0.1" && c.Forwards[fi].Lines[li].Src.Addr.String() != "[::1]" {
// BUG: Need to keep track of used ports and not try to use them twice.
c.Forwards[fi].Lines[li].SrcIP = "127.0.0.1"
c.Forwards[fi].Lines[li].SrcPort = port
port += c.Forwards[fi].Lines[li].Repeat + 1
c.Forwards[fi].Lines[li].Src.Addr = net.ParseIP("127.0.0.1")
for sp := range c.Forwards[fi].Lines[li].Src.Ports {
c.Forwards[fi].Lines[li].Src.Ports[sp] = port
port += 1
}
}
}
}
Expand Down
42 changes: 21 additions & 21 deletions src/mole/conf/config_test.go
Expand Up @@ -161,7 +161,7 @@ func TestHosts(t *testing.T) {
func TestForwards(t *testing.T) {
cfg, _ := loadFile("test/valid-forwards.ini")

if l := len(cfg.Forwards); l != 2 {
if l := len(cfg.Forwards); l != 5 {
t.Errorf("Incorrect len(Forwards) %d", l)
}

Expand All @@ -171,37 +171,37 @@ func TestForwards(t *testing.T) {
}

l1 := f.Lines[0]
if l1.SrcIP != "127.0.0.1" {
t.Errorf("Incorrect SrcIP %q", l1.SrcIP)
if l1.Src.Addr.String() != "127.0.0.1" {
t.Errorf("Incorrect SrcIP %q", l1.Src.Addr.String())
}
if l1.SrcPort != 42000 {
t.Errorf("Incorrect SrcPort %d", l1.SrcPort)
if l1.Src.Ports[0] != 42000 {
t.Errorf("Incorrect SrcPort %d", l1.Src.Ports[0])
}
if l1.DstIP != "192.168.173.10" {
t.Errorf("Incorrect DstIP %q", l1.DstIP)
if l1.Dst.Addr.String() != "192.168.173.10" {
t.Errorf("Incorrect DstIP %q", l1.Dst.Addr.String())
}
if l1.DstPort != 42000 {
t.Errorf("Incorrect DstPort %d", l1.DstPort)
if l1.Dst.Ports[0] != 42000 {
t.Errorf("Incorrect DstPort %d", l1.Dst.Ports[0])
}
if l1.Repeat != 2 {
t.Errorf("Incorrect Repeat %d", l1.Repeat)
if len(l1.Src.Ports) != 3 || len(l1.Dst.Ports) != 3 {
t.Errorf("Incorrect port range %d", l1.Src.Ports)
}

l2 := f.Lines[1]
if l2.SrcIP != "127.0.0.1" {
t.Errorf("Incorrect l2 SrcIP %q", l2.SrcIP)
if l2.Src.Addr.String() != "127.0.0.1" {
t.Errorf("Incorrect l2 SrcIP %q", l2.Src.Addr.String())
}
if l2.SrcPort != 8443 {
t.Errorf("Incorrect l2 SrcPort %d", l2.SrcPort)
if l2.Src.Ports[0] != 8443 {
t.Errorf("Incorrect l2 SrcPort %d", l2.Src.Ports[0])
}
if l2.DstIP != "192.168.173.10" {
t.Errorf("Incorrect l2 DstIP %q", l2.DstIP)
if l2.Dst.Addr.String() != "192.168.173.10" {
t.Errorf("Incorrect l2 DstIP %q", l2.Dst.Addr.String())
}
if l2.DstPort != 443 {
t.Errorf("Incorrect l2 DstPort %d", l2.DstPort)
if l2.Dst.Ports[0] != 443 {
t.Errorf("Incorrect l2 DstPort %d", l2.Dst.Ports[0])
}
if l2.Repeat != 0 {
t.Errorf("Incorrect l2 Repeat %d", l2.Repeat)
if len(l2.Src.Ports) != 1 || len(l2.Dst.Ports) != 1 {
t.Errorf("Incorrect l2 port range %d", l2.Src.Ports)
}

f = cfg.Forwards[1]
Expand Down

0 comments on commit 6f60fd1

Please sign in to comment.