// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package revdial implements a Dialer and Listener which work together
// to turn an accepted connection (for instance, a Hijacked HTTP request) into
// a Dialer which can then create net.Conns connecting back to the original
// dialer, which then gets a net.Listener accepting those conns.
//
// This is basically a very minimal SOCKS5 client & server.
//
// The motivation is that sometimes you want to run a server on a
// machine deep inside a NAT. Rather than connecting to the machine
// directly (which you can't, because of the NAT), you have the
// sequestered machine connect out to a public machine. Both sides
// then use revdial and the public machine can become a client for the
// NATed machine.
//
// Deprecated: this package should not be used and actually can no
// longer be used: half of its code has been deleted as it's no longer
// in use. We kept the half still needed by cmd/coordinator for old
// buildlet clients, but the new buildlet no longer uses this.
// Instead, callers should use the revdial/v2 version that is based on
// a different design without the flow control issues.
package revdial

/*
Protocol:

7-byte frame header:

uint8: frame type
   0 new conn   (server to peer only)
   1 close conn (either way)
   2 write      (either way)
uint32: conn id  (coordinator chooses, no ack from peer)
uint16: length of rest of data (for all frame types)

TODO(bradfitz): health checking PING packet type? since we can't use
TCP keep-alives at this layer. I guess we can just assume our caller
set up TCP keep-alives or similar. But it's actually tedious/hard to
do.

*/

import (
	"bufio"
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"sync"
	"time"
)

// The Dialer can create new connections.
type Dialer struct {
	rw     *bufio.ReadWriter
	closer io.Closer

	mu     sync.Mutex // guards following, and writes to rw
	err    error      // non-nil when closed or peer dies
	closed bool
	conns  map[uint32]*conn
	nextID uint32
	donec  chan struct{}
}

// NewDialer returns the side of the connection which will initiate
// new connections. This will typically be the side which did the
// HTTP Hijack. The io.Closer is what gets closed by the Close
// or by any errors. It will typically be the hijacked Conn.
func NewDialer(rw *bufio.ReadWriter, c io.Closer) *Dialer {
	d := &Dialer{
		rw:     rw,
		closer: c,
		conns:  map[uint32]*conn{},
		nextID: 1, // just for debugging, not seeing zeros
		donec:  make(chan struct{}),
	}
	go func() {
		err := readFrames(rw.Reader, d)
		if err == nil {
			err = errors.New("revdial: Dialer.readFrames terminated with success")
		}
		d.closeWithError(err)
	}()
	return d
}

// Done returns a channel which is closed when d is either closed or closed
// by the peer.
func (d *Dialer) Done() <-chan struct{} { return d.donec }

var errDialerClosed = errors.New("revdial: Dialer closed")

// Close closes the Dialer and all still-open connections from it.
func (d *Dialer) Close() error {
	return d.closeWithError(errDialerClosed)
}

func (d *Dialer) closeWithError(err error) error {
	d.mu.Lock()
	defer d.mu.Unlock()
	if d.closed {
		return nil
	}
	d.closed = true
	d.err = err
	for _, c := range d.conns {
		// TODO(bradfitz): propagate err to peers. For now they'll just fail with
		// EOF, which works but isn't as nice as it could be.
		c.peerClose()
	}
	closeErr := d.closer.Close()
	close(d.donec)

	return closeErr
}

func (d *Dialer) conn(id uint32) (*conn, error) {
	d.mu.Lock()
	defer d.mu.Unlock()
	c, ok := d.conns[id]
	if !ok {
		return nil, fmt.Errorf("revdial.Dialer saw reference to unknown conn %v", id)
	}
	return c, nil
}

var (
	errRole = errors.New("revdial: invalid frame type received for role")
)

func (d *Dialer) onFrame(f frame) error {
	switch f.command {
	case frameNewConn:
		return errRole
	case frameCloseConn:
		c, err := d.conn(f.connID)
		if err != nil {
			// Oh well.
			return nil
		}
		c.peerClose()
		return nil
	case frameWrite:
		c, err := d.conn(f.connID)
		if err != nil {
			// Ignore writes on bogus conn IDs; assume it
			// just recently closed.
			return nil
		}
		if _, err := c.peerWrite(f.payload); err != nil {
			c.mu.Lock()
			closed := c.closed
			c.mu.Unlock()
			if closed {
				// Conn is now closed. Assume error
				// was "io: read/write on closed pipe"
				// and it was just data in-flight
				// while this side closed. So, don't abort
				// the frame-reading loop.
				return nil
			}
			return err
		}
		return nil
	default:
		// Ignore unknown frame types.
	}
	return nil
}

