code: func ReadProxyLine(reader *bufio.Reader) (*ProxyLine, error) {
  	line, err := reader.ReadString('\n')
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  	if !strings.HasSuffix(line, proxyCRLF) {
  		return nil, trace.BadParameter("expected CRLF in proxy protocol, got something else")
  	}
  	tokens := strings.Split(line[:len(line)-2], proxySep)
  	ret := ProxyLine{}
  	if len(tokens) < 6 {
  		return nil, trace.BadParameter("malformed PROXY line protocol string")
  	}
  	switch tokens[1] {
  	case TCP4:
  		ret.Protocol = TCP4
  	case TCP6:
  		ret.Protocol = TCP6
  	default:
  		ret.Protocol = UNKNOWN
  	}
  	sourceIP, err := parseIP(ret.Protocol, tokens[2])
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  	destIP, err := parseIP(ret.Protocol, tokens[3])
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  	sourcePort, err := parsePortNumber(tokens[4])
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  	destPort, err := parsePortNumber(tokens[5])
  	if err != nil {
  		return nil, err
  	}
  	ret.Source = net.TCPAddr{IP: sourceIP, Port: sourcePort}
  	ret.Destination = net.TCPAddr{IP: destIP, Port: destPort}
  	return &ret, nil
  }
docs: // ReadProxyLine reads proxy line protocol from the reader