i found a ready source code on github for portforwarding in golang
here is the code
package main
import (
"io"
"log"
"net"
)
var localServerHost = "localhost:1020"
var remoteServerHost = "192.168.10.1:1020"
func main() {
ln, err := net.Listen("tcp", localServerHost)
if err != nil {
log.Fatal(err)
}
log.Println("Port forwarding server up and listening on ",
localServerHost)
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go handleConnection(conn)
}
}
func forward(src, dest net.Conn) {
defer src.Close()
defer dest.Close()
io.Copy(src, dest)
}
func handleConnection(c net.Conn) {
log.Println("Connection from : ", c.RemoteAddr())
remote, err := net.Dial("tcp", remoteServerHost)
if err != nil {
log.Fatal(err)
}
log.Println("Connected to ", remoteServerHost)
go forward(c, remote)
go forward(remote, c)
}
i dont have any idea now how can i put flag on user connections, so then i can read data form user connection and save or filter some of packets depend on connection flag
its a wrong way ?
Edit: This is an answer original question about forwarding and filtering TCP. @ermya has since changed the question to ask about WebSockets. This answer is not relevant to what is now a very different question.
You can filter the stream by interposing a reader or writer in the io.Copy operation. Here's how to interpose a reader:
type myFilter struct {
r io.Reader
}
func (f myFilter) Read(p []byte) (int, error) {
n, err := f.r.Read(p)
// Do something with p[:n]. As an example, the following for loop shows how
// to uppercase ASCII letters. Replace this for loop with the filtering of
// your choice.
for i, b := range p[:n] {
if 'a' <= b && b <= 'z' {
p[i] = b - ('a' - 'A')
}
}
return n, err
}
Filter data from net.Conn by replacing the call to go forward(remote, c)
with:
go func() {
defer remote.Close()
defer c.Close()
io.Copy(remote, myFilter{c}) // interpose the filter here
}()
As an aside, the naming in forward
is confusing because src
is actually the destination and dest
is the source. Use this:
func forward(dest, src net.Conn) {
defer src.Close()
defer dest.Close()
io.Copy(dest, src)
}