forked from hswaw/hscloud
59 lines
1.8 KiB
Go
59 lines
1.8 KiB
Go
package ident
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
// Request is an ident protocol request, as seen by the client or server.
|
|
type Request struct {
|
|
// ClientPort is the port number on the client side of the indent protocol,
|
|
// ie. the port local to the ident client.
|
|
ClientPort uint16
|
|
// ServerPort is the port number on the server side of the ident protocol,
|
|
// ie. the port local to the ident server.
|
|
ServerPort uint16
|
|
|
|
// ClientAddress is the address of the ident protocol client. This is set
|
|
// by the ident Server before invoking handlers, and is ignored by the
|
|
// ident protocol Client.
|
|
// In handlers this can be used to ensure that responses are only returned
|
|
// to clients who are running on the remote side of the connection that
|
|
// they are querying about.
|
|
ClientAddress net.Addr
|
|
}
|
|
|
|
// encode encodes ths Request as per RFC1413, including the terminating \r\n.
|
|
func (r *Request) encode() []byte {
|
|
return []byte(fmt.Sprintf("%d,%d\r\n", r.ServerPort, r.ClientPort))
|
|
}
|
|
|
|
var (
|
|
// reRequest matches request from RFC1413, but allows extra whitespace
|
|
// between significant tokens.
|
|
reRequest = regexp.MustCompile(`^\s*(\d{1,5})\s*,\s*(\d{1,5})\s*$`)
|
|
)
|
|
|
|
// decodeRequest parses the given bytes as an ident request. The data must be
|
|
// stripped of the trailing \r\n.
|
|
func decodeRequest(data []byte) (*Request, error) {
|
|
match := reRequest.FindStringSubmatch(string(data))
|
|
if match == nil {
|
|
return nil, fmt.Errorf("unparseable request")
|
|
}
|
|
serverPort, err := strconv.ParseUint(match[1], 10, 16)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid server port: %w", err)
|
|
}
|
|
clientPort, err := strconv.ParseUint(match[2], 10, 16)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid client port: %w", err)
|
|
}
|
|
return &Request{
|
|
ClientPort: uint16(clientPort),
|
|
ServerPort: uint16(serverPort),
|
|
}, nil
|
|
}
|