Skip to content

Instantly share code, notes, and snippets.

@kallydev
Created July 29, 2019 02:15
Show Gist options
  • Save kallydev/f823fd551f4bd984fbf53b5704a5b588 to your computer and use it in GitHub Desktop.
Save kallydev/f823fd551f4bd984fbf53b5704a5b588 to your computer and use it in GitHub Desktop.
Simple TCP forwarding implementation, part of the code comes from shadowsocks/shadowsocks-go
// https://github.com/shadowsocks/shadowsocks-go/blob/master/LICENSE
package main
type LeakyBuf struct {
bufSize int
freeList chan []byte
}
const leakyBufSize = 4096
const maxNBuf = 2048
var leakyBuf = NewLeakyBuf(maxNBuf, leakyBufSize)
func NewLeakyBuf(n, bufSize int) *LeakyBuf {
return &LeakyBuf{
bufSize: bufSize,
freeList: make(chan []byte, n),
}
}
func (lb *LeakyBuf) Get() (b []byte) {
select {
case b = <-lb.freeList:
default:
b = make([]byte, lb.bufSize)
}
return
}
func (lb *LeakyBuf) Put(b []byte) {
if len(b) != lb.bufSize {
panic("invalid buffer size that's put into leaky buffer")
}
select {
case lb.freeList <- b:
default:
}
return
}
package main
import (
"flag"
"log"
"net"
)
var localAddr, remoteAddr string
func main() {
flag.StringVar(&localAddr, "l", "0.0.0.0:80", "local addr")
flag.StringVar(&remoteAddr, "r", "127.0.0.1:8080", "remote addr")
flag.Parse()
tcpAddr, err := net.ResolveTCPAddr("tcp", localAddr)
if err != nil {
log.Println(err)
return
}
tcpListener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Println(err)
return
}
for {
tcpConn, err := tcpListener.AcceptTCP()
if err != nil {
log.Println(err)
continue
}
go tcpHandler(tcpConn)
}
}
func tcpHandler(tcpConn *net.TCPConn) {
dstConn, err := net.Dial("tcp", remoteAddr)
if err != nil {
log.Println(err)
return
}
go pipe(tcpConn, dstConn)
pipe(dstConn, tcpConn)
}
func pipe(src, dst net.Conn) {
defer dst.Close()
buf := leakyBuf.Get()
defer leakyBuf.Put(buf)
for {
n, err := src.Read(buf)
if n > 0 {
if _, err := dst.Write(buf[0:n]); err != nil {
log.Println(err)
break
}
}
if err != nil {
break
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment