mirror of
https://github.com/go-i2p/go-meta-listener.git
synced 2025-09-23 23:33:23 -04:00
Compare commits
8 Commits
v0.0.1
...
6b30e62ee4
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6b30e62ee4 | ||
![]() |
c0524805f7 | ||
![]() |
b692f9c58f | ||
![]() |
509c265a3d | ||
![]() |
ab41cecda5 | ||
![]() |
87fc3e2113 | ||
![]() |
69fcebc9e2 | ||
![]() |
ba004dc59b |
2
Makefile
Normal file
2
Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
fmt:
|
||||
find . -name '*.go' -exec gofumpt -s -extra -w {} \;
|
@@ -14,6 +14,8 @@ var (
|
||||
ErrListenerClosed = errors.New("listener is closed")
|
||||
// ErrNoListeners is returned when the meta listener has no active listeners
|
||||
ErrNoListeners = errors.New("no active listeners")
|
||||
// ErrInternalListenerFailure is returned when an internal listener fails
|
||||
ErrInternalListenerFailure = errors.New("Internal listener error, shutting down metalistener for restart")
|
||||
)
|
||||
|
||||
// MetaListener implements the net.Listener interface and manages multiple
|
||||
@@ -127,12 +129,19 @@ func (ml *MetaListener) handleListener(id string, listener net.Listener) {
|
||||
ml.mu.RUnlock()
|
||||
|
||||
if stillExists {
|
||||
// Only report error if this listener hasn't been removed
|
||||
// Create a combined error with both the standard message and original error details
|
||||
combinedErr := fmt.Errorf("%w: listener %s error - %v",
|
||||
ErrInternalListenerFailure, id, err)
|
||||
|
||||
// Send the combined error to notify Accept() calls
|
||||
select {
|
||||
case ml.errCh <- fmt.Errorf("listener %s error: %w", id, err):
|
||||
case ml.errCh <- combinedErr:
|
||||
default:
|
||||
// Don't block if no one is reading errors
|
||||
}
|
||||
|
||||
// Then close all listeners
|
||||
go ml.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
72
mirror/header.go
Normal file
72
mirror/header.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package mirror
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// AddHeaders adds headers to the connection.
|
||||
// It takes a net.Conn and a map of headers as input.
|
||||
// It only adds headers if the connection is an HTTP connection.
|
||||
// It returns a net.Conn with the headers added.
|
||||
func AddHeaders(conn net.Conn, headers map[string]string) net.Conn {
|
||||
// read a request from the connection
|
||||
// if the request is an HTTP request, add the headers
|
||||
// if the request is not an HTTP request, return the connection as is
|
||||
req, err := http.ReadRequest(bufio.NewReader(conn))
|
||||
if err != nil {
|
||||
log.Println("Error reading request:", err)
|
||||
// if the request is not an HTTP request, return the connection as is
|
||||
return conn
|
||||
}
|
||||
log.Println("Adding headers to connection:", req.Method, req.URL)
|
||||
for key, value := range headers {
|
||||
req.Header.Add(key, value)
|
||||
log.Println("Added header:", key, value)
|
||||
}
|
||||
// write the request back to the connection
|
||||
if err := req.Write(conn); err != nil {
|
||||
log.Println("Error writing request:", err)
|
||||
// if there is an error writing the request, return the connection as is
|
||||
return conn
|
||||
}
|
||||
// If all goes well, return the connection with the headers added
|
||||
return conn
|
||||
}
|
||||
|
||||
// Accept accepts a connection from the listener.
|
||||
// It takes a net.Listener as input and returns a net.Conn with the headers added.
|
||||
// It is used to accept connections from the meta listener and add headers to them.
|
||||
func (ml *Mirror) Accept() (net.Conn, error) {
|
||||
// Accept a connection from the listener
|
||||
conn, err := ml.MetaListener.Accept()
|
||||
if err != nil {
|
||||
log.Println("Error accepting connection:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if the connection is a TLS connection
|
||||
if tlsConn, ok := conn.(*tls.Conn); ok {
|
||||
// If it is a TLS connection, perform the handshake
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
log.Println("Error performing TLS handshake:", err)
|
||||
return nil, err
|
||||
}
|
||||
// If the handshake is successful, get the underlying connection
|
||||
conn = tlsConn.NetConn()
|
||||
}
|
||||
|
||||
host := map[string]string{
|
||||
"Host": ml.MetaListener.Addr().String(),
|
||||
"X-Forwarded-For": conn.RemoteAddr().String(),
|
||||
"X-Forwarded-Proto": "http",
|
||||
}
|
||||
|
||||
// Add headers to the connection
|
||||
conn = AddHeaders(conn, host)
|
||||
|
||||
return conn, nil
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package mirror
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -79,23 +80,30 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
}
|
||||
port = "3000"
|
||||
}
|
||||
if strings.HasSuffix(port, "22") {
|
||||
log.Println("Port ends with 22, setting hiddenTls to true")
|
||||
log.Println("This is a workaround for the fact that the default port for SSH is 22")
|
||||
log.Println("This is so self-configuring SSH servers can be used without TLS, which would make connecting to them wierd")
|
||||
hiddenTls = false
|
||||
}
|
||||
localAddr := net.JoinHostPort("127.0.0.1", port)
|
||||
// Listen on plain HTTP
|
||||
tcpListener, err := net.Listen("tcp", localAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("http", tcpListener); err != nil {
|
||||
if err := ml.AddListener(port, tcpListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("HTTP Local listener added http://%s\n", tcpListener.Addr())
|
||||
log.Println("Checking for existing onion and garlic listeners")
|
||||
listenerId := fmt.Sprintf("metalistener-%s-%s", name, port)
|
||||
// Check if onion and garlic listeners already exist
|
||||
if ml.Onions[port] == nil {
|
||||
// make a new onion listener
|
||||
// and add it to the map
|
||||
log.Println("Creating new onion listener")
|
||||
onion, err := onramp.NewOnion("metalistener-" + name + port)
|
||||
onion, err := onramp.NewOnion(listenerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,7 +114,7 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
// make a new garlic listener
|
||||
// and add it to the map
|
||||
log.Println("Creating new garlic listener")
|
||||
garlic, err := onramp.NewGarlic("metalistener-"+name+port, "127.0.0.1:7656", onramp.OPT_WIDE)
|
||||
garlic, err := onramp.NewGarlic(listenerId, "127.0.0.1:7656", onramp.OPT_WIDE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -120,7 +128,8 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("onion", onionListener); err != nil {
|
||||
oid := fmt.Sprintf("onion-%s", onionListener.Addr().String())
|
||||
if err := ml.AddListener(oid, onionListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("OnionTLS listener added https://%s\n", onionListener.Addr())
|
||||
@@ -128,7 +137,8 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("garlic", garlicListener); err != nil {
|
||||
gid := fmt.Sprintf("garlic-%s", garlicListener.Addr().String())
|
||||
if err := ml.AddListener(gid, garlicListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("GarlicTLS listener added https://%s\n", garlicListener.Addr())
|
||||
@@ -137,7 +147,8 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("onion", onionListener); err != nil {
|
||||
oid := fmt.Sprintf("onion-%s", onionListener.Addr().String())
|
||||
if err := ml.AddListener(oid, onionListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Onion listener added http://%s\n", onionListener.Addr())
|
||||
@@ -145,7 +156,8 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("garlic", garlicListener); err != nil {
|
||||
gid := fmt.Sprintf("garlic-%s", garlicListener.Addr().String())
|
||||
if err := ml.AddListener(gid, garlicListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Garlic listener added http://%s\n", garlicListener.Addr())
|
||||
@@ -161,7 +173,8 @@ func (ml Mirror) Listen(name, addr, certdir string, hiddenTls bool) (net.Listene
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ml.AddListener("tls", tlsListener); err != nil {
|
||||
tid := fmt.Sprintf("tls-%s", tlsListener.Addr().String())
|
||||
if err := ml.AddListener(tid, tlsListener); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("TLS listener added https://%s\n", tlsListener.Addr())
|
||||
|
Reference in New Issue
Block a user