// Dial creates a new connection back to the Listener.
func (d *Dialer) Dial() (net.Conn, error) {
	d.mu.Lock()
	defer d.mu.Unlock()
	if d.closed {
		return nil, errors.New("revdial: Dial on closed client")
	}
	var id uint32
	for {
		id = d.nextID
		d.nextID++ // wrapping is okay; we check for free ones, assuming sparse
		if _, inUse := d.conns[id]; inUse {
			continue
		}
		break
	}
	c := &conn{
		id:        id,
		wmu:       &d.mu,
		w:         d.rw.Writer,
		unregConn: d.unregConn,
	}
	c.cond = sync.NewCond(&c.mu)
	d.conns[id] = c
	err := writeFrame(c, frame{
		command: frameNewConn,
		connID:  id,
	})
	return c, err
}

// c.wmu must be held.
func writeFrame(c *conn, f frame) error {
	if len(f.payload) > 0xffff {
		return errors.New("revdial: frame too long")
	}
	w := c.w
	hdr := [7]byte{
		byte(f.command),
		byte(f.connID >> 24),
		byte(f.connID >> 16),
		byte(f.connID >> 8),
		byte(f.connID),
		byte(len(f.payload) >> 8),
		byte(len(f.payload)),
	}
	if _, err := w.Write(hdr[:]); err != nil {
		return err
	}
	if _, err := w.Write(f.payload); err != nil {
		return err
	}
	return w.Flush()
}

type conn struct {
	id uint32

	wmu       *sync.Mutex // held while writing & calling unreg
	w         *bufio.Writer
	unregConn func(id uint32) // called with wmu held

	mu        sync.Mutex
	cond      *sync.Cond
	buf       []byte // unread data
	eof       bool   // remote side closed
	closed    bool   // our side closed (with Close)
	rdeadline time.Time
	wdeadline time.Time
	rtimer    *time.Timer
	wtimer    *time.Timer
}

func (c *conn) LocalAddr() net.Addr  { return fakeAddr{} }
func (c *conn) RemoteAddr() net.Addr { return fakeAddr{} }

func (c *conn) SetDeadline(t time.Time) error {
	rerr := c.SetReadDeadline(t)
	werr := c.SetWriteDeadline(t)
	if rerr != nil {
		return rerr
	}
	return werr
}

func (c *conn) SetWriteDeadline(t time.Time) error {
	defer c.cond.Signal()
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.closed {
		return errors.New("SetWriteDeadline called on closed connection")
	}
	c.stopWriteTimerLocked()
	c.wdeadline = t
	now := time.Now()
	if t.After(now) {
		c.wtimer = time.AfterFunc(t.Sub(now), c.cond.Broadcast)
	}
	return nil
}

func (c *conn) SetReadDeadline(t time.Time) error {
	defer c.cond.Signal()
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.closed {
		return errors.New("SetReadDeadline called on closed connection")
	}
	c.stopReadTimerLocked()
	c.rdeadline = t
	now := time.Now()
	if t.After(now) {
		c.rtimer = time.AfterFunc(t.Sub(now), c.cond.Broadcast)
	}
	return nil
}

func (c *conn) stopReadTimerLocked() {
	if c.rtimer != nil {
		c.rtimer.Stop()
		c.rtimer = nil
	}
}

func (c *conn) stopWriteTimerLocked() {
	if c.wtimer != nil {
		c.wtimer.Stop()
		c.wtimer = nil
	}
}

func (c *conn) Close() error {
	defer c.cond.Broadcast()
	c.mu.Lock()
	if c.closed {
		c.mu.Unlock()
		return nil
	}
	c.stopReadTimerLocked()
	c.stopWriteTimerLocked()
	c.closed = true
	c.mu.Unlock()

	c.wmu.Lock()
	c.unregConn(c.id)
	defer c.wmu.Unlock()
	return writeFrame(c, frame{
		command: frameCloseConn,
		connID:  c.id,
	})
}

func (d *Dialer) unregConn(id uint32) {
	delete(d.conns, id)
}

func (c *conn) peerWrite(p []byte) (n int, err error) {
	defer c.cond.Signal()
	c.mu.Lock()
	defer c.mu.Unlock()
	// TODO(bradfitz): bound this, like http2's buffer/pipe code
	c.buf = append(c.buf, p...)
	return len(p), nil
}

func (c *conn) peerClose() {
	defer c.cond.Broadcast()
	c.mu.Lock()
	defer c.mu.Unlock()
	c.eof = true
}

var errDeadline net.Error = deadlineError{}

type deadlineError struct{}

func (deadlineError) Error() string   { return "revdial: Read/Write deadline expired" }
func (deadlineError) Temporary() bool { return false }
func (deadlineError) Timeout() bool   { return true }

func (c *conn) Read(p []byte) (n int, err error) {
	defer c.cond.Signal() // for when writers block
	c.mu.Lock()
	defer c.mu.Unlock()
	for {
		n = copy(p, c.buf)
		c.buf = c.buf[:copy(c.buf, c.buf[n:])] // slide down
		if dl := c.rdeadline; !dl.IsZero() {
			if time.Now().After(dl) {
				return n, errDeadline
			}
		}
		if c.closed {
			return n, errors.New("revdial: Read on closed connection")
		}
		if len(c.buf) == 0 && c.eof {
			return n, io.EOF
		}
		if n > 0 || len(p) == 0 {
			return n, nil
		}
		c.cond.Wait()
	}
}

func (c *conn) Write(p []byte) (n int, err error) {
	c.mu.Lock()
	if c.closed {
		c.mu.Unlock()
		return 0, errors.New("revdial: Write on Closed conn")
	}
	dl := c.wdeadline
	if !dl.IsZero() && time.Now().After(dl) {
		c.mu.Unlock()
		// TODO: better write deadline support. do it per chunk, push it down
		// to underlying net.Conn (which involves changing API to let caller
		// supply a net.Conn)
		return 0, errDeadline
	}
	c.mu.Unlock()

	var timeout <-chan time.Time
	if !dl.IsZero() {
		timer := time.NewTimer(time.Until(dl))
		defer timer.Stop()
		timeout = timer.C
	}
	type result struct {
		n   int
		err error
	}
	res := make(chan result, 1)
	go func() {
		const max = 0xffff // max chunk size
		n := 0
		for len(p) > 0 {
			chunk := p
			if len(chunk) > max {
				chunk = chunk[:max]
			}
			c.wmu.Lock()
			err = writeFrame(c, frame{
				command: frameWrite,
				connID:  c.id,
				payload: chunk,
			})
			c.wmu.Unlock()
			if err != nil {
				res <- result{n, err}
				return
			}
			n += len(chunk)
			p = p[len(chunk):]
		}
		res <- result{n: n}
	}()
	select {
	case v := <-res:
		return v.n, v.err
	case <-timeout:
		println("timeout for " + dl.String())
		return 0, errDeadline
	}
}

type frameType uint8

const (
	frameNewConn   frameType = 'N'
	frameCloseConn frameType = 'C'
	frameWrite     frameType = 'W'
)

type frame struct {
	command frameType
	connID  uint32
	payload []byte // not owned
}

func (f frame) String() string {
	p := f.payload
	if len(p) > 64 {
		p = p[:64]
	}
	return fmt.Sprintf("[frame %q conn %v, %q]", f.command, f.connID, p)
}

// onFramer is the interface for something that can get callbacks on
// new frames being received.
type onFramer interface {
	onFrame(f frame) error
}

const debug = false

func readFrames(br *bufio.Reader, of onFramer) error {
	var hdr [7]byte
	var payload bytes.Buffer
	for {
		_, err := io.ReadFull(br, hdr[:])
		if err != nil {
			return err
		}
		f := frame{
			command: frameType(hdr[0]),
			connID:  binary.BigEndian.Uint32(hdr[1:5]),
		}
		paySize := binary.BigEndian.Uint16(hdr[5:7])
		if debug {
			log.Printf("Read frame header: %+v (len %v)", f, paySize)
		}
		payload.Reset()
		if paySize > 0 {
			if _, err := io.CopyN(&payload, br, int64(paySize)); err != nil {
				return err
			}
			if payload.Len() != int(paySize) {
				panic("invariant")
			}
		}
		f.payload = payload.Bytes()
		if debug {
			log.Printf("Read full frame: %+v (len %v)", f, paySize)
		}
		err = of.onFrame(f)
		if debug {
			log.Printf("onFrame = %v", err)
		}
		if err != nil {
			return err
		}
	}
}

type fakeAddr struct{}

func (fakeAddr) Network() string { return "revdial" }
func (fakeAddr) String() string  { return "revdialconn" }
