mirror of
https://github.com/go-i2p/onramp.git
synced 2025-07-12 10:55:29 -04:00
87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package onramp
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type OnrampProxy struct {
|
|
Onion
|
|
Garlic
|
|
}
|
|
|
|
// Proxy passes requests from a net.Listener to a remote server
|
|
// without touching them in any way. It can be used as a shortcut,
|
|
// set up a Garlic or Onion Listener and pass it, along with the
|
|
// address of a locally running service and the hidden service
|
|
// listener will expose the local service.
|
|
// Pass it a regular net.Listener(or a TLS listener if you like),
|
|
// and an I2P or Onion address, and it will act as a tunnel to a
|
|
// listening hidden service somewhere.
|
|
func (p *OnrampProxy) Proxy(list net.Listener, raddr string) error {
|
|
log.WithFields(logrus.Fields{
|
|
"remote_address": raddr,
|
|
"local_address": list.Addr().String(),
|
|
}).Debug("Starting proxy service")
|
|
|
|
for {
|
|
log.Debug("Waiting for incoming connection")
|
|
conn, err := list.Accept()
|
|
if err != nil {
|
|
log.WithError(err).Error("Failed to accept connection")
|
|
return err
|
|
}
|
|
|
|
log.WithFields(logrus.Fields{
|
|
"local_addr": conn.LocalAddr().String(),
|
|
"remote_addr": conn.RemoteAddr().String(),
|
|
}).Debug("Accepted new connection, starting proxy routine")
|
|
|
|
go p.proxy(conn, raddr)
|
|
}
|
|
}
|
|
|
|
func (p *OnrampProxy) proxy(conn net.Conn, raddr string) {
|
|
log.WithFields(logrus.Fields{
|
|
"remote_address": raddr,
|
|
"local_addr": conn.LocalAddr().String(),
|
|
"remote_addr": conn.RemoteAddr().String(),
|
|
}).Debug("Setting up proxy connection")
|
|
|
|
var remote net.Conn
|
|
var err error
|
|
checkaddr := strings.Split(raddr, ":")[0]
|
|
if strings.HasSuffix(checkaddr, ".i2p") {
|
|
log.Debug("Detected I2P address, using Garlic connection")
|
|
remote, err = p.Garlic.Dial("tcp", raddr)
|
|
} else if strings.HasSuffix(checkaddr, ".onion") {
|
|
log.Debug("Detected Onion address, using Tor connection")
|
|
remote, err = p.Onion.Dial("tcp", raddr)
|
|
} else {
|
|
log.Debug("Using standard TCP connection")
|
|
remote, err = net.Dial("tcp", raddr)
|
|
}
|
|
if err != nil {
|
|
log.WithError(err).Error("Failed to establish remote connection")
|
|
log.Fatal("Cannot dial to remote")
|
|
}
|
|
defer remote.Close()
|
|
|
|
log.WithFields(logrus.Fields{
|
|
"local_addr": remote.LocalAddr().String(),
|
|
"remote_addr": remote.RemoteAddr().String(),
|
|
}).Debug("Remote connection established, starting bidirectional copy")
|
|
|
|
go io.Copy(remote, conn)
|
|
io.Copy(conn, remote)
|
|
}
|
|
|
|
var proxy *OnrampProxy = &OnrampProxy{}
|
|
|
|
func Proxy(list net.Listener, raddr string) error {
|
|
return proxy.Proxy(list, raddr)
|
|
}
|