greet

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 10 Imported by: 0

README

Greet is a lightweight Go library to test greet / ping / handshake process in TCP, UDP and other popular protocols based on them.

Goals

  • Fast: The library only performs handshake without entering full session
  • Secure: The process ends before authentication / authorization step
  • Lightweight: The library constructs raw command from scratch and does not depend on third-party service clients
  • Tracing: The library outputs helpful errors from connection init to handshake

Use case

  • Greet is good enough to test connectivity, service name and service version.

Installation

Library

go get github.com/crystade/greet@latest

Then import and use in your Go code:

import "github.com/crystade/greet"

func main() {
    ctx := context.Background()
    result, err := greet.Greet(ctx, "ssh", "github.com:22")
    // ...
}

CLI

go install github.com/crystade/greet/cmd/greet@latest

Or build from source:

go build -o greet ./cmd/greet/

Library Usage

The greet.Greet() function is the primary entry point:

result, err := greet.Greet(ctx, "ssh", "github.com:22")
if err != nil {
    // handle *greet.GreetError
}
fmt.Println(result.Success, result.Latency, result.Data)

Customize behavior with functional options:

result, err := greet.Greet(ctx, "minecraft", "hypixel.net:25565",
    greet.WithTimeout(10*time.Second),
    greet.WithProtocolConfig(&minecraft.Config{ProtocolVersion: 775}),
)

For pre-resolved protocols, use greet.GreetWith():

p, _ := greet.Get("ssh")
result, err := greet.GreetWith(ctx, p, "github.com", 22)

See greet.go and options.go for the complete API.

CLI Usage

greet <protocol> <host>[:<port>] [flags]

Commands

Command Description
greet list List all registered protocols
greet --help Show help

Examples

# Generic TCP — test connectivity to a port
greet tcp example.com:80

# SSH — read server version banner
greet ssh github.com:22

# PostgreSQL — probe SSL support
greet postgresql localhost:5432

# PostgreSQL — skip SSL probe
greet postgresql localhost:5432 --sslmode=disable

# Minecraft Java — query server status
greet minecraft hypixel.net:25565

# Minecraft — specify protocol version (default: 775)
greet minecraft localhost:25565 --protocol-version=775

# Use default port (from protocol's well-known port)
greet ssh github.com        # equivalent to github.com:22

Output

All commands output structured JSON to stdout:

{
  "protocol": "ssh",
  "transport": "tcp",
  "latency": "45.123ms",
  "latency_ms": 45.123,
  "success": true,
  "data": {
    "version_string": "SSH-2.0-OpenSSH_8.9"
  }
}

Errors are output as JSON to stderr:

{
  "success": false,
  "error": "[ssh] connection_refused: connection to localhost:22 refused",
  "code": "connection_refused",
  "protocol": "ssh"
}

Protocol-Specific Flags

Protocol Flag Default Description
postgresql --sslmode prefer SSL mode: prefer (try SSL) or disable (skip SSL)
minecraft --protocol-version 775 Minecraft protocol version (e.g. 775 for 26.1)

Protocols

Error Code Reuse Hierarchy

Protocols inherit error codes from their transport layer:

graph TD
    COMMON[Common Errors]
    TCP[Generic TCP Errors]
    UDP[Generic UDP Errors]
    SSH[SSH Errors]
    PG[PostgreSQL Errors]
    MC[Minecraft Errors]

    COMMON --> TCP
    COMMON --> UDP
    TCP --> SSH
    TCP --> PG
    TCP --> MC
Common Errors
Error Code Description
resolve_host_failed Failed to resolve hostname to IP address
invalid_address Invalid host or port format
unknown_protocol Requested protocol name is not registered
invalid_config Protocol-specific configuration is malformed or of the wrong type
Generic TCP Errors
Error Code Description
connection_refused Server actively refused the connection
connection_timeout TCP connection attempt timed out
connection_reset Connection reset by remote peer
network_unreachable Target network is unreachable
connection_failed Generic connection failure (unknown OS error)
Generic UDP Errors
Error Code Description
send_failed Failed to send UDP datagram
receive_timeout Timed out waiting for UDP response
port_unreachable Received ICMP port unreachable

Generic TCP

  • Input: Host, Port
  • Output: Success with latency, or an error code from Common + Generic TCP errors

Generic UDP

  • Input: Host, Port
  • Output: Success with latency, or an error code from Common + Generic UDP errors

SSH (TCP)

  • Input: Host, Port (default 22)
  • Output: Success with server version string (e.g. SSH-2.0-OpenSSH_8.9) and latency, or an error code

Inherits: Common + Generic TCP errors

Error Code Description
banner_timeout Timed out waiting for SSH version banner
invalid_banner Received malformed SSH version string

PostgreSQL (TCP)

  • Input: Host, Port (default 5432), SSL Mode (default prefer)
  • Output: Success with server version, auth type, and latency, or an error code

Inherits: Common + Generic TCP errors

Error Code Description
startup_timeout Timed out waiting for server response
send_failed Failed to send packet to the server
malformed_response Received malformed PostgreSQL message
ssl_rejected Server does not support requested SSL mode

Minecraft Java (TCP)

  • Input: Host, Port (default 25565), Protocol Version (required, VarInt — e.g. 775 for Minecraft 26.1). Intent is automatically set to Status (1) by the library.
  • Output: Success with server status JSON (MOTD, players, version) and latency, or an error code

Inherits: Common + Generic TCP errors

Error Code Description
handshake_timeout Timed out waiting for status response
handshake_failed Failed to send handshake or status request
malformed_response Received malformed status response

Contribution

Due to overhead of maintenance, we only accept popular protocols for now.

Postpone:

  • DNS: having the most RFCs and Drafts attached to it of all protocols, we are looking to provide support to a subset of popular DNS protocols only

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

View Source
const DefaultTimeout = 5 * time.Second

DefaultTimeout is the deadline for the entire handshake operation.

Variables

This section is empty.

Functions

func ListProtocols

func ListProtocols() []string

ListProtocols returns all registered protocol names, sorted.

func ParseTarget

func ParseTarget(target string, defaultPort int) (string, int, error)

ParseTarget splits a target string into host and port. Accepted formats: "host", "host:port", "[::1]:port". If no port is specified, defaultPort is used. Port is validated to be in the range 1–65535.

func Register

func Register(p Protocol)

Register adds a protocol implementation to the global registry. Call this from init() in each protocol package.

Types

type ErrorCode

type ErrorCode string

ErrorCode is a human-readable error category string. Code always compares against named constants; the string value is immediately readable in logs and debug prints.

const (
	ErrResolveHostFailed ErrorCode = "resolve_host_failed"
	ErrInvalidAddress    ErrorCode = "invalid_address"
	ErrUnknownProtocol   ErrorCode = "unknown_protocol"
	ErrInvalidConfig     ErrorCode = "invalid_config"
)

Common error codes shared by every protocol.

const (
	ErrConnectionRefused  ErrorCode = "connection_refused"
	ErrConnectionTimeout  ErrorCode = "connection_timeout"
	ErrConnectionReset    ErrorCode = "connection_reset"
	ErrNetworkUnreachable ErrorCode = "network_unreachable"
	ErrConnectionFailed   ErrorCode = "connection_failed"
)

Generic TCP error codes shared by all TCP-based protocols.

const (
	ErrSendFailed      ErrorCode = "send_failed"
	ErrReceiveTimeout  ErrorCode = "receive_timeout"
	ErrPortUnreachable ErrorCode = "port_unreachable"
)

func (ErrorCode) String

func (c ErrorCode) String() string

String returns the human-readable error code.

type FlaggedProtocol

type FlaggedProtocol interface {
	Protocol

	// RegisterFlags adds protocol-specific flags to a flag.FlagSet.
	RegisterFlags(fs *flag.FlagSet)

	// ParseFlags returns protocol-specific options from parsed flags.
	ParseFlags(fs *flag.FlagSet) ([]GreetOption, error)
}

