Skip to content

Instantly share code, notes, and snippets.

@ericflo
Last active April 17, 2024 21:27
Show Gist options
  • Save ericflo/7dcf4179c315d8bd714c to your computer and use it in GitHub Desktop.
Save ericflo/7dcf4179c315d8bd714c to your computer and use it in GitHub Desktop.

Revisions

  1. ericflo revised this gist Jul 24, 2015. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions proxy.go
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,7 @@ package proxy
    import (
    "io"
    "net"
    "sync"

    log "github.com/Sirupsen/logrus"
    )
    @@ -71,11 +72,15 @@ func (p *Proxy) handle(connection net.Conn) {
    return
    }
    defer remote.Close()
    go p.copy(remote, connection)
    p.copy(connection, remote)
    wg := &sync.WaitGroup{}
    wg.Add(2)
    go p.copy(remote, connection, wg)
    go p.copy(connection, remote, wg)
    wg.Wait()
    }

    func (p *Proxy) copy(from, to net.Conn) {
    func (p *Proxy) copy(from, to net.Conn, wg *sync.WaitGroup) {
    defer wg.Done()
    select {
    case <-p.done:
    return
    @@ -86,4 +91,4 @@ func (p *Proxy) copy(from, to net.Conn) {
    return
    }
    }
    }
    }
  2. ericflo revised this gist Jul 24, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion proxy.go
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    package agent
    package proxy

    import (
    "io"
  3. ericflo revised this gist Jul 24, 2015. 1 changed file with 1 addition and 53 deletions.
    54 changes: 1 addition & 53 deletions proxy.go
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,8 @@
    package proxy
    package agent

    import (
    "fmt"
    "io"
    "net"
    "sync"

    log "github.com/Sirupsen/logrus"
    )
    @@ -89,53 +87,3 @@ func (p *Proxy) copy(from, to net.Conn) {
    }
    }
    }

    type ProxyManager struct {
    fromIP string
    proxies map[string]*Proxy
    mut *sync.Mutex
    }

    func NewProxyManager(fromIP string) *ProxyManager {
    return &ProxyManager{
    fromIP: fromIP,
    proxies: make(map[string]*Proxy),
    mut: &sync.Mutex{},
    }
    }

    func (p *ProxyManager) Add(fromPort int, to string) {
    p.mut.Lock()
    defer p.mut.Unlock()
    from := fmt.Sprintf("%s:%d", p.fromIP, fromPort)
    if _, ok := p.proxies[from]; ok {
    log.WithFields(log.Fields{
    "from": from, "to": to,
    }).Errorln("Tried to add a proxy when one already existed")
    return
    }
    proxy := NewProxy(from, to)
    p.proxies[from] = proxy
    if err := proxy.Start(); err != nil {
    log.WithFields(log.Fields{
    "from": from,
    "to": to,
    "err": err,
    }).Errorln("Could not start proxy")
    }
    }

    func (p *ProxyManager) Remove(fromPort int) {
    p.mut.Lock()
    defer p.mut.Unlock()
    from := fmt.Sprintf("%s:%d", p.fromIP, fromPort)
    proxy, ok := p.proxies[from]
    if !ok {
    log.WithFields(log.Fields{
    "from": from,
    }).Errorln("Tried to remove a proxy when none existed")
    return
    }
    proxy.Stop()
    delete(p.proxies, from)
    }
  4. ericflo created this gist Jul 24, 2015.
    141 changes: 141 additions & 0 deletions proxy.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,141 @@
    package proxy

    import (
    "fmt"
    "io"
    "net"
    "sync"

    log "github.com/Sirupsen/logrus"
    )

    type Proxy struct {
    from string
    to string
    done chan struct{}
    log *log.Entry
    }

    func NewProxy(from, to string) *Proxy {
    return &Proxy{
    from: from,
    to: to,
    done: make(chan struct{}),
    log: log.WithFields(log.Fields{
    "from": from,
    "to": to,
    }),
    }
    }

    func (p *Proxy) Start() error {
    p.log.Infoln("Starting proxy")
    listener, err := net.Listen("tcp", p.from)
    if err != nil {
    return err
    }
    go p.run(listener)
    return nil
    }

    func (p *Proxy) Stop() {
    p.log.Infoln("Stopping proxy")
    if p.done == nil {
    return
    }
    close(p.done)
    p.done = nil
    }

    func (p *Proxy) run(listener net.Listener) {
    for {
    select {
    case <-p.done:
    return
    default:
    connection, err := listener.Accept()
    if err == nil {
    go p.handle(connection)
    } else {
    p.log.WithField("err", err).Errorln("Error accepting conn")
    }
    }
    }
    }

    func (p *Proxy) handle(connection net.Conn) {
    p.log.Debugln("Handling", connection)
    defer p.log.Debugln("Done handling", connection)
    defer connection.Close()
    remote, err := net.Dial("tcp", p.to)
    if err != nil {
    p.log.WithField("err", err).Errorln("Error dialing remote host")
    return
    }
    defer remote.Close()
    go p.copy(remote, connection)
    p.copy(connection, remote)
    }

    func (p *Proxy) copy(from, to net.Conn) {
    select {
    case <-p.done:
    return
    default:
    if _, err := io.Copy(to, from); err != nil {
    p.log.WithField("err", err).Errorln("Error from copy")
    p.Stop()
    return
    }
    }
    }

    type ProxyManager struct {
    fromIP string
    proxies map[string]*Proxy
    mut *sync.Mutex
    }

    func NewProxyManager(fromIP string) *ProxyManager {
    return &ProxyManager{
    fromIP: fromIP,
    proxies: make(map[string]*Proxy),
    mut: &sync.Mutex{},
    }
    }

    func (p *ProxyManager) Add(fromPort int, to string) {
    p.mut.Lock()
    defer p.mut.Unlock()
    from := fmt.Sprintf("%s:%d", p.fromIP, fromPort)
    if _, ok := p.proxies[from]; ok {
    log.WithFields(log.Fields{
    "from": from, "to": to,
    }).Errorln("Tried to add a proxy when one already existed")
    return
    }
    proxy := NewProxy(from, to)
    p.proxies[from] = proxy
    if err := proxy.Start(); err != nil {
    log.WithFields(log.Fields{
    "from": from,
    "to": to,
    "err": err,
    }).Errorln("Could not start proxy")
    }
    }

    func (p *ProxyManager) Remove(fromPort int) {
    p.mut.Lock()
    defer p.mut.Unlock()
    from := fmt.Sprintf("%s:%d", p.fromIP, fromPort)
    proxy, ok := p.proxies[from]
    if !ok {
    log.WithFields(log.Fields{
    "from": from,
    }).Errorln("Tried to remove a proxy when none existed")
    return
    }
    proxy.Stop()
    delete(p.proxies, from)
    }