Beispiel #1
0
func fwdRequest(conn net.Conn) {
	l.Log("Request: ", connStr(conn))
	hcon := httpheadreader.NewHTTPHeadReader(conn)

	l.Log("Request: host:", hcon.Host())

	if hcon.Host() == *externAddr || hcon.Host() == "www."+*externAddr {
		conn.Write([]byte(defaultMsg))
		conn.Close()
		return
	}

	// if host is '.m.'+*externAddr then fwd it to a redis server
	// or something.

	p, ok := router.GetProxy(hcon.Host())
	if !ok {
		l.Log("Request: coundn't find proxy for", hcon.Host())
		conn.Write([]byte(fmt.Sprintf("Couldn't fine proxy for <%s>", hcon.Host())))
		conn.Close()
		return
	}

	proto.SendConnRequest(p.Admin)
	p.Proxy.Forward(hcon)
}
Beispiel #2
0
// https://groups.google.com/d/topic/golang-nuts/e8sUeulwD3c/discussion
func isAlive(c net.Conn) (ret bool) {
	ret = false

	defer func() {
		if r := recover(); r != nil {
			l.Log("isAlive: Recovering from f", r)
			ret = false
		}
	}()

	one := make([]byte, 10)
	c.SetReadDeadline(time.Now().Add(10 * time.Second))
	n, err := c.Read(one)
	// l.Log("isAlive: read %v - %v", len(one), string(one))
	if err == io.EOF {
		l.Log("isAlive: %s detected closed LAN connection", c)
		c.Close()
		c = nil
		return
	}
	if n == 0 {
		l.Log("isAlive: read 0 bytes. Probably client out of reach")
		return
	}

	c.SetReadDeadline(time.Time{})
	ret = true
	return
}
func (p *ProxyClient) accept() {
	for {
		backconn, err := p.listenServer.Accept()
		l.Log("New connection from backend ")
		if err != nil {
			l.Log("some problem %v", err)
		}

		p.conn <- backconn
	}
}
func (c *HTTPHeadReader) regexpHost() string {
	// TODO: make this generic
	reg, err := regexp.Compile(`(\w*\.localtunnel\.net)`)
	if err != nil {
		l.Log("H: couldn't find host")
		return ""
	}

	if reg.Match(c.buf[0:]) {
		l.Log("H: found host: ", reg.FindString(string(c.buf[0:])))
		return reg.FindString(string(c.buf[0:]))
	}
	return ""
}
Beispiel #5
0
// given a connection, figures out the subdomain and gives respective
// proxy.
func (r *TCPRouter) GetProxy(host string) (*Proxy, bool) {
	id, ok := IdForHost(host)
	if !ok {
		l.Log("Router: Couldn't find the subdomain for the request", host)
		return nil, false
	}

	l.Log("Router: for id: ", id, r.String())
	if proxy, ok := r.proxies[id]; ok {
		l.Log("Router: found proxy")
		return proxy, true
	}
	return nil, false
}
func (c *HTTPHeadReader) parseHeaders() (err error) {
	var buf [http.DefaultMaxHeaderBytes]byte

	n, err := c.conn.Read(buf[0:])
	if err != nil {
		l.Log("H: error while reading", err)
		return err
	}
	l.Log("H: bytes", n)
	c.buf = make([]byte, n)
	copy(c.buf, buf[0:n])

	c.req, err = http.ReadRequest(bufio.NewReader(bytes.NewReader(c.buf[0:n])))
	if err != nil {
		l.Log("H: error while parsing header")
		return err
	}
	return nil
}
Beispiel #7
0
func setupClient(eaddr, port string, adminc net.Conn) {
	id := proto.ReceiveSubRequest(adminc)

	l.Log("Client: asked for ", connStr(adminc), id)

	proxy := router.Register(adminc, id)

	requestURL, backendURL := proxy.FrontHost(eaddr, port), proxy.BackendHost(eaddr)
	l.Log("Client: --- sending %v %v", requestURL, backendURL)

	proto.SendProxyInfo(adminc, requestURL, backendURL)

	for {
		time.Sleep(2 * time.Second)
		if !isAlive(adminc) {
			router.Deregister(proxy)
			break
		}
	}
	l.Log("Client: closing backend connection")
}
func (c *HTTPHeadReader) Read(b []byte) (int, error) {
	// read from internal buffer
	if c.err != nil {
		return 0, c.err
	}
	if len(c.buf) != 0 {
		n := copy(b, c.buf)
		c.buf = c.buf[n:]
		l.Log("copied: %d - remaining %d ", n, len(c.buf))
		return n, nil
	}
	return c.conn.Read(b)
}
Beispiel #9
0
func SetupClient(port, remote, subdomain string, servInfo chan string) bool {
	localServer := net.JoinHostPort("127.0.0.1", port)

	// if !ensureServer(localServer) {
	// 	return false
	// }

	req, quit, conn := make(chan bool), make(chan bool), make(chan string)

	// fmt.Printf("Setting Gotunnel server %s with local server on %s\n\n", remote, port)

	go setupCommandChannel(remote, subdomain, req, quit, conn, servInfo)

	remoteProxy := <-conn

	// l.Log("remote proxy: %v", remoteProxy)

	for {
		select {
		case <-req:
			// fmt.Printf("New link b/w %s and %s\n", remoteProxy, localServer)
			rp, err := net.Dial("tcp", remoteProxy)
			if err != nil {
				l.Log("Coundn't connect to remote clientproxy", err)
				return false
			}
			lp, err := net.Dial("tcp", localServer)
			if err != nil {
				l.Log("Couldn't connect to localserver", err)
				return false
			}

			go rwtunnel.NewRWTunnel(rp, lp)
		case <-quit:
			return true
		}
	}
	return true
}
Beispiel #10
0
func setupHeartbeat(c net.Conn) {

	for {
		time.Sleep(1 * time.Second)
		c.SetWriteDeadline(time.Now().Add(3 * time.Second))

		_, err := c.Write([]byte("ping"))
		if err != nil {
			l.Log("Couldn't connect to server. Check your network connection, and run client again.")
			os.Exit(1)
		}
	}
}
func (c *HTTPHeadReader) Host() string {
	if c.req != nil {
		return c.req.Host
	}

	err := c.parseHeaders()
	if err != nil {
		l.Log("H: error", err)
		return c.regexpHost()
	}

	return c.req.Host
}
Beispiel #12
0
func (r *TCPRouter) Register(ac net.Conn, suggestedId string) (proxy *Proxy) {
	// check if its suggestedId is already registered.
	proxyClient := r.setupClientCommChan(suggestedId)

	id := suggestedId
	for _, ok := r.proxies[id]; ok || id == ""; _, ok = r.proxies[id] {
		id = newRandString()
	}

	l.Log("Router: registering with (%s)", id)
	r.proxies[id] = &Proxy{Proxy: proxyClient, Admin: ac, id: id}

	return r.proxies[id]
}
Beispiel #13
0
// https://groups.google.com/d/topic/golang-nuts/e8sUeulwD3c/discussion
func isAlive(c net.Conn) bool {
	one := []byte{0}
	c.SetReadDeadline(time.Now())
	_, err := c.Read(one)
	if err == io.EOF {
		l.Log("%s detected closed LAN connection", c)
		c.Close()
		c = nil
		return false
	}

	c.SetReadDeadline(time.Time{})
	return true
}
Beispiel #14
0
func IdForHost(host string) (string, bool) {
	h, _, err := net.SplitHostPort(host)
	if h == "" { // assumes host:port or host as parameter
		h = host
	}

	reg, err := regexp.Compile(`^([A-Za-z]*)`)
	if err != nil {
		return "", false
	}

	if reg.Match([]byte(host)) {
		l.Log("Router: id for host", reg.FindString(h), host)
		return reg.FindString(host), true
	}
	return "", false
}
Beispiel #15
0
func copypaste(in, out io.ReadWriteCloser, close_in bool, msg string) {
	var buf [512]byte

	defer func() {
		if close_in {
			l.Log("eof closing connection")
			in.Close()
			out.Close()
		}
	}()

	for {
		n, err := in.Read(buf[0:])
		// on readerror, only bail if no other choice.
		if err == io.EOF {
			l.Log("msg: ", msg)
			// fmt.Print(msg)
			// time.Sleep(1e9)
			l.Log("eof", msg)
			return
		}
		l.Log("-- read ", n)
		if err != nil {
			l.Log("something wrong while copying in ot out ", msg)
			l.Log("error: ", err)
			return
		}
		// if n < 1 {
		// 	fmt.Println("nothign to read")
		// 	return
		// }

		l.Log("-- wrote msg bytes", n)

		_, err = out.Write(buf[0:n])
		if err != nil {
			l.Log("something wrong while copying out to in ")
			// l.Fatal("something wrong while copying out to in", err)
			return
		}
	}
}
Beispiel #16
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	if *port == "" || *backproxyAdd == "" || *externAddr == "" {
		flag.Usage()
		os.Exit(1)
	}

	// new clients
	go func() {
		backproxy, err := net.Listen("tcp", *backproxyAdd)
		if err != nil {
			l.Fatal("Client: Coundn't start server to connect clients", err)
		}

		for {
			adminc, err := backproxy.Accept()
			if err != nil {
				l.Fatal("Client: Problem accepting new client", err)
			}
			go setupClient(*externAddr, *port, adminc)
		}

	}()

	// new request
	server, err := net.Listen("tcp", net.JoinHostPort("0.0.0.0", *port))
	if server == nil {
		l.Fatal("Request: cannot listen: %v", err)
	}
	l.Log("Listening at: %s", *port)

	for {
		conn, err := server.Accept()
		if err != nil {
			l.Fatal("Request: failed to accept new request: ", err)
		}
		go fwdRequest(conn)
	}
}
Beispiel #17
0
// connect to server:
// - send the requested subdomain to server.
// - server replies back with a port to setup command channel on.
// - it also replies with the server address that users can access the site on.
func setupCommandChannel(addr, sub string, req, quit chan bool, conn, servInfo chan string) {
	backproxy, err := net.Dial("tcp", addr)
	if err != nil {
		l.Log("CMD: Couldn't connect to ", addr, "err: ", err)
		quit <- true
		return
	}
	defer backproxy.Close()

	proto.SendSubRequest(backproxy, sub)

	// the port to connect on
	serverat, conn_to, _ := proto.ReceiveProxyInfo(backproxy)
	conn <- conn_to
	servInfo <- serverat

	go setupHeartbeat(backproxy)

	for {
		req <- proto.ReceiveConnRequest(backproxy)
	}
}
Beispiel #18
0
func (p *ProxyClient) Forward(c io.ReadWriteCloser) error {
	bc := <-p.conn
	l.Log("Received new connection. Fowarding.. ")
	rwtunnel.NewRWTunnel(c, bc)
	return nil
}