Skip to content

Commit

Permalink
Refactor handleConnection in server.go
Browse files Browse the repository at this point in the history
  • Loading branch information
cyfdecyf committed Dec 13, 2012
1 parent af0682b commit 5686c46
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 79 deletions.
4 changes: 2 additions & 2 deletions cmd/shadowsocks-local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ func handleConnection(conn net.Conn, server string, encTbl *ss.EncryptTable) {
log.Println("unsurpported addr type")
break
}
debug.Println("connecting ", addr)
debug.Println("connecting", addr)
conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43})

remote, err := ss.DialWithRawAddr(addrToSend, server, encTbl)
if err != nil {
hasError = true
break
}
c := make(chan int, 2)
c := make(chan byte, 2)
go ss.Pipe(conn, remote, c)
go ss.Pipe(remote, conn, c)
<-c // close the other connection whenever one connection is closed
Expand Down
134 changes: 58 additions & 76 deletions cmd/shadowsocks-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"bytes"
"encoding/binary"
"errors"
ss "github.com/shadowsocks/shadowsocks-go/shadowsocks"
"log"
"net"
Expand All @@ -13,89 +14,70 @@ import (

var debug ss.DebugLog

var errAddr = errors.New("addr type not supported")

func handleConnection(conn *ss.Conn) {
debug.Printf("socks connect from %s\n", conn.RemoteAddr().String())
var err error = nil
var hasError = false
for {
var _ int
buf := make([]byte, 1)
_, err = conn.Read(buf)
if err != nil {
hasError = true
break
}
addrType := buf[0]
var addr string
var port int16
if addrType == 1 {
buf = make([]byte, 6)
_, err = conn.Read(buf)
if err != nil {
hasError = true
break
}
var addrIp net.IP = make(net.IP, 4)
copy(addrIp, buf[0:4])
addr = addrIp.String()
sb := bytes.NewBuffer(buf[4:6])
binary.Read(sb, binary.BigEndian, &port)
} else if addrType == 3 {
_, err = conn.Read(buf)
if err != nil {
hasError = true
break
}
addrLen := buf[0]
buf = make([]byte, addrLen+2)
_, err = conn.Read(buf)
if err != nil {
hasError = true
break
}
sb := bytes.NewBuffer(buf[0:addrLen])
addr = sb.String()
sb = bytes.NewBuffer(buf[addrLen : addrLen+2])
binary.Read(sb, binary.BigEndian, &port)
} else {
hasError = true
log.Println("unsurpported addr type")
break
}
debug.Println("connecting ", addr)
var remote net.Conn
remote, err = net.Dial("tcp", addr+":"+strconv.Itoa(int(port)))
if err != nil {
hasError = true
break
if debug {
// function arguments are always evaluated, so surround debug
// statement with if statement
debug.Printf("socks connect from %s\n", conn.RemoteAddr().String())
}
defer conn.Close()

var addr string
var port int16
var addrType byte
var remote net.Conn
var c chan byte
var err error

buf := make([]byte, 1)
if _, err = conn.Read(buf); err != nil {
goto onError
}
addrType = buf[0]
if addrType == 1 {
buf = make([]byte, 6)
if _, err = conn.Read(buf); err != nil {
goto onError
}
if err != nil {
hasError = true
break
sb := bytes.NewBuffer(buf[4:6])
binary.Read(sb, binary.BigEndian, &port)
addrIp := make(net.IP, 4)
copy(addrIp, buf[0:4])
addr = addrIp.String()
} else if addrType == 3 {
if _, err = conn.Read(buf); err != nil {
goto onError
}
c := make(chan int, 2)
go ss.Pipe(conn, remote, c)
go ss.Pipe(remote, conn, c)
<-c // close the other connection whenever one connection is closed
debug.Println("closing")
err = conn.Close()
err1 := remote.Close()
if err == nil {
err = err1
addrLen := buf[0]
buf = make([]byte, addrLen+2)
if _, err = conn.Read(buf); err != nil {
goto onError
}
break
sb := bytes.NewBuffer(buf[addrLen : addrLen+2])
binary.Read(sb, binary.BigEndian, &port)
addr = string(buf[0:addrLen])
} else {
log.Println("unsurpported addr type")
err = errAddr
goto onError
}
if err != nil || hasError {
if err != nil {
debug.Println("error:", err)
}
err = conn.Close()
if err != nil {
debug.Println("close:", err)
}
return
debug.Println("connecting", addr)
if remote, err = net.Dial("tcp", addr+":"+strconv.Itoa(int(port))); err != nil {
goto onError
}
defer remote.Close()
debug.Println("piping", addr)
c = make(chan byte, 2)
go ss.Pipe(conn, remote, c)
go ss.Pipe(remote, conn, c)
<-c // close the other connection whenever one connection is closed
debug.Println("closing", addr)
return

onError:
debug.Println("error", addr, err)
}

// Add a encrypt table cache to save memory and startup time in case of many
Expand Down
2 changes: 1 addition & 1 deletion shadowsocks/pipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"net"
)

func Pipe(src, dst net.Conn, end chan int) {
func Pipe(src, dst net.Conn, end chan byte) {
// Should not use io.Copy here.
// io.Copy will try to use the ReadFrom interface of TCPConn, but the src
// here is not a regular file, so sendfile is not applicable.
Expand Down

0 comments on commit 5686c46

Please sign in to comment.