Skip to content
This repository has been archived by the owner on Apr 16, 2024. It is now read-only.

Commit

Permalink
push work
Browse files Browse the repository at this point in the history
  • Loading branch information
lodevil committed Feb 25, 2013
0 parents commit 2ef6dbd
Show file tree
Hide file tree
Showing 17 changed files with 1,265 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
client
server
cli.cfg
ser.cfg
users
mk
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Secretun
a vpn written in go
16 changes: 16 additions & 0 deletions cli.cfg.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"tunnel": {
"name": "tcp",
"encoders": [
{
"name": "zlib",
"level": 6
}
],
"addr": "192.168.1.2:5555"
},
"auth": {
"username": "user",
"password": "passwd"
}
}
150 changes: 150 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package secretun

import (
"fmt"
"log"
)

type Client struct {
cfg map[string]map[string]interface{}
tunnel ClientTunnel
cli_ch ClientChan
nat_info NatInfo
}

func NewClient(cfg map[string]map[string]interface{}) (cli Client, err error) {
var name interface{}

cli.cfg = cfg
if _, ok := cfg["auth"]; !ok {
err = fmt.Errorf("missing `auth`")
return
}

tunnel_cfg, ok := cfg["tunnel"]
if !ok {
err = fmt.Errorf("missing `tunnel`")
return
}
name, ok = tunnel_cfg["name"]
if !ok {
err = fmt.Errorf("missing `tunnel.name`")
return
} else {
if _, ok = name.(string); !ok {
err = fmt.Errorf("tunnel.name is not a string")
return
}
}

if cli.tunnel, err = NewClientTunnel(name.(string)); err != nil {
return
}
cli.cli_ch = NewClientChan()
return
}

func (c *Client) Init() error {
return c.tunnel.Init(c.cfg["tunnel"])
}

func (c *Client) Run() error {
if err := c.tunnel.Start(c.cli_ch); err != nil {
return err
}
if err := c.auth(); err != nil {
return err
}

return c.nat()
}

func (c *Client) Shutdown() error {
return nil
}

func (c *Client) auth() error {
var user, passwd interface{}
var ok bool
var rst AuthResult

if user, ok = c.cfg["auth"]["username"]; !ok {
return fmt.Errorf("missing `username`")
} else if _, ok = user.(string); !ok {
return fmt.Errorf("invalid username type (string desired)")
}
if passwd, ok = c.cfg["auth"]["password"]; !ok {
return fmt.Errorf("missing `password`")
} else if _, ok = passwd.(string); !ok {
return fmt.Errorf("invalid password type (string desired)")
}

p := NewPacket(PT_AUTH, &AuthInfo{user.(string), passwd.(string)})
c.cli_ch.W <- p
p = <-c.cli_ch.R
if p.Decode(&rst) != nil {
return fmt.Errorf("invalid auth result")
}

if !rst.Ok {
return fmt.Errorf("auth fail: %s", rst.Message)
}
log.Println(rst)
c.nat_info = rst.NatInfo

return nil
}

func (c *Client) nat() error {
tun, err := CreateTun("")

if err != nil {
return err
}
defer tun.Close()

if err := tun.SetAddr(c.nat_info.IP, c.nat_info.Gateway); err != nil {
return err
}
if err := tun.SetNetmask(c.nat_info.Netmask); err != nil {
return err
}
if err := tun.SetMTU(1400); err != nil {
return err
}
tun_ch, err := tun.ReadChan()
if err != nil {
return err
}
if err := tun.Up(); err != nil {
return err
}

for {
select {
case packet, ok := <-c.cli_ch.R:
if !ok {
log.Println("tunnel closed")
return nil
}
if packet.Type == PT_P2P {
if _, err := tun.Write(packet.Data); err != nil {
return err
}
} else {
log.Println("end")
return nil
}
case data, ok := <-tun_ch:
if !ok {
log.Println("chan closed")
return nil
}
c.cli_ch.W <- NewPacket(PT_P2P, data)
case err := <-c.cli_ch.End:
return err
}
}

return nil
}
40 changes: 40 additions & 0 deletions cmd/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
json "encoding/json"
"flag"
"log"
"os"
"secretun"
)

var cfgfile = flag.String("cfg", "cli.cfg", "configure file path")

func main() {
flag.Parse()
var cfg = map[string]map[string]interface{}{}

if f, err := os.Open(*cfgfile); err != nil {
log.Println(err)
return
} else {
defer f.Close()
decoder := json.NewDecoder(f)
if err := decoder.Decode(&cfg); err != nil {
log.Println(err)
return
}
}

if cli, err := secretun.NewClient(cfg); err != nil {
log.Println(err)
} else {
if err := cli.Init(); err != nil {
log.Println(err)
return
}
if err = cli.Run(); err != nil {
log.Println(err)
}
}
}
40 changes: 40 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
json "encoding/json"
"flag"
"log"
"os"
"secretun"
)

var cfgfile = flag.String("cfg", "ser.cfg", "configure file path")

func main() {
flag.Parse()
var cfg = map[string]map[string]interface{}{}

if f, err := os.Open(*cfgfile); err != nil {
log.Println(err)
return
} else {
defer f.Close()
decoder := json.NewDecoder(f)
if err := decoder.Decode(&cfg); err != nil {
log.Println(err)
return
}
}

if ser, err := secretun.NewServer(cfg); err != nil {
log.Println(err)
} else {
if err := ser.Init(); err != nil {
log.Println(err)
return
}
if err = ser.Run(); err != nil {
log.Println(err)
}
}
}
57 changes: 57 additions & 0 deletions compress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package secretun

import (
"bytes"
zlib "compress/zlib"
"fmt"
"io"
)

type ZlibEncoder struct {
level int
}

func (z *ZlibEncoder) Init(cfg map[string]interface{}) error {
if ilevel, ok := cfg["level"]; !ok {
z.level = 6
} else if z.level, ok = ilevel.(int); !ok {
return fmt.Errorf("zlib.level invalid type (int desired)")
}

return nil
}

func (z *ZlibEncoder) Encode(data []byte) ([]byte, error) {
w := new(bytes.Buffer)
dec, err := zlib.NewWriterLevel(w, z.level)
if err != nil {
return nil, err
}
defer dec.Close()

if _, err = dec.Write(data); err != nil {
return nil, err
}
if err = dec.Flush(); err != nil {
return nil, err
}
return w.Bytes(), nil
}

func (z *ZlibEncoder) Decode(data []byte) ([]byte, error) {
w := new(bytes.Buffer)
if r, err := zlib.NewReader(bytes.NewBuffer(data)); err != nil {
return nil, err
} else {
if _, err = io.Copy(w, r); err != nil {
if err != io.ErrUnexpectedEOF && err != io.EOF {
return nil, err
}
}
}
return w.Bytes(), nil
}

func init() {
RegisterEncoder("zlib", ZlibEncoder{})
}
32 changes: 32 additions & 0 deletions encoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package secretun

import (
"fmt"
"reflect"
)

type Encoder interface {
Init(map[string]interface{}) error
Encode([]byte) ([]byte, error)
Decode([]byte) ([]byte, error)
}

var encoders = map[string]reflect.Type{}

func RegisterEncoder(name string, i interface{}) {
t := reflect.TypeOf(i)
if _, ok := reflect.New(t).Interface().(Encoder); !ok {
panic(fmt.Errorf("invalid encoder: %s", name))
}
encoders[name] = t
}

func NewEncoder(name string) (en Encoder, err error) {
if t, ok := encoders[name]; !ok {
err = fmt.Errorf("can't find encoder: %s", name)
return
} else {
return reflect.New(t).Interface().(Encoder), nil
}
return
}
Loading

0 comments on commit 2ef6dbd

Please sign in to comment.