FlaggedProtocol is an optional interface for protocols that need CLI-specific flags. The CLI auto-discovers this via type assertion.

type GreetConfig

type GreetConfig struct {
	Timeout        time.Duration
	ProtocolConfig any // protocol-specific config set via WithProtocolConfig
}

GreetConfig holds resolved options for a Greet call.

func ResolveOptions

func ResolveOptions(opts ...GreetOption) GreetConfig

ResolveOptions applies functional options and fills defaults.

type GreetError

type GreetError struct {
	Code     ErrorCode
	Message  string
	Protocol string // protocol name; empty for common errors
	Cause    error  // underlying OS or network error
}

GreetError is the structured error type returned by all protocol implementations. It carries a machine-readable code, a human message, the originating protocol name, and the underlying OS / network error.

func (*GreetError) Error

func (e *GreetError) Error() string

Error implements the error interface.

func (*GreetError) Unwrap

func (e *GreetError) Unwrap() error

Unwrap returns the underlying cause, enabling errors.Is / errors.As chains.

type GreetOption

type GreetOption func(*GreetConfig)

GreetOption is a functional option for configuring a Greet call.

func WithProtocolConfig

func WithProtocolConfig(cfg any) GreetOption

WithProtocolConfig carries protocol-specific configuration from FlaggedProtocol.ParseFlags into the Greet call.

func WithTimeout

func WithTimeout(d time.Duration) GreetOption

WithTimeout overrides the default handshake timeout.

type GreetResult

type GreetResult struct {
	Protocol  string
	Transport Transport
	Latency   time.Duration
	Success   bool

	// Data holds protocol-specific payload. Nil for generic TCP/UDP.
	// Cast to the protocol's result type for typed access, e.g.:
	//   mc, ok := result.Data.(*minecraft.MinecraftResult)
	Data any
}

GreetResult holds the outcome of a protocol handshake. Protocols populate Data with a typed result struct (e.g. *MinecraftResult); generic TCP/UDP set Data to nil.

func Greet

func Greet(ctx context.Context, protocol, target string, opts ...GreetOption) (*GreetResult, error)

Greet is the one-stop entry point. It looks up the protocol by name, resolves the target (host or host:port), and performs the handshake.

func GreetWith

func GreetWith(ctx context.Context, p Protocol, host string, port int, opts ...GreetOption) (*GreetResult, error)

GreetWith is like Greet but accepts a pre-resolved Protocol instance.

func NewResult

func NewResult(protocol string, transport Transport, latency time.Duration, success bool, data any) *GreetResult

NewResult creates a GreetResult with the given fields.

type Protocol

type Protocol interface {
	// Name returns the protocol slug used by the CLI and registry (e.g. "minecraft").
	Name() string

	// Description is a one-line human-readable summary.
	Description() string

	// DefaultPort is the well-known port (e.g. 25565 for Minecraft).
	DefaultPort() int

	// Transport returns TransportTCP or TransportUDP.
	Transport() Transport

	// Greet performs the handshake and returns a result or error.
	Greet(ctx context.Context, host string, port int, opts ...GreetOption) (*GreetResult, error)
}

Protocol is the interface every greeter implementation must satisfy. Implementations register themselves via greet.Register() in init().

func Get

func Get(name string) (Protocol, error)

Get looks up a protocol by name (case-insensitive).

func List

func List() []Protocol

List returns every registered protocol, sorted by name.

type Transport

type Transport string

Transport is the network transport layer a protocol operates over.

const (
	TransportTCP Transport = "tcp"
	TransportUDP Transport = "udp"
)

func (Transport) String

func (t Transport) String() string

String returns the human-readable transport name.

Directories

Path Synopsis
cmd
greet command
protocols
all
Package all blank-imports every protocol to trigger their init() registration.
Package all blank-imports every protocol to trigger their init() registration.
ssh
tcp
udp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL