From 99676ef4bfc1a2538f0b8fd08e06a6489674e1eb Mon Sep 17 00:00:00 2001 From: tigerbot Date: Thu, 30 Mar 2017 13:28:00 -0600 Subject: [PATCH] made it easier to send multiple messages with the same header --- rvpn/client/local_conns.go | 9 ++-- rvpn/genericlistener/listener_generic.go | 34 +++++++------ rvpn/packer/packer.go | 37 +++++++------- rvpn/packer/packer_data.go | 4 -- rvpn/packer/packer_header.go | 61 ++++++++++++++---------- 5 files changed, 75 insertions(+), 70 deletions(-) diff --git a/rvpn/client/local_conns.go b/rvpn/client/local_conns.go index d434449..704a98c 100644 --- a/rvpn/client/local_conns.go +++ b/rvpn/client/local_conns.go @@ -31,7 +31,7 @@ func (l *localConns) Write(p *packer.Packer) error { l.lock.RLock() defer l.lock.RUnlock() - key := fmt.Sprintf("%s:%d", p.Header.Address(), p.Header.Port) + key := fmt.Sprintf("%s:%d", p.Address(), p.Port()) if conn := l.locals[key]; conn != nil { _, err := conn.Write(p.Data.Data()) return err @@ -42,8 +42,8 @@ func (l *localConns) Write(p *packer.Packer) error { } func (l *localConns) startConnection(orig *packer.Packer) { - key := fmt.Sprintf("%s:%d", orig.Header.Address(), orig.Header.Port) - addr := fmt.Sprintf("127.0.0.1:%d", l.services[orig.Header.Service]) + key := fmt.Sprintf("%s:%d", orig.Address(), orig.Port()) + addr := fmt.Sprintf("127.0.0.1:%d", l.services[orig.Service()]) conn, err := net.Dial("tcp", addr) if err != nil { loginfo.Println("failed to open connection to", addr, err) @@ -74,8 +74,7 @@ func (l *localConns) startConnection(orig *packer.Packer) { return } - p := packer.NewPacker() - p.Header = orig.Header + p := packer.NewPacker(&orig.Header) p.Data.AppendBytes(buf[:size]) packed := p.PackV1() l.remote.WriteMessage(websocket.BinaryMessage, packed.Bytes()) diff --git a/rvpn/genericlistener/listener_generic.go b/rvpn/genericlistener/listener_generic.go index 4716a2b..d239951 100644 --- a/rvpn/genericlistener/listener_generic.go +++ b/rvpn/genericlistener/listener_generic.go @@ -292,11 +292,19 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname track := NewTrack(extConn, hostname) serverStatus.ExtConnectionRegister(track) - loginfo.Println("Domain Accepted", hostname, extConn.RemoteAddr().String()) + remoteStr := extConn.RemoteAddr().String() + loginfo.Println("Domain Accepted", hostname, remoteStr) - rAddr, rPort, err := net.SplitHostPort(extConn.RemoteAddr().String()) - if err != nil { - loginfo.Println("unable to decode hostport", extConn.RemoteAddr().String()) + var header *packer.Header + if rAddr, rPort, err := net.SplitHostPort(remoteStr); err != nil { + loginfo.Println("unable to decode hostport", remoteStr, err) + } else if port, err := strconv.Atoi(rPort); err != nil { + loginfo.Printf("unable to parse port string %q: %v\n", rPort, err) + } else if header, err = packer.NewHeader(rAddr, port, service); err != nil { + loginfo.Println("unable to create packer header", err) + } + + if header == nil { return } @@ -309,18 +317,8 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname loginfo.Println("Before Packer", hex.Dump(buffer)) - cnt := len(buffer) - - p := packer.NewPacker() - p.Header.SetAddress(rAddr) - p.Header.Port, err = strconv.Atoi(rPort) - if err != nil { - loginfo.Println("Unable to set Remote port", err) - return - } - - p.Header.Service = service - p.Data.AppendBytes(buffer[0:cnt]) + p := packer.NewPacker(header) + p.Data.AppendBytes(buffer) buf := p.PackV1() //loginfo.Println(hex.Dump(buf.Bytes())) @@ -329,8 +327,8 @@ func handleExternalHTTPRequest(ctx context.Context, extConn *WedgeConn, hostname sendTrack := NewSendTrack(buf.Bytes(), hostname) serverStatus.SendExtRequest(conn, sendTrack) - _, err = extConn.Discard(cnt) - if err != nil { + cnt := len(buffer) + if _, err = extConn.Discard(cnt); err != nil { loginfo.Println("unable to discard", cnt, err) return } diff --git a/rvpn/packer/packer.go b/rvpn/packer/packer.go index 7f4af1b..3948bf2 100644 --- a/rvpn/packer/packer.go +++ b/rvpn/packer/packer.go @@ -16,16 +16,19 @@ const ( //Packer -- contains both header and data type Packer struct { - Header *packerHeader - Data *packerData + Header + Data packerData } -//NewPacker -- Structre -func NewPacker() (p *Packer) { - p = new(Packer) - p.Header = newPackerHeader() - p.Data = newPackerData() - return +// NewPacker creates a new Packer struct using the information from the provided header as +// its own header. (Because the header is stored directly and not as a pointer/reference +// it should be safe to override items like the service without affecting the template header.) +func NewPacker(header *Header) *Packer { + p := new(Packer) + if header != nil { + p.Header = *header + } + return p } func splitHeader(header []byte, names []string) (map[string]string, error) { @@ -48,7 +51,7 @@ func ReadMessage(b []byte) (*Packer, error) { // Detect protocol in use if b[0] == packerV1 { // Separate the header and body using the header length in the second byte. - p := NewPacker() + p := NewPacker(nil) header := b[2 : b[1]+2] data := b[b[1]+2:] @@ -69,8 +72,8 @@ func ReadMessage(b []byte) (*Packer, error) { p.Header.address = net.ParseIP(parts["address"]) if p.Header.address == nil { return nil, fmt.Errorf("Invalid network address %q", parts["address"]) - } else if p.Header.Family() == FamilyIPv4 && p.Header.address.To4() == nil { - return nil, fmt.Errorf("Address %q is not in address family %s", parts["address"], p.Header.FamilyText()) + } else if p.Header.family == FamilyIPv4 && p.Header.address.To4() == nil { + return nil, fmt.Errorf("Address %q is not in address family %s", parts["address"], p.Header.Family()) } //handle port @@ -79,7 +82,7 @@ func ReadMessage(b []byte) (*Packer, error) { } else if port <= 0 || port > 65535 { return nil, fmt.Errorf("Port %d out of range", port) } else { - p.Header.Port = port + p.Header.port = port } //handle data length @@ -90,7 +93,7 @@ func ReadMessage(b []byte) (*Packer, error) { } //handle Service - p.Header.Service = parts["service"] + p.Header.service = parts["service"] //handle payload p.Data.AppendBytes(data) @@ -103,11 +106,11 @@ func ReadMessage(b []byte) (*Packer, error) { //PackV1 -- Outputs version 1 of packer func (p *Packer) PackV1() bytes.Buffer { header := strings.Join([]string{ - p.Header.FamilyText(), - p.Header.AddressString(), - strconv.Itoa(p.Header.Port), + p.Header.Family(), + p.Header.Address(), + strconv.Itoa(p.Header.Port()), strconv.Itoa(p.Data.DataLen()), - p.Header.Service, + p.Header.Service(), }, ",") var buf bytes.Buffer diff --git a/rvpn/packer/packer_data.go b/rvpn/packer/packer_data.go index 08775ad..3dfbadc 100644 --- a/rvpn/packer/packer_data.go +++ b/rvpn/packer/packer_data.go @@ -9,10 +9,6 @@ type packerData struct { buffer bytes.Buffer } -func newPackerData() *packerData { - return new(packerData) -} - func (p *packerData) AppendString(dataString string) (int, error) { return p.buffer.WriteString(dataString) } diff --git a/rvpn/packer/packer_header.go b/rvpn/packer/packer_header.go index be7cbb2..668cec4 100644 --- a/rvpn/packer/packer_header.go +++ b/rvpn/packer/packer_header.go @@ -7,12 +7,15 @@ import ( type addressFamily int -// packerHeader structure to hold our header information. -type packerHeader struct { +// The Header struct holds most of the information contained in the header for packets +// between the client and the server (the length of the data is not included here). It +// is used to uniquely identify remote connections on the servers end and to communicate +// which service the remote client is trying to connect to. +type Header struct { family addressFamily address net.IP - Port int - Service string + port int + service string } //Family -- ENUM for Address Family @@ -26,16 +29,19 @@ var addressFamilyText = [...]string{ "IPv6", } -func newPackerHeader() (p *packerHeader) { - p = new(packerHeader) - p.SetAddress("127.0.0.1") - p.Port = 65535 - p.Service = "na" - return +// NewHeader create a new Header object. +func NewHeader(address string, port int, service string) (*Header, error) { + h := new(Header) + if err := h.setAddress(address); err != nil { + return nil, err + } + h.port = port + h.service = service + return h, nil } -//SetAddress -- Set Address. which sets address family automatically -func (p *packerHeader) SetAddress(addr string) { +// setAddress parses the provided address string and automatically sets the IP family. +func (p *Header) setAddress(addr string) error { p.address = net.ParseIP(addr) if p.address.To4() != nil { @@ -43,30 +49,33 @@ func (p *packerHeader) SetAddress(addr string) { } else if p.address.To16() != nil { p.family = FamilyIPv6 } else { - panic(fmt.Sprintf("setAddress does not support %q", addr)) + return fmt.Errorf("invalid IP address %q", addr) } + return nil } -func (p *packerHeader) AddressBytes() []byte { - if ip4 := p.address.To4(); ip4 != nil { - p.address = ip4 - } - - return []byte(p.address) +// Family returns the string corresponding to the address's IP family. +func (p *Header) Family() string { + return addressFamilyText[p.family] } -func (p *packerHeader) AddressString() string { +// Address returns the string form of the header's remote address. +func (p *Header) Address() string { return p.address.String() } -func (p *packerHeader) Address() net.IP { - return p.address +// Port returns the connected port of the remote connection. +func (p *Header) Port() int { + return p.port } -func (p *packerHeader) Family() addressFamily { - return p.family +// SetService overrides the header's original service. This is primarily useful +// for sending 'error' and 'end' messages. +func (p *Header) SetService(service string) { + p.service = service } -func (p *packerHeader) FamilyText() string { - return addressFamilyText[p.family] +// Service returns the service stored in the header. +func (p *Header) Service() string { + return p.